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

public class transpose extends Applet implements Runnable{

   Thread th = null;
   Image os;
   Graphics og;
   Image koma[] = new Image[5];
   int pd[][] = new int[3][3];
   int pa[][] = new int[3][3];
   int pn = 0;
   int gd[][][] = {{{1,4,1},{4,0,4},{5,4,5}},
                   {{2,4,2},{4,0,4},{5,4,5}},
                   {{1,4,1},{4,0,4},{2,4,2}},
                   {{1,3,1},{3,0,3},{2,3,2}},
                   {{2,3,2},{3,0,3},{1,3,1}},
                   {{3,3,3},{4,0,4},{5,5,5}},
                   {{4,4,4},{3,0,3},{5,5,5}},
                   {{4,3,4},{5,0,5},{5,5,5}}};
   int ad[][][] = {{{5,4,5},{4,0,4},{1,4,1}},
                   {{5,4,5},{4,0,4},{2,4,2}},
                   {{2,4,2},{4,0,4},{1,4,1}},
                   {{2,3,2},{3,0,3},{1,3,1}},
                   {{1,3,1},{3,0,3},{2,3,2}},
                   {{5,5,5},{4,0,4},{3,3,3}},
                   {{5,5,5},{3,0,3},{4,4,4}},
                   {{5,5,5},{5,0,5},{4,3,4}}};
   int skn = 0;
   int kme[][][] = {{{0,1,0},{1,0,1},{0,1,0}},
                    {{1,0,1},{0,0,0},{1,0,1}},
                    {{1,1,1},{1,0,1},{0,1,0}},
                    {{1,1,1},{0,0,0},{1,0,1}},
                    {{0,1,0},{0,0,0},{0,0,0}}};
   int tx,ty,dx,dy;
   int sx1 = -1,sy1,sx2,sy2;
   int kx = 1,ky = 1;
   Choice cho = new Choice();
   Button rep,und;
   Label spa;

   public void init(){
      os = createImage(480,360);
      og = os.getGraphics();
      setBackground(Color.white);
      for(int in = 0;in < 5;in ++){
         koma[in] = getImage(getDocumentBase(),"Picture/koma"+(in+1)+".gif");
      }
      for(int iy = 0;iy < 3;iy ++){
         for(int ix = 0;ix < 3;ix ++){
            pd[iy][ix] = gd[pn][iy][ix];
            pa[iy][ix] = ad[pn][iy][ix];
         }
      }
      setLayout(new BorderLayout());
      Panel pan = new Panel();
      pan.setLayout(new FlowLayout());
      pan.add(und = new Button("  undo  "));
      pan.add(spa = new Label("    "));
      pan.add(rep = new Button("  replay  "));
      pan.add(spa = new Label("              "));
      pan.add(cho);
      cho.addItem("  no.1  ");
      cho.addItem("  no.2  ");
      cho.addItem("  no.3  ");
      cho.addItem("  no.4  ");
      cho.addItem("  no.5  ");
      cho.addItem("  no.6  ");
      cho.addItem("  no.7  ");
      cho.addItem("  no.8  ");
      cho.addItemListener(new MyListener());
      add("South",pan);
      rep.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            R_set();
            repaint();
         }
      });
      und.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            if(sx1 != -1){
               pd[sy2][sx2] = pd[sy1][sx1];pd[sy1][sx1] = 0;
               kx = sx1 ; ky = sy1 ; sx1 = -1;
               repaint();
            }
         }
      });
      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               dx = (e.getX() - 40) / 80;
               dy = (e.getY() - 40) / 80;
               if(skn != 0){
                  if(kme[skn-1][1+ky-dy][1+kx-dx] == 1){
                     sx1 = kx ; sy1 = ky ; sx2 = dx ; sy2 = dy;
                     pd[ky][kx] = pd[dy][dx];pd[dy][dx] = 0;
                     kx = dx;ky = dy;
                     repaint();
                  }
               }             
            }
         }
      );
      addMouseMotionListener(
         new MouseMotionAdapter(){
            public void mouseMoved(MouseEvent e){
               tx = (e.getX() - 40) / 80;
               ty = (e.getY() - 40) / 80;
               if((tx >= 0)&&(tx < 3)&&(ty >= 0)&&(ty < 3)){
                  skn = pd[ty][tx];
               }
               repaint();
            }
         }
      );
   }
   class MyListener implements ItemListener{
      public void itemStateChanged(ItemEvent e){
         Choice cho = (Choice)e.getSource();
         switch(cho.getSelectedIndex()){
            case 0 : pn = 0 ; R_set() ; repaint() ; break;
            case 1 : pn = 1 ; R_set() ; repaint() ; break;
            case 2 : pn = 2 ; R_set() ; repaint() ; break;
            case 3 : pn = 3 ; R_set() ; repaint() ; break;
            case 4 : pn = 4 ; R_set() ; repaint() ; break;
            case 5 : pn = 5 ; R_set() ; repaint() ; break;
            case 6 : pn = 6 ; R_set() ; repaint() ; break;
            case 7 : pn = 7 ; R_set() ; repaint() ; break;
         }
      }
   }

   public void paint(Graphics g){
      og.setColor(Color.white); 
      og.fillRect(0,0,480,360);
      og.setColor(new Color(255,255,230));
      og.fillRect(40,40,240,240);
      og.fillRect(320,30,120,120);
      og.fillRect(320,170,120,120);
      og.setColor(new Color(51,51,51));
      for(int lx = 0;lx < 4;lx ++){
         og.drawLine(lx*80+40,40,lx*80+40,280);
         og.drawLine(40,lx*80+40,280,lx*80+40);
         og.drawLine(lx*40+320,30,lx*40+320,150);
         og.drawLine(320,lx*40+30,440,lx*40+30);
         og.drawLine(lx*40+320,170,lx*40+320,290);
         og.drawLine(320,lx*40+170,440,lx*40+170);
      }
      for(int gy = 0;gy < 3;gy ++){
         for(int gx = 0;gx < 3;gx ++){
            if(pd[gy][gx] != 0){
               og.drawImage(koma[pd[gy][gx]-1],80*gx+40,80*gy+40,this);
            }
            if(pa[gy][gx] != 0){
               og.drawImage(koma[pa[gy][gx]-1],40*gx+320,40*gy+30,40,40,this);
            }
            if(skn != 0){
               if(kme[skn-1][gy][gx] != 0){
                  og.setColor(new Color(100,250,255));
                  og.fillRect(40*gx+322,40*gy+172,37,37);
               }
            }
         }
      }
      if(skn != 0){
         og.drawImage(koma[skn-1],360,210,40,40,this);
      }
      g.drawImage(os,0,0,this);
   }

   public void R_set(){
      for(int iy = 0;iy < 3;iy ++){
         for(int ix = 0;ix < 3;ix ++){
            pd[iy][ix] = gd[pn][iy][ix];
            pa[iy][ix] = ad[pn][iy][ix];
         }
      }
      kx = 1;ky = 1;skn = 0;
      return;
   }

   public void start(){    
      if(th == null){
         th = new Thread(this);
         th.start();
      }
      th.suspend();
   }

   public void stop(){
      th = null;
   }

   public void run(){
      while (th != null){
         try {
            Thread.sleep(100);
         }                   
         catch (InterruptedException e){ }
      }
   }

   public void update(Graphics g){
      paint(g) ;
   }

}