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

public class board_wh extends Applet implements Runnable{

   Image os;
   Graphics og;
   Thread th = null;
   int bd[][] = {{0,0,0,1},{0,0,1,0},{0,0,1,1},{0,1,0,1},
                {1,0,0,1},{0,1,1,0},{0,1,1,1},{1,0,1,1}};
   int td[][][] = {{{1,2,3,4},{0,0,0,0},{5,6,7,8}},
                   {{0,0,0,0},{0,0,0,0},{0,0,0,0}}};
   int hd[][] = new int[4][4];
   int dd = 0,dn = 0;
   int px,py,sx,sy;
   int sw = 0;
   int sp;

   public void init(){
      os = createImage(560,210);
      og = os.getGraphics();
      setBackground(Color.white);


      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               if((e.getClickCount() == 2)&&(Math.abs(e.getX()-280)<80)&&(Math.abs(e.getY()-195)<15)){
                  sw = 0;
                  if((dn == 4)&&(dd == 0)){
                     for(int k = 0;k < 4;k ++){
                        td[1][0][k] = td[0][0][k] ; td[0][0][k] = 0;
                        td[1][2][k] = td[0][2][k] ; td[0][2][k] = 0;
                     }
                     dd = 1;
                  }else if((dn == 4)&&(dd == 1)){
                     for(int k = 0;k < 4;k ++){
                        td[0][0][k] = td[1][0][k] ; td[1][0][k] = 0;
                        td[0][2][k] = td[1][2][k] ; td[1][2][k] = 0;
                     }
                     dd = 0;
                  }
               }else{
                  if(sw == 0){
                     if(dd == 0){
                        sx = (e.getX() - 20) / 180;
                        sy = (e.getY() - 20) / 40;
                     }else if(dd == 1){
                        sx = (e.getX() - 20) / 180;
                        sy = (e.getX() - 20 - sx * 180) / 40;
                     }
                     if(sy > 3)sy = 3;
                     sw = 1;
                  }else if(sw == 1){
                     if((sx == px)&&(sy == py)){
                        if(td[dd][sx][sy] != 0){
                           sp = bd[td[dd][sx][sy]-1][0] ; bd[td[dd][sx][sy]-1][0] = bd[td[dd][sx][sy]-1][3] ; bd[td[dd][sx][sy]-1][3] = sp;
                           sp = bd[td[dd][sx][sy]-1][1] ; bd[td[dd][sx][sy]-1][1] = bd[td[dd][sx][sy]-1][2] ; bd[td[dd][sx][sy]-1][2] = sp;
                        }
                        sw = 0;
                     }else{
                        sp = td[dd][sx][sy] ; td[dd][sx][sy] = td[dd][px][py] ; td[dd][px][py] = sp;
                        sw = 0;
                     }
                  }
               }
               dn = 0;
               for(int k = 0;k < 4;k ++){
                  if(td[0][1][k] != 0)dn ++;
                  if(td[1][1][k] != 0)dn ++;
               }
               if((dn == 4)&&(dd == 1)){
                  for(int t1 = 0;t1 < 4;t1 ++){
                     for(int t2 = 0;t2 < 4;t2 ++){
                        hd[t1][t2] = bd[td[0][1][t1]-1][t2];
                     }
                  }
               }
               repaint();
            }
         }
      );


      addMouseMotionListener(
         new MouseMotionAdapter(){
            public void mouseMoved(MouseEvent e){
               if(dd == 0){
                  px = (e.getX() - 20) / 180;
                  py = (e.getY() - 20) / 40;
               }else if(dd == 1){
                  px = (e.getX() - 20) / 180;
                  py = (e.getX() - 20 - px * 180) / 40;
               }
               if(py > 3)py = 3;
               repaint();
            }
         }
      );

   }

   public void paint(Graphics g){
      og.setColor(Color.white); 
      og.fillRect(0,0,560,210);

      og.setColor(Color.black); 
      og.fillRoundRect(202,22,156,156,15,15);

      if(dd == 0){
         for(int i1 = 0;i1 < 3;i1 ++){
            for(int i2 = 0;i2 < 4;i2 ++){
               if(td[0][i1][i2] != 0)board(20+180*i1,20+40*i2,td[0][i1][i2]);
            }
         }
      }else if(dd == 1){
         dd = 0;
         for(int i0 = 0;i0 < 4;i0 ++){
            if(td[0][1][i0] != 0)board(20+180,20+40*i0,td[0][1][i0]);
         }
         dd = 1;
         for(int i1 = 0;i1 < 3;i1 ++){
            for(int i2 = 0;i2 < 4;i2 ++){
               if(td[1][i1][i2] != 0)board(20+40*i2+180*i1,20,td[1][i1][i2]);
            }
         }
      }   
      if(sw == 1){
         if(dd == 0){
            frame(px*180+20,py*40+20,0);
            frame(sx*180+20,sy*40+20,1);
         }else if(dd == 1){
            frame(px*180+py*40+20,20,0);
            frame(sx*180+sy*40+20,20,1);
         }
      }
      og.setColor(Color.red);
      if(dn == 4)og.drawString("Direction changes by double click.",195,200);
      g.drawImage(os,0,0,this);
   }

   public void board(int x , int y , int no){

      if(dd == 0){
         og.setColor(new Color(153,51,0));
         og.fillRoundRect(x,y,160,40,15,15);
         og.setColor(Color.gray);
         og.drawRoundRect(x,y,160,40,15,15);
         for(int h = 0;h < 4;h ++){
            if(bd[no-1][h] == 1){
               if(x == 200){
                  og.setColor(Color.black);
               }else{
                  og.setColor(Color.white);
               }
               og.fillOval(x+40*h+4,y+4,32,32);
               og.setColor(Color.gray);
               og.drawOval(x+40*h+4,y+4,32,32);
            }
         }
      }else if(dd == 1){
         og.setColor(new Color(153,51,0));
         og.fillRoundRect(x,y,40,160,15,15);
         og.setColor(Color.gray);
         og.drawRoundRect(x,y,40,160,15,15);
         for(int h = 0;h < 4;h ++){
            if(bd[no-1][h] == 1){
               if((x >= 200)&&(x <= 320)){
                  if(hd[h][(x-200)/40] == 1){
                     og.setColor(Color.black);
                  }else{
                     og.setColor(new Color(145,51,0));
                  }
               }else{
                  og.setColor(Color.white);
               }
               og.fillOval(x+4,y+40*h+4,32,32);
               og.setColor(Color.gray);
               og.drawOval(x+4,y+40*h+4,32,32);
            }
         }
      }

   }

   public void frame(int x , int y , int c){
      if(c == 0){
         og.setColor(Color.blue);
      }else if(c == 1){
         og.setColor(Color.green);
      }
      if(dd == 0){
         og.drawRect(x,y,160,40);
         og.drawRect(x-1,y-1,162,42);
      }else if(dd == 1){
         og.drawRect(x,y,40,160);
         og.drawRect(x-1,y-1,42,162);
      }
   }

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

   public void stop(){
      th = null;
   }

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

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