import java.lang.*;
import java.awt.*;
import java.applet.*;




/*
 *	Purpose: The main program of the applet
 */
public class InsertionSort extends Applet {
  public void init() {
   setLayout(new BorderLayout());
   ITextPanel WritingArea = new ITextPanel();
   ISortPanel DrawingArea = new ISortPanel();
   IMainPanel MainArea = new IMainPanel(DrawingArea, WritingArea);
   add("Center", MainArea);
   add("North", new IControlPanel(MainArea, this));

  }
}



/*
 *	Purpose: The container panel for the whole applet
 */
class IMainPanel extends Panel {
  public ISortPanel panel1;
  public ITextPanel panel2;

  public IMainPanel(ISortPanel p, ITextPanel t) {
   panel1 = p;
   panel2 = t;

   setLayout(new GridLayout(2, 1));	/* 2 rows, 1 column */
   add(p);
   add(t);
  }

}	/* End Class IMainPanel */



/*
 *	Purpose: Drawing the text description	
 */
class ITextPanel extends Panel {
  private int TOPMARGIN=50;
  private int LEFTMARGIN=30;

  public boolean AnimationNext[] = new boolean[15];
  public int NextStep=0;

  private Font f;
  private String Description[][] = new String[15][5];

  public ITextPanel() {
   setBackground(new Color(255, 248, 220));	/* set background as cornsilk */

   f  = new Font("Helvetica", Font.PLAIN, 16);


   Description[0][0] = "The leftmost value (3) can be said to be sorted in";
   Description[0][1] = "relation to itself. Thus, we don't need to do any-";
   Description[0][2] = "thing.";
   Description[0][3] = "";
   Description[0][4] = "";
   AnimationNext[0] = false;

   Description[1][0] = "Check to see if the second value (10) is smaller";
   Description[1][1] = "than the first one (3). If it is so, we swap these";
   Description[1][2] = "two values. But this time we don't need to swap.";
   Description[1][3] = "";
   Description[1][4] = "";
   AnimationNext[1] = false;

   Description[2][0] = "The blue portion (the first two values) are now";
   Description[2][1] = "relatively sorted.";
   Description[2][2] = "";
   Description[2][3] = "";
   Description[2][4] = "";
   AnimationNext[3] = false;

   Description[3][0] = "Next, we need to insert the third value (4) into the";
   Description[3][1] = "blue portion so that after insertion, the blue portion";
   Description[3][2] = "will still be relatively sorted.";
   Description[3][3] = "";
   Description[3][4] = "";
   AnimationNext[3] = false;

   Description[4][0] = "Remove the third value first.";
   Description[4][1] = "";
   Description[4][2] = "";
   Description[4][3] = "";
   Description[4][4] = "";
   AnimationNext[4] = true;

   Description[5][0] = "Slide the second value (10) over to make room for."; 
   Description[5][1] = "insertion.";
   Description[5][2] = "";
   Description[5][3] = "";
   Description[5][4] = "";
   AnimationNext[5] = true;

   Description[6][0] = "Insert the value 4 into appropriate position.";
   Description[6][1] = "";
   Description[6][2] = "";
   Description[6][3] = "";
   Description[6][4] = "";
   AnimationNext[6] = true;

   Description[7][0] = "Now the first three values are relatively sorted";
   Description[7][1] = "and we insert the fourth value into these three";
   Description[7][2] = "values. The first four values should be relatively";
   Description[7][3] = "sorted after insertion.";
   Description[7][4] = "";
   AnimationNext[7] = true;

   Description[8][0] = "Repeat the process until the last value is inserted.";
   Description[8][1] = "";
   Description[8][2] = "";
   Description[8][3] = "";
   Description[8][4] = "";
   AnimationNext[8] = true;

   Description[9][0] = "The whole array is sorted now.";
   Description[9][1] = "";
   Description[9][2] = "";
   Description[9][3] = "";
   Description[9][4] = "";
   AnimationNext[9] = true;

  }

  public void paint(Graphics g) {
   g.drawRect(0, 0, size().width-1, size().height-1);

   g.setFont(f);
   for (int i=0; i<5; i++) {
    g.drawString(Description[NextStep][i], LEFTMARGIN, TOPMARGIN+18*i); 
   }
  }


  /*
   *	Purpose: executed when the next button is pushed
   */
  public void Next() {
   NextStep++;
   repaint();
  }

  /*
   *	Purpose: reset this panel to the begining situation
   */
  public void reset() {
   NextStep=0;
   repaint();
  }

}	/* End Class ITextPanel */


/*
 *	Purpose: the control panel
 */
class IControlPanel extends Panel {
  IMainPanel MainArea;
  Button b1, b2, b3, bsound;
  Checkbox cb_sound;
  Applet applet;
  boolean voice = false;
  AudioClip ac=null;

  String sound[] = new String[10];


  public IControlPanel(IMainPanel m, Applet app) {
   MainArea = m;
   applet = app;

   sound[0] = "sound/insert1.au";
   sound[1] = "sound/insert2.au";
   sound[2] = "sound/insert3.au";
   sound[3] = "sound/insert4.au";
   sound[4] = "sound/insert5.au";
   sound[5] = "sound/insert6.au";
   sound[6] = "sound/insert7.au";
   sound[7] = "sound/insert8.au";
   sound[8] = "sound/insert9.au";
   sound[9] = "sound/insert10.au";

   setLayout(new FlowLayout(FlowLayout.LEFT));
   setBackground(Color.lightGray);
   b1 = new Button("Start Animation");
   b2 = new Button("  Next  ");
   reset();
   add(b1);
   add(b2);

   cb_sound = new Checkbox("Voice Description");
   cb_sound.setState(false);
   add(cb_sound);
  }	/* End Method IControlPanel() */


  /*
   *	build in function to control events
   */
  public boolean action(Event e, Object arg) {
   
   if (e.target instanceof Button) {
     String str = ((Button)(e.target)).getLabel();
     if (str.equals("Start Animation")) {
	b1.disable();
	cb_sound.disable();
	MainArea.panel1.Next();
	cb_sound.enable();
	b2.enable();
     } else if (str.equals("  Next  ")) {
	b2.disable();
	MainArea.panel2.Next();
        if (voice) {
/*	  applet.play(applet.getCodeBase(), sound[MainArea.panel2.NextStep]);
*/
          if (ac != null) ac.stop();
          ac = applet.getAudioClip(applet.getCodeBase(), sound[MainArea.panel2.NextStep]);
          ac.play();
        }

	if (MainArea.panel2.NextStep <= 3) MainArea.panel1.Next();

	if (MainArea.panel2.AnimationNext[MainArea.panel2.NextStep]) {
	   if (MainArea.panel2.NextStep < 9)
	     b1.enable();
	   else {
	     b2.setLabel("Restart");
	     b2.enable();
           }
	} else {
	   b2.enable();
	}
     } else if (str.equals("Restart")) {
	MainArea.panel1.reset();
	MainArea.panel2.reset();
	b2.setLabel("  Next  ");
	reset();
     } else if (str.equals("Voice Description")) {
        System.out.println(applet.getCodeBase());
        applet.play(applet.getCodeBase(), sound[MainArea.panel2.NextStep]);
     } else if (str.equals("Disable Voice")) {
        voice = false;
        bsound.setLabel("Enable Voice");
     } else if (str.equals("Enable Voice")) {
        voice = true;
        bsound.setLabel("Disable Voice");
        applet.play(applet.getCodeBase(), sound[MainArea.panel2.NextStep]);
     }

   } else if (e.target instanceof Checkbox) {
     Checkbox cb = (Checkbox)e.target;
     String str = cb.getLabel();

     if (str.equals("Voice Description")) {
       if (cb.getState()) {
         voice = true;
/*         applet.play(applet.getCodeBase(), sound[MainArea.panel2.NextStep]);
*/
         if (ac != null) ac.stop();
         ac = applet.getAudioClip(applet.getCodeBase(), sound[MainArea.panel2.NextStep]);
         ac.play();
       } else {
         voice = false;
         ac.stop();
       }
     }

   }


   return true;
  }	/* End Method action() */


  /*
   *	Purpose: reset this panel to the initial situation
   */
  public void reset() {
   b1.disable();
   b2.enable();
  }

}
