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

public class container extends Applet implements Runnable{

   Image os;
   Graphics og;
   Thread th = null;
   int co;
   double pi = 3.14159263 / 2;
   double rs[] = new double[3];
   int td[][] = new int[4][3];
   int px,py,pr,pn,kx,ky;
   int sx=3,sy=0,sw;
   int fg,dd = -1;
   Button shuf;

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

      setLayout(new BorderLayout());
      Panel pan = new Panel();
      pan.setLayout(new FlowLayout());
      pan.add(shuf = new Button("  shuffle  "));
      add("South",pan);

      for(int i1 = 0;i1 < 4;i1 ++){
         for(int i2 = 0;i2 < 3;i2 ++){
            td[i1][i2] = i1 + 1;
         }
      }
      td[3][0] = 0;

      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               if(fg == 0){
                  px = e.getX();
                  py = e.getY();
                  pr = (int)Math.sqrt((px-160)*(px-160)+(py-160)*(py-160));
                  if((px>180)&&(px<300)&&(py>140)&&(py<180)){
                     if(sx == 0){
                        pn = (px - 180) / 40;
                        if(sy == 0){
                           if(pn == 1){
                              td[0][0] = td[0][1] ; td[0][1] = 0 ; sy = 1 ; repaint() ;
                           }else if(pn == 2){
                              td[0][0] = td[0][1] ; td[0][1] = td[0][2] ; td[0][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 1){
                           if(pn == 0){
                              td[0][1] = td[0][0] ; td[0][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 2){
                              td[0][1] = td[0][2] ; td[0][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 2){
                           if(pn == 0){
                              td[0][2] = td[0][1] ; td[0][1] = td[0][0] ; td[0][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 1){
                              td[0][2] = td[0][1] ; td[0][1] = 0 ; sy = 1 ; repaint() ;
                           }
                        }
                     }
                  }else if((px>140)&&(px<180)&&(py>180)&&(py<300)){
                     if(sx == 1){
                        pn = (py - 180) / 40;
                        if(sy == 0){
                           if(pn == 1){
                              td[1][0] = td[1][1] ; td[1][1] = 0 ; sy = 1 ; repaint() ;
                           }else if(pn == 2){
                              td[1][0] = td[1][1] ; td[1][1] = td[1][2] ; td[1][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 1){
                           if(pn == 0){
                              td[1][1] = td[1][0] ; td[1][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 2){
                              td[1][1] = td[1][2] ; td[1][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 2){
                           if(pn == 0){
                              td[1][2] = td[1][1] ; td[1][1] = td[1][0] ; td[1][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 1){
                              td[1][2] = td[1][1] ; td[1][1] = 0 ; sy = 1 ; repaint() ;
                           }
                        }
                     }
                  }else if((px>20)&&(px<140)&&(py>140)&&(py<180)){
                     if(sx == 2){
                        pn = 2 - (px - 20) / 40;
                        if(sy == 0){
                           if(pn == 1){
                              td[2][0] = td[2][1] ; td[2][1] = 0 ; sy = 1 ; repaint() ;
                           }else if(pn == 2){
                              td[2][0] = td[2][1] ; td[2][1] = td[2][2] ; td[2][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 1){
                           if(pn == 0){
                              td[2][1] = td[2][0] ; td[2][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 2){
                              td[2][1] = td[2][2] ; td[2][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 2){
                           if(pn == 0){
                              td[2][2] = td[2][1] ; td[2][1] = td[2][0] ; td[2][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 1){
                              td[2][2] = td[2][1] ; td[2][1] = 0 ; sy = 1 ; repaint() ;
                           }
                        }
                     }
                  }else if((px>140)&&(px<180)&&(py>20)&&(py<140)){
                     if(sx == 3){
                        pn = 2 - (py - 20) / 40;
                        if(sy == 0){
                           if(pn == 1){
                              td[3][0] = td[3][1] ; td[3][1] = 0 ; sy = 1 ; repaint() ;
                           }else if(pn == 2){
                              td[3][0] = td[3][1] ; td[3][1] = td[3][2] ; td[3][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 1){
                           if(pn == 0){
                              td[3][1] = td[3][0] ; td[3][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 2){
                              td[3][1] = td[3][2] ; td[3][2] = 0 ; sy = 2 ; repaint() ;
                           }
                        }else if(sy == 2){
                           if(pn == 0){
                              td[3][2] = td[3][1] ; td[3][1] = td[3][0] ; td[3][0] = 0 ; sy = 0 ; repaint() ;
                           }else if(pn == 1){
                              td[3][2] = td[3][1] ; td[3][1] = 0 ; sy = 1 ; repaint() ;
                           }
                        }
                     }
                  }else if(pr<20){
                     dd = -1 * dd;
                  }else if((pr>20)&&(pr<60)){
                     fg = 1;
                     th.resume();
                  }else if((pr>60)&&(pr<100)){
                     fg = 2;
                     th.resume();
                  }else if((pr>100)&&(pr<140)){
                     fg = 3;
                     th.resume();
                  }
                  repaint();
               }
            }
         }
      );

      shuf.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            for(int k = 0;k < 50;k ++){
               if(Math.random() < 0.2){
                  if(sy == 0){
                     td[sx][0] = td[sx][1] ; td[sx][1] = 0 ; sy = 1;
                  }else if(sy == 1){
                     td[sx][1] = td[sx][2] ; td[sx][2] = 0 ; sy = 2;
                  }
               }else if(Math.random() < 0.4){
                  if(sy == 2){
                     td[sx][2] = td[sx][1] ; td[sx][1] = 0 ; sy = 1;
                  }else if(sy == 1){
                     td[sx][1] = td[sx][0] ; td[sx][0] = 0 ; sy = 0 ;
                  }
               }else{
                  sw = td[0][sy] ; td[0][sy] = td[1][sy] ; td[1][sy] = td[2][sy] ; td[2][sy] = td[3][sy] ; td[3][sy] = sw;
                  sx = sx - 1;
                  if(sx < 0)sx = 3;
               }

            }
            repaint();
         }
      });

   }

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

      og.setColor(new Color(0,0,255));
      og.fillArc(10,10,300,300,75,30);
      og.setColor(new Color(255,0,0));
      og.fillArc(10,10,300,300,345,30);
      og.setColor(new Color(0,255,0));
      og.fillArc(10,10,300,300,165,30);
      og.setColor(new Color(255,255,0));
      og.fillArc(10,10,300,300,255,30);
      og.setColor(Color.gray);
      og.drawArc(10,10,300,300,75,30);
      og.drawArc(10,10,300,300,345,30);
      og.drawArc(10,10,300,300,165,30);
      og.drawArc(10,10,300,300,255,30);
      for(int r = 0;r < 3;r ++){
         og.setColor(new Color(255,150+20*r,150+20*r)); 
         og.fillOval(20+40*r,20+40*r,280-80*r,280-80*r);
         og.setColor(Color.gray);
         og.drawOval(20+40*r,20+40*r,280-80*r,280-80*r);
      }
      og.setColor(Color.white);
      og.fillOval(140,140,40,40);
      og.setColor(Color.gray);
      og.drawOval(140,140,40,40);
      og.drawLine(139,21,139,298);
      og.drawLine(180,21,180,298);
      og.drawLine(21,139,298,139);
      og.drawLine(21,180,298,180);
      og.setColor(Color.black);
      og.drawArc(145,145,30,30,45+dd*45,90);
      og.drawArc(145,145,30,30,45+dd*225,90);
      og.drawString("<",157,165+dd*15);
      og.drawString(">",160,165-1*dd*15);

      for(int i = 0;i < 3;i ++){
         for(int j = 0;j < 4;j ++){
            if(td[j][i] != 0){
               kx = 140+(int)(Math.round((i+1)*40*Math.cos(rs[i]+j*pi)));
               ky = 140+(int)(Math.round((i+1)*40*Math.sin(rs[i]+j*pi)));
               ball(kx,ky,td[j][i]);
            }
         }
      }

      g.drawImage(os,0,0,this);
   }

   public void ball(int x,int y,int c){
      for(int i = 0;i < 20;i++){
         co = (int)(120+100*Math.sin(1.57*i/20));
         switch (c){
            case 1 : og.setColor(new Color(co,0,0)) ; break ;
            case 2 : og.setColor(new Color(co,co,0)) ; break ;
            case 3 : og.setColor(new Color(0,co,0)) ; break ;
            case 4 : og.setColor(new Color(0,0,co)) ; break ;
         }
         og.fillOval(x+i,y+i,40-2*i,40-2*i);
      }
   }

   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{
            if(fg != 0){
               if(dd == -1){
                  rs[fg - 1] = rs[fg - 1] - pi / 30 ;
                  if(rs[fg - 1] < -1 * pi){
                     sw = td[0][fg-1] ; td[0][fg-1] = td[1][fg-1] ; td[1][fg-1] = td[2][fg-1] ; td[2][fg-1] = td[3][fg-1] ; td[3][fg-1] = sw ;
                     if(sy == fg - 1)sx -- ; if(sx < 0)sx = 3 ;
                     rs[fg - 1] = 0;
                     fg = 0;
                     th.suspend();
                  }
               }else if(dd == 1){
                  rs[fg - 1] = rs[fg - 1] + pi / 30 ;
                  if(rs[fg - 1] > pi){
                     sw = td[3][fg-1] ; td[3][fg-1] = td[2][fg-1] ; td[2][fg-1] = td[1][fg-1] ; td[1][fg-1] = td[0][fg-1] ; td[0][fg-1] = sw ;
                     if(sy == fg - 1)sx ++ ; if(sx > 3)sx = 0 ;
                     rs[fg - 1] = 0;
                     fg = 0;
                     th.suspend();
                  }
               }
            }
            Thread.sleep(30);
         }
         catch (InterruptedException e){
         }
         repaint();
      }
   }

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