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


class SSortPanel extends Canvas {
  private int LEFTMARGIN=50;
  private int TOPMARGIN=80;
  private int BOXSIZE=30;
  private int NextStep=0;

  private int UP=-35;
  private int NORMAL=0;
  private int DOWN=35;

  private Font f;
  private long PAUSE_TIME=300;

  private int I=-1;
  private int J=-1;

  public int arr[];
  public int posx[];
  public int posy[];

  private int blue=10;
  private int current;
  private boolean Erase=false;

  private Thread kicker;


  public SSortPanel() {
   /* set background as White */
   setBackground(Color.white);

   int a[] = new int[10];
   arr = a;

   int px[] = new int[10];
   posx = px;

   int py[] = new int[10];
   posy = py;

   f = new Font("Courier", Font.PLAIN, 14);
   reset();
  }

  public void reset()
  {
   NextStep = 0;
   blue=10;
   current=1;

   for (int i=0; i<10; i++) {
        posx[i] = i;
        posy[i] = NORMAL;
   }

   arr[0] = 3;  arr[1] = 10;  arr[2] = 4;  arr[3] = 6;  arr[4] = 8;
   arr[5] = 9;  arr[6] = 7;   arr[7] = 2;  arr[8] = 1;  arr[9] = 5;

   repaint();
  }

  public void paint(Graphics g) {

   System.out.println("paint!");
   if (I<0) g.clearRect(0, 0, size().width-1, size().height-1);
   g.drawRect(0, 0, size().width-1, size().height-1);

   g.setFont(f);

   if (I>=0) {
     if (Erase) {
	EraseElement(g, I, posx[I], posy[I]); 
	EraseElement(g, J, posx[J], posy[J]);
	return;
     } else {
	if (posy[I] == UP) g.setColor(Color.red);
	if (posy[I] == DOWN) g.setColor(Color.red);
	DrawElement(g, I, posx[I], posy[I]); 
	if (J >= blue)
	  g.setColor(Color.blue);
	else
	  g.setColor(Color.black);
	if (posy[J] == UP) g.setColor(Color.red);
	if (posy[J] == DOWN) g.setColor(Color.red);
	DrawElement(g, J, posx[J], posy[J]);
	return;
     }
   }

   for (int i=0; i<10; i++) {
    if (i >= blue)
	g.setColor(Color.blue);
    else
	g.setColor(Color.black);
/*    if (posy[i] == UP) g.setColor(Color.red);
    if (posy[i] == DOWN) g.setColor(Color.green);  */
    DrawElement(g, i, posx[i], posy[i]);
   }

  }

  public void update(Graphics g) { 
	System.out.println("update!"); 
	this.paint(g); 
  }

  public void EraseElement(Graphics g, int index, int positionX, int positionY) {

   g.clearRect(LEFTMARGIN+(BOXSIZE+1)*positionX, TOPMARGIN+positionY,
                BOXSIZE+1, BOXSIZE+1);
  }

  public void DrawElement(Graphics g, int index, int positionX, int positionY) {

   if (current == index ) {
     g.setColor(Color.red);
     g.drawOval(LEFTMARGIN+(BOXSIZE+1)*positionX+2, TOPMARGIN+positionY+2, 
                BOXSIZE-4, BOXSIZE-4);
   } else {
     g.drawRect(LEFTMARGIN+(BOXSIZE+1)*positionX, TOPMARGIN+positionY, 
                BOXSIZE, BOXSIZE);
   }

   g.drawString(Integer.toString(arr[index]),
         LEFTMARGIN+(BOXSIZE+1)*positionX+8, TOPMARGIN+20+positionY);
  }


  public void Swap(int i, int j) {

   /* Wait a while before really start the swap */
   try {
       Thread.sleep(PAUSE_TIME);
   } catch (InterruptedException e1){
   }

   if (i==j) {
     blue--;
     I=J=i;
     paint(this.getGraphics());
getToolkit().sync();
     try {
       Thread.sleep(PAUSE_TIME);
     } catch (InterruptedException e1){
     }
     I=J=-1;
     return;
   }

   I=i; J=j;

   Erase=true;
   paint(this.getGraphics()); 
getToolkit().sync();
   posy[i] = UP;
   posy[j] = DOWN;
   Erase=false;
   paint(this.getGraphics()); 
getToolkit().sync();
   try {
     Thread.sleep(PAUSE_TIME);
   } catch (InterruptedException e1){
   }

   for (int k=0; k<j-i; k++) {
     Erase=true;
     paint(this.getGraphics()); 
getToolkit().sync();
     posx[i] = posx[i] + 1;
     posx[j] = posx[j] - 1;
    
     Erase=false;
     paint(this.getGraphics()); 
getToolkit().sync();

     try {
       Thread.sleep(PAUSE_TIME);
     } catch (InterruptedException e2){
     }
   }


   Erase=true;
   paint(this.getGraphics());
getToolkit().sync();

   blue--;
   posy[i] = NORMAL;
   posy[j] = NORMAL;

   int tmp = arr[i];
   arr[i] = arr[j];
   arr[j] = tmp;

   posx[i] = i;
   posx[j] = j;

   Erase=false;
   paint(this.getGraphics());
getToolkit().sync();

   I=J=-1;
  }


  public void Next() {
   Draw draw = new Draw();

   draw.SetSSortPanel(this);
   switch (NextStep) {

    case 0:
	current = -1;
	Swap(1, 9);
	break;

    case 1:
	current = 5;
	repaint();
	break;

    case 2:
	current = -1;
	Swap(5, 8);
	break;

    case 3:
	Swap(4, 7);
	Swap(6, 6);
	Swap(3, 5);
	Swap(1, 4);
	break;

    case 4:
	Swap(2, 3);
	Swap(0, 2);
	Swap(1, 1);
	Swap(0, 0);
	break;

    default:
   }

   NextStep++;
  }

}


class Draw extends Thread {
  private int I[] = new int[100];
  private int J[] = new int[100];
  private int count=0;
  private SSortPanel p;

  public void SetSSortPanel(SSortPanel panel) {
   p = panel;
  }

  public void AddSwapIndex(int i, int j) {
   I[count]=i; 
   J[count]=j;
   count++;
  }

  public void run() { 
    for (int i=0; i<count; i++) p.Swap(I[i], J[i]);
  }

}

