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

public class push_out extends Applet implements Runnable{

   Thread th = null;
   Image os;
   Graphics og;
   int td[][] = {{0,0,0,0,0},{0,2,1,2,1},{0,3,4,3,4},{0,2,1,2,1},{0,3,4,3,4}};
   int arx[] = {10,30,30,60,60,30,30,10},ary[] = {30,10,20,20,40,40,50,30};
   int dax[] = new int[8],day[] = new int[8];
   int br=1,sw=0,mn,cs=0;
   int mx1,my1,mx2,my2,mt1;

   public void init(){
      os = createImage(420,360);
      og = os.getGraphics();

      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               if(cs == 0){
                  if((e.getX()>330)&&(e.getX()<390)){
                     sw = (e.getY()-90)/60+1;
                  }
                  switch (sw){
                     case 1 : mx1 = 90;my1 = 90;mt1 = 1;break;
                     case 2 : mx1 = 90;my1 = 150;mt1 = 1;mx2 = 270;my2 = 90;break;
                     case 3 : mx1 = 90;my1 = 210;mt1 = 1;mx2 = 270;my2 = 150;break;
                     case 4 : mx1 = 90;my1 = 270;mt1 = 1;mx2 = 270;my2 = 210;break;
                  }
                  cs = 1;
                  repaint();
               }
            }
         } 
      );

   }

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

      for(int d1 = 1;d1 < 5;d1 ++){
         for(int d2 = 1;d2 < 5;d2 ++){
            if(mt1 == 1){
               if(sw != d2)d_cube(td[d2][d1],d1*60+30,d2*60+30);
            }else if(mt1 == 2){
               if((d1 != 4)||(d2 > sw))d_cube(td[d2][d1],d1*60+30,d2*60+30);
            }else{
               d_cube(td[d2][d1],d1*60+30,d2*60+30);
            }
         }
      }

      for(int d1 = 0;d1 < 4;d1 ++){
         for(int d2 = 0;d2 < 8;d2 ++){
            dax[d2] = arx[d2]+333;day[d2] = ary[d2]+92+d1*60;
         }
         og.setColor(Color.black);
         og.fillPolygon(dax,day,8);
         for(int d2 = 0;d2 < 8;d2 ++){
            dax[d2] = arx[d2]+330;day[d2] = ary[d2]+90+d1*60;
         }
         og.setColor(Color.red);
         og.fillPolygon(dax,day,8);
      }
      for(int d1 = 0;d1 < 24;d1 ++){
         if(d1%2 == 0){
            if(br == 1){
               og.setColor(Color.darkGray);
            }else{
               og.setColor(Color.white);
            }
         }else{
            if(br == 1){
               og.setColor(Color.white);
            }else{
               og.setColor(Color.darkGray);
            }
         }
         og.drawLine(50,10*d1+100,60,10*d1+90);
         og.drawLine(60,10*d1+90,70,10*d1+100);
         og.drawLine(10*d1+90,50,10*d1+100,60);
         og.drawLine(10*d1+100,60,10*d1+90,70);
         if(d1 < 6){
            og.drawLine((int)(-40*Math.cos(0.262*d1)+90),(int)(-40*Math.sin(0.262*d1)+90),
                        (int)(-30*Math.cos(0.262*d1)+10*Math.sin(0.262*d1)+90),(int)(-30*Math.sin(0.262*d1)-10*Math.cos(0.262*d1)+90));
            og.drawLine((int)(-30*Math.cos(0.262*d1)+10*Math.sin(0.262*d1)+90),(int)(-30*Math.sin(0.262*d1)-10*Math.cos(0.262*d1)+90),
                        (int)(-20*Math.cos(0.262*d1)+90),(int)(-20*Math.sin(0.262*d1)+90));
         }
      }

      if(sw != 0){
         if(mt1 == 1){
            for(int d1 = 0;d1 < 4;d1 ++){
               d_cube(td[sw][d1+1],mx1+d1*60,my1);
            }
         }else{
            d_cube(mn,mx1,my1);
            if(mt1 == 2){
               if(sw != 1){
                  for(int d2 = sw-1;d2 > 0;d2 --){
                     d_cube(td[d2][4],mx2,my2-60*(sw-d2-1));
                  }
               }
            }
         }
      }

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

   }

   public void d_cube(int no,int dx,int dy){
      if(no != 0){
      og.setColor(Color.orange);
      og.fillRoundRect(dx,dy,60,60,5,5);
         switch (no){
            case 1 : og.setColor(Color.black);og.fillArc(dx-60,dy,120,120,0,90);
                     og.setColor(Color.orange);og.fillArc(dx-50,dy+10,100,100,0,90);break;
            case 2 : og.setColor(Color.black);og.fillArc(dx,dy,120,120,90,90);
                     og.setColor(Color.orange);og.fillArc(dx+10,dy+10,100,100,90,90);break;
            case 3 : og.setColor(Color.black);og.fillArc(dx,dy-60,120,120,180,90);
                     og.setColor(Color.orange);og.fillArc(dx+10,dy-50,100,100,180,90);break;
            case 4 : og.setColor(Color.black);og.fillArc(dx-60,dy-60,120,120,270,90);
                     og.setColor(Color.orange);og.fillArc(dx-50,dy-50,100,100,270,90);break;
         }
         og.setColor(Color.lightGray);
         og.drawRoundRect(dx,dy,60,60,5,5);
      }
   }

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

   public void stop(){
      th = null;
   }

   public void run(){
      while(th != null){
         try{
            br = br*(-1);
            switch (mt1){
               case 1 : mx1 = mx1 - 5;
                        if(mx1 < 30){
                           mx1 = 30;
                           mn = td[sw][1];
                           td[sw][1] = td[sw][2];td[sw][2] = td[sw][3];td[sw][3] = td[sw][4];td[sw][4] = 0;
                           mt1 = 2;
                        }
                        break;
               case 2 : my1 = my1 - 5;
                        my2 = my2 + 5;
                        if(my1 < 30){
                           mx1 = 30;my1 = 30;mt1 = 3;
                           for(int d2 = sw;d2 > 1;d2 --){
                              td[d2][4] = td[d2-1][4];
                           }
                           td[1][4] = 0;
                        }
                        if(my2 > sw*60+30)my2 = sw*60+30;
                        break;
               case 3 : mx1 = mx1 + 5;
                        if(mx1 > 270){
                           mx1 = 270;my1 = 30;mt1 = 4;
                        }
                        break;
               case 4 : my1 = my1 + 5;
                        if(my1 > 90){
                           td[1][4] = mn;
                           sw = 0;
                           cs = 0;
                        }
                        break;
            }

            Thread.sleep(10);
         }
         catch (InterruptedException e){
         }
         repaint();
      }
   }

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