// Final project for CSII of S'98
// Patho_Image.java - Image Description

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.*;
import java.awt.*;

public class Patho_Image extends Applet implements ItemListener {
   private ScrollPane Scroller;
   private SelfContainedCanvas drawCanvas, dc1, dc2;
   private Image tissue[], star;
   private List images;
   private Label l;

   public void init()
   {
      l = new Label("Choose an image: ");
      l.setFont( new Font( "Serif", Font.BOLD, 12) );

      star = getImage (getDocumentBase(), "star.gif" );
      tissue = new Image[2];
      tissue[0] = getImage (getDocumentBase(), "Brain_tumor.jpg" );
      tissue[1] = getImage (getDocumentBase(), "Brain_tumor_closeup.jpg" );

      images = new List(2,false);
      images.add( "Brain Tumor" );
      images.add( "BT-CloseUp" );
      images.addItemListener( this );

      add( l );
      add( images );
    
      drawCanvas = new SelfContainedCanvas(tissue[0], star, 0);
      drawCanvas.setBackground( Color.lightGray );
      drawCanvas.setSize( 800, 600 );
      Scroller = new ScrollPane();
      Scroller.add( drawCanvas );
      Scroller.setSize( 580, 330 );
      add( Scroller );

      Adjustable horizontal = Scroller.getHAdjustable();
      horizontal.setUnitIncrement( 4 );
      Adjustable vertical = Scroller.getVAdjustable();
      vertical.setUnitIncrement( 4 );
   }

   public void itemStateChanged( ItemEvent e )
   {
     drawCanvas.setValues( tissue[images.getSelectedIndex()], star,
                           images.getSelectedIndex() );
     drawCanvas.reSetArrow( -10, 0 );
   }
}

class SelfContainedCanvas extends Canvas
         implements ActionListener, MouseListener {

   private int aa, bb = -10;
   private int xPos, yPos = -10;
   private Polygon p0[], p1[];
   private String info0[], info1[];;
   private Label Show;
   private Label Show0;
   private Label Show1;
   private Label Show2;
   private Label Show3;
   private Label Show4;
   private Font font1, font2;
   private boolean Flags = false;
   private Image T, tar;
   private int ImageNo;
   private ColorFrame showFrame0, showFrame1;
   private String s[];
  
   private int xValues0[][] = {
{235,226,228,236,251,261,267,266,261,252}, 
{382,399,411,407,396,378,368,371,377},
{202,214,221,222,218,205,191,188,191},
{415,403,400,405,418,428,437,436,427,419},
{343,353,363,372,366,358,348,342,336},
{287,278,283,307,314,313,300},
{303,299,291,289,288,292,304,310,315,321,322,326,318,311},
{224,238,244,243,231,222,221},
{224,230,232,228,218},
{246,243,234,224,204,195,181,191,202,219,234},
{232,240,248,243,231,226},
{207,243,270,290,308,319,327,323,313,295,276,252,233,212,188,179,170,170,176,189},
{313,347,355,361,364,375,372,390,397,390,368,351,335},
{275,267,267,279,291,304,307,319,331,340,355,360,357,356,337,312,298,289},
{326,320,306,284,236,197,171,155,134,127,135,159,176,192,208,226,254,276,276,265,276,325,337},
{332,336,352,398,415,445,463,486,495,505,512,516,509,486,459,424,391,349,345,350,362,359,356}  };

  private int yValues0[][] = {
{362,371,383,390,393,382,374,365,358,354},
{362,362,374,390,397,395,384,374,365},
{232,233,244,256,264,269,260,247,237},
{225,231,244,253,259,255,244,235,228,226},
{64,63,65,77,88,94,91,83,75},
{66,77,83,92,83,73,65},
{150,180,192,200,213,219,217,210,201,185,175,162,150,147},
{169,169,175,187,188,184,176},
{204,204,211,217,212},
{125,139,143,140,146,155,155,136,131,128,125},
{149,147,156,166,169,162},
{112,100,99,103,118,142,163,188,214,238,252,261,267,262,244,225,202,178,152,
  131},
{110,164,190,191,203,195,175,155,135,122,133,141,132},
{319,352,396,417,436,427,415,419,434,438,404,377,347,325,332,334,316,314},
{72,33,20,20,42,76,117,173,233,274,334,384,420,430,424,456,453,447,411,366,318,268,191},
{67,33,24,34,49,70,97,138,163,206,249,294,324,360,407,448,462,457,423,406,377 ,353,327} }; 

   private int xValues1[][] = { 
{155,174,191,222,239,240,221,207,187,168,149,139,139,139,147},
{239,276,295,301,295,289,274,255,233,232},
{485,466,465,439,432,446,481,514,533,544,547,554,535,517,503,492},
{169,120,111,123,128,152,170,192,199,195},
{290,299,303,299},
{54,61,66,63},
{107,110,116},
{264,268,275,275,271},
{257,267,257,249,248},
{119,113,99,105,115},
{267,250,250,269,286,292,310,314,298},
{27,85,123,238,341,431,497,533,580,563,488,145},
{99,62,50,41,3,3,598,619,615,635,635,600,548,505},
{635,614,614,602,614,630,629,637},
{632,634,514,580} };

   private int yValues1[][] = { 
{380,375,373,387,415,446,464,473,475,472,457,436,419,401,386 }, 
{188,196,194,200,230,240,242,240,233,209},
{36,192,240,277,321,341,345,309,258,217,180,158,142,124,118,127},
{263,293,306,328,339,320,301,290,275,262},
{82,88,81,76},
{272,282,261,255},
{344,349,345},
{387,394,394,386,382},
{293,321,322,310,299},
{233,254,249,235,229},
{141,161,177,190,187,166,157,151,146},
{260,386,474,472,476,434,373,308,200,99,3,4},
{0,70,105,169,296,473,473,409,378,354,213,147,61,1},
{356,384,416,456,453,403,396,372},
{199,137,7,106} };

   private int points0[][] = { {243, 372}, {384,378}, {203,249}, {415,239}, {351,76}, {295,75}, {308,181}, {229,176}, {220,209}, {194,139}, {228,155}, {269,139}, {365,157}, {310,365}, {277,45}, {360,46}  };

   private int points1[][] = { {184, 426}, {265, 216}, {501,230}, {154,293}, {290,80}, {51,269}, {102,345}, {262,387}, {244,304}, {99,239}, {265,162}, {337,281}, {94,63}, {621,383}, {608,136} };

   private String Image0[] = { "Button_1", "Button_2", "Button_3", "Button_4", "Button_5", "Button_6", "Cystic_space_1", "Cystic_space_2", "Bleeding_1", "Bleeding_2", "Bleeding_3", "Tumor", "Ventricles", "Cerebellum", "Hemisphere_1", "Hemisphere_2" };

   private String Image1[] = { "Button", "Cystic_space_1", "Cystic_space_2", "Cystic_space_3", "Bleeding_1", "Bleeding_2", "Bleeding_3","Bleeding_4", "Bleeding_5", "Bleeding_6", "Bleeding_7", "Tumor", "Hemisphere", "Ventricle_1", "Ventricle_2" };
 
   private String Title0[], Title1[];
   private MenuItem M0[], M1[];
   private PopupMenu pop0, pop1;
 //  private Graphics gContext;
 //  private Image buffer;

   public SelfContainedCanvas(Image I, Image TT, int N)
   {                            
      pop0 = new PopupMenu( "Image0_t" );
      pop1 = new PopupMenu( "Image1_t" );
      M0 = new MenuItem[Image0.length];
      M1 = new MenuItem[Image1.length];

      for( int m = 0; m < Image0.length; m++ )
      {
         M0[m] = new MenuItem( Image0[m] );
         pop0.add( M0[m] );
         M0[m].addActionListener( this );
      }

      for( int m = 0; m < Image1.length; m++ )
      {
         M1[m] = new MenuItem( Image1[m] );
         pop1.add( M1[m] );
         M1[m].addActionListener( this );
      }

      add( pop0 );
      add( pop1 );
      enableEvents( AWTEvent.MOUSE_EVENT_MASK );

      s = new String[2];
      s[0] = "Brain Tumor";
      s[1] = "BT-Close Up";
 
      info0 = new String[xValues0.length];
      info1 = new String[xValues1.length];
      p0 = new Polygon[xValues0.length];
      p1 = new Polygon[xValues1.length];
 
   info0[0] = "Buttons used to protect delicate brain tissue when mounting the specimen";
   info0[1] = "Cystic spaces within tumor";
   info0[2] =  "Bleeding within brain tumor";
   info0[3] = "Malignant brain tumor"; 
   info0[4] = "Compressed lateral ventricles"; 
   info0[5] = "Cerebellum"; 
   info0[6] = "Cerebral hemisphere";

   info1[0] = "Buttons used to protect delicate brain tissue when mounting the specimen";
   info1[1] = "Cystic area in brain tumor";
   info1[2] = "Area of bleeding (haemorrhage) in brain tumor ";
   info1[3] = "Malignant brain tumor"; 
   info1[4] = "Cerebral hemisphere"; 
   info1[5] = "Compressed ventricle"; 
 
      for (int j = 0; j < xValues0.length; j++ )
         p0[j] = new Polygon();

      for (int j = 0; j < xValues1.length; j++ )
         p1[j] = new Polygon();

      for (int row = 0; row < xValues0.length; row++)
         for (int col = 0; col < xValues0[row].length; col++)
            p0[row].addPoint( xValues0[row][col], yValues0[row][col] );

      for (int row = 0; row < xValues1.length; row++)
         for (int col = 0; col < xValues1[row].length; col++)
            p1[row].addPoint( xValues1[row][col], yValues1[row][col] );

      font1 = new Font( "Serif", Font.BOLD, 22 );
      font2 = new Font ("SansSerif", Font.PLAIN, 14 );
      Show = new Label( " Directions: " );
      Show0 = new Label( " 1. Choose an image in the List box. " );
      Show1 = new Label( " 2. Left click on any part of the image " );
      Show2 = new Label( "     to show the information specific for that part. " );
      Show3 = new Label( " 3. Right click on empty part to bring up a popup menu " );
      Show4 = new Label( "     to find where the part you are interested in is . " );

      T  = I;
      ImageNo = N;
      tar = TT;
 //     buffer = createImage( T.getWidth( this ), T.getHeight( this ) );
 //     gContext = buffer.getGraphics();
 //     gContext.setColor( Color.white );
 //     gContext.fillRect( 0, 0, T.getWidth( this ), T.getHeight( this) );

      showFrame0 = new ColorFrame(s[0]);
      showFrame1 = new ColorFrame(s[1]);

      addMouseListener( this );
   }

   public void actionPerformed( ActionEvent e )
   {
      if( Flags == true )
      {
      if( ImageNo == 0)
         for (int i = 0; i < M0.length; i++ )
            if( e.getSource() == M0[i] )
            {
               aa = points0[i][0];
               bb = points0[i][1];
            }
      if( ImageNo == 1)
         for (int j = 0; j < M1.length; j++ )
            if( e.getSource() == M1[j] )
            {
               aa = points1[j][0];
               bb = points1[j][1];
            }    
      repaint();
      }
   }

   public void processMouseEvent( MouseEvent e )
   {
      if( Flags == true )
      {
      if ( ImageNo == 0 && e.isPopupTrigger() )
         pop0.show( this, e.getX(), e.getY() );

      if ( ImageNo == 1 && e.isPopupTrigger() )
         pop1.show( this, e.getX(), e.getY() );

      super.processMouseEvent( e );
      }
   }

   public void reSetArrow( int a, int b )
   {
     aa = a;
     bb = b;
     repaint();
   }

   public void setValues(Image IM, Image TT, int NN)
   {
      Flags = true;
      T  = IM;
      tar = TT;
      ImageNo = NN;
      repaint();
   }
    
   public void paint( Graphics g )
   {
         g.setColor( Color.red);
         g.setFont( font1 );
         g.drawString(Show.getText(), 20, 40);

         g.setColor( Color.black);
         g.setFont( font2);
         g.drawString(Show0.getText(), 30, 90);
         g.drawString(Show1.getText(), 30, 120);
         g.drawString(Show2.getText(), 30, 150);
         g.drawString(Show3.getText(), 30, 180);
         g.drawString(Show4.getText(), 30, 210);

         if( Flags == true )
         {
            g.drawImage( T, 0, 0, this );
 //           gContext.fillRect( 0, 0, T.getWidth( this ), T.getHeight( this) );
 //           gContext.drawImage( T, 0, 0, this );
            g.drawImage( tar, aa, bb, this );
         }
   }

   public void mouseClicked( MouseEvent e )
   {
      xPos = e.getX();
      yPos = e.getY();

      if( Flags = true )
      {
      if( ImageNo == 0 && ( ! e.isPopupTrigger() ) )
      {
         if( p0[0].contains( xPos, yPos )||p0[1].contains( xPos, yPos )
         || p0[2].contains( xPos, yPos )||p0[3].contains( xPos, yPos )
         || p0[4].contains( xPos, yPos )||p0[5].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[0]);
         }
         else if( p0[6].contains( xPos, yPos ) || p0[7].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[1]);
         }
         else if (p0[8].contains( xPos, yPos ) || p0[9].contains( xPos, yPos )
               || p0[10].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[2]);
         }
         else if (p0[11].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[3]);
         }
         else if (p0[12].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[4]);
         }
         else if (p0[13].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[5]);
         }
         else if (p0[14].contains( xPos, yPos ) || p0[15].contains( xPos, yPos ) )
         {
            showFrame0.setVisible(true);
            showFrame0.setInfo(info0[6]);
         }
         else
            showFrame0.setVisible(false);
      }


      if( ImageNo == 1 && ( ! e.isPopupTrigger() ) )   {
         if( p1[0].contains( xPos, yPos ) )
         {
            showFrame1.setVisible(true);
            showFrame1.setInfo(info1[0]);
         }
         else if( p1[1].contains( xPos, yPos ) || 
		  p1[2].contains( xPos, yPos ) ||
		  p1[3].contains( xPos, yPos ) )
         {
            showFrame1.setVisible(true);
            showFrame1.setInfo(info1[1]);
         }
         else if( p1[4].contains( xPos, yPos ) || 
                  p1[5].contains( xPos, yPos ) ||
                  p1[6].contains( xPos, yPos ) ||
                  p1[7].contains( xPos, yPos ) || 
                  p1[8].contains( xPos, yPos ) || 
                  p1[9].contains( xPos, yPos ) ||
                  p1[10].contains( xPos, yPos ) )
         {
            showFrame1.setVisible(true);
            showFrame1.setInfo(info1[2]);
         }
         else if (p1[11].contains( xPos, yPos ) )
         {
            showFrame1.setVisible(true);
            showFrame1.setInfo(info1[3]);
         }
         else if (p1[12].contains( xPos, yPos ) )
         {
            showFrame1.setVisible(true);
            showFrame1.setInfo(info1[4]);
         }
         else if( p1[13].contains( xPos, yPos ) || 
                  p1[14].contains( xPos, yPos ) )
         {
            showFrame1.setVisible(true);
            showFrame1.setInfo(info1[5]);
         }
         else
            showFrame1.setVisible(false);
      }
    }
    }

   public void mousePressed( MouseEvent e ) { }
   public void mouseReleased( MouseEvent e ) { }
   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
}

class ColorFrame extends Frame implements ActionListener, ItemListener {
   private String ss;
   private TextArea t;
   private String fontNames[] =
      { "TimesRoman", "Courier", "Helvetica" };
   private String colorNames[] =
      { "Black", "Red", "Green", "Blue" };
   private Color colorValues[] =
      { Color.black, Color.red, Color.green, Color.blue };

   private MenuBar bar;
   private Menu formatMenu, fontMenu, colorMenu;
   private MenuItem fonts[], colors[];
   private CheckboxMenuItem readOnly;

   public ColorFrame( String s )
   {
      super( s );
      setSize( 275, 150 );
      setLocation(360, 0);
  
      t = new TextArea( ss, 2, 20,
                        TextArea.SCROLLBARS_VERTICAL_ONLY);
      
      add( t, BorderLayout.CENTER );

      t.setFont( new Font( "TimesRoman", Font.PLAIN, 12 ) );
      t.setForeground( colorValues[ 0 ] );

      bar = new MenuBar();

      formatMenu = new Menu( "Format" );

      fontMenu = new Menu( "Font" );

      fonts = new MenuItem[ fontNames.length ];

      for ( int i = 0; i < fonts.length; i++ ) {
         fonts[ i ] = new MenuItem( fontNames[ i ] );
         fontMenu.add( fonts[ i ] );
         fonts[ i ].addActionListener( this );
      }

      formatMenu.add( fontMenu );
      formatMenu.addSeparator();

      colorMenu = new Menu( "Color" );

      colors = new MenuItem[ colorNames.length ];

      for ( int i = 0; i < colors.length; i++ ) {
         colors[ i ] = new MenuItem( colorNames[ i ] );
         colorMenu.add( colors[ i ] );
         colors[ i ].addActionListener( this );
      }

      formatMenu.add( colorMenu );
      formatMenu.addSeparator();

      readOnly = new CheckboxMenuItem( "Read-Only" );
      readOnly.addItemListener( this );

      formatMenu.add( readOnly );

      bar.add( formatMenu );

      setMenuBar( bar );
 
      addWindowListener( new CloseWindow() );
   }

   public void setInfo( String s1 )
   {
      ss = s1;
      t.setText( ss );
   }

   public void actionPerformed( ActionEvent e )
   {
      for ( int i = 0; i < fonts.length; i++ )
         if ( e.getSource() == fonts[ i ] ) {
            t.setFont( new Font( fonts[ i ].getLabel(),
               Font.PLAIN, 12 ) );
            break;
         }

      for ( int i = 0; i < colors.length; i++ )
         if ( e.getSource() == colors[ i ] ) {
            t.setForeground( colorValues[ i ] );
            break;
         }
   }

   public void itemStateChanged( ItemEvent e )
   {
      t.setEditable( ! t.isEditable() );
   }
}

class CloseWindow extends WindowAdapter {
   public void windowClosing( WindowEvent e )
   {
      e.getWindow().setVisible( false );
   }
}