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

public class r_cube2 extends Applet implements Runnable{

   Thread th = null;
   double r2 = 1.414214 , pi = 3.141592;
   double ang;
   Image os;
   Graphics og;
   int td[][] = new int[8][8];
   int cn[] = {1,0,0,0,0,0};
   int cx,cy,cd,gd;
   int px,py,sp;
   int fg,cf;
   Color c1,c2;
   Button rep;

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

      setLayout(new BorderLayout());
      Panel pan = new Panel();
      pan.setLayout(new FlowLayout());
      pan.add(rep = new Button("  replay  "));
      add("South",pan);
      rep.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            r_set();
            repaint();
         }
      });

      td[0][0] = 1;
      c1 = new Color(255,0,0);
      c2 = new Color(255,255,100);

      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               if(fg == 0){
                  px = (e.getX() - 30) / 30;
                  py = (e.getY() - 30) / 30;
                  if((cx-cy < px-py) && (cx+cy < px+py)){
                     if(cx != 7){
                        if(td[cy][cx+1] == 0){
                           if(cn[0] == 1)gd = 2;
                           if(cn[1] == 1)gd = 1;
                           if(cn[2] == 1)gd = 5;
                           if(cn[3] == 1)gd = 0;
                           if(cn[4] == 1)gd = 4;
                           if(cn[5] == 1)gd = 3;
                           cd = 0;
                           fg = 1;
                           th.resume();
                        }
                     }
                  }else if((cx-cy < px-py) && (cx+cy > px+py)){
                     if(cy != 0){
                        if(td[cy-1][cx] == 0){
                           if(cn[0] == 1)gd = 4;
                           if(cn[1] == 1)gd = 0;
                           if(cn[2] == 1)gd = 2;
                           if(cn[3] == 1)gd = 3;
                           if(cn[4] == 1)gd = 5;
                           if(cn[5] == 1)gd = 1;
                           cd = 1;
                           fg = 1;
                           th.resume();
                        }
                     }
                  }else if((cx-cy > px-py) && (cx+cy > px+py)){
                     if(cx != 0){
                        if(td[cy][cx-1] == 0){
                           if(cn[0] == 1)gd = 3;
                           if(cn[1] == 1)gd = 1;
                           if(cn[2] == 1)gd = 0;
                           if(cn[3] == 1)gd = 5;
                           if(cn[4] == 1)gd = 4;
                           if(cn[5] == 1)gd = 2;
                           cd = 2;
                           fg = 1;
                           th.resume();
                        }
                     }
                  }else if((cx-cy > px-py) && (cx+cy < px+py)){
                     if(cy != 7){
                        if(td[cy+1][cx] == 0){
                           if(cn[0] == 1)gd = 1;
                           if(cn[1] == 1)gd = 5;
                           if(cn[2] == 1)gd = 2;
                           if(cn[3] == 1)gd = 3;
                           if(cn[4] == 1)gd = 0;
                           if(cn[5] == 1)gd = 4;
                           cd = 3;
                           fg = 1;
                           th.resume();
                        }
                     }
                  }
               }
            }
         }
      );

   }

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

      for(int k1 = 0;k1 < 8;k1 ++){
         for(int k2 = 0;k2 < 8;k2 ++){
            if(td[k2][k1] == 0){
               og.setColor(new Color(102,255,102));
            }else{
               og.setColor(c2);
            }
            og.fill3DRect(30*k1+30,30*k2+30,30,30,true);
         }
      }

      if((cx == 7)&&(cy == 0)){
        cf = 1;
        for(int i1 = 0;i1 < 8;i1 ++){
           for(int i2 = 0;i2 < 8;i2 ++){
              cf = cf * td[i2][i1] ;
           }
        }
        if(cf == 1){
           cd = 5;
           fg = 1;
         }
      }else{
         if((cn[0] == 1)&&((cx != 0)||(cy != 0))){
            cd = 4;
            fg = 1;
         }
      }
      switch(cd){
         case 0 : if(cn[3] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+60-(int)(30*Math.cos(ang)),cy*30+30,(int)(30*Math.sin(ang)),30);
                  if(cn[0] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+60-(int)(30*r2*Math.cos(ang+pi/4)),cy*30+30,(int)(30*Math.cos(ang)),30);
                  og.setColor(Color.black);
                  og.drawRect(30*cx+60-(int)(30*Math.cos(ang)),cy*30+30,(int)(30*Math.sin(ang)),30);
                  og.drawRect(30*cx+60-(int)(30*r2*Math.cos(ang+pi/4)),cy*30+30,(int)(30*Math.cos(ang)),30);
                  break ;
         case 1 : if(cn[1] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+30,cy*30+30+(int)(30*r2*Math.cos(ang+pi/4)),30,(int)(30*Math.sin(ang)));
                  if(cn[0] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+30,cy*30+30-(int)(30*Math.sin(ang)),30,(int)(30*Math.cos(ang)));
                  og.setColor(Color.black);
                  og.drawRect(30*cx+30,cy*30+30+(int)(30*r2*Math.cos(ang+pi/4)),30,(int)(30*Math.sin(ang)));
                  og.drawRect(30*cx+30,cy*30+30-(int)(30*Math.sin(ang)),30,(int)(30*Math.cos(ang)));
                  break ;
         case 2 : if(cn[2] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+30+(int)(30*r2*Math.cos(ang+pi/4)),cy*30+30,(int)(30*Math.sin(ang)),30);
                  if(cn[0] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+30-(int)(30*Math.sin(ang)),cy*30+30,(int)(30*Math.cos(ang)),30);
                  og.setColor(Color.black);
                  og.drawRect(30*cx+30+(int)(30*r2*Math.cos(ang+pi/4)),cy*30+30,(int)(30*Math.sin(ang)),30);
                  og.drawRect(30*cx+30-(int)(30*Math.sin(ang)),cy*30+30,(int)(30*Math.cos(ang)),30);
                  break ;
         case 3 : if(cn[4] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+30,cy*30+60-(int)(30*Math.cos(ang)),30,(int)(30*Math.sin(ang)));
                  if(cn[0] == 1){
                     og.setColor(c1);
                  }else{
                     og.setColor(c2);
                  }
                  og.fillRect(30*cx+30,cy*30+60-(int)(30*r2*Math.cos(ang+pi/4)),30,(int)(30*Math.cos(ang)));
                  og.setColor(Color.black);
                  og.drawRect(30*cx+30,cy*30+60-(int)(30*Math.cos(ang)),30,(int)(30*Math.sin(ang)));
                  og.drawRect(30*cx+30,cy*30+60-(int)(30*r2*Math.cos(ang+pi/4)),30,(int)(30*Math.cos(ang)));
                  break ;
         case 4 : og.setColor(Color.red);
                  og.fillRect(30*cx+30,cy*30+30,30,30);
                  og.fillRect(30*cx+30-(int)(30*Math.sin(ang)),cy*30+30,(int)(30*Math.sin(ang)),30);
                  og.fillRect(30*cx+60,cy*30+30,(int)(30*Math.sin(ang)),30);
                  og.fillRect(30*cx+30,cy*30+30-(int)(30*Math.sin(ang)),30,(int)(30*Math.sin(ang)));
                  og.fillRect(30*cx+30,cy*30+60,30,(int)(30*Math.sin(ang)));
                  og.setColor(Color.black);
                  og.drawRect(30*cx+30,cy*30+30,30,30);
                  og.drawRect(30*cx+30-(int)(30*Math.sin(ang)),cy*30+30,(int)(30*Math.sin(ang)),30);
                  og.drawRect(30*cx+60,cy*30+30,(int)(30*Math.sin(ang)),30);
                  og.drawRect(30*cx+30,cy*30+30-(int)(30*Math.sin(ang)),30,(int)(30*Math.sin(ang)));
                  og.drawRect(30*cx+30,cy*30+60,30,(int)(30*Math.sin(ang)));
                  break ;
         case 5 : og.setColor(new Color(255-(int)(100*ang),0,0));
                  og.setFont(new Font("",Font.PLAIN,60));
                  og.drawString("clear !!",70,170);
                  break ;
         }

         og.setColor(Color.red);
         switch(gd){
            case 1 : og.fillRect(30,275,240,5);break;
            case 2 : og.fillRect(275,30,5,240);break;
            case 3 : og.fillRect(20,30,5,240);break;
            case 4 : og.fillRect(30,20,240,5);break;
         }
      g.drawImage(os,0,0,this );
   }

   public void r_set(){
      for(int i1 = 0;i1 < 8;i1 ++){
         for(int i2 = 0;i2 < 8;i2 ++){
            td[i2][i1] = 0;
         }
      }
      td[0][0] = 1;
      cx = 0 ; cy = 0;
      for(int i1 = 0;i1 < 6;i1 ++)cn[i1] = 0;
      cn[0] = 1;
      cd = 0;
      ang = 0;
      fg = 0;
      gd = 0;
      th.suspend();
   }

   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{
            ang = ang + pi / 200;
            if(ang > pi / 2)ang = pi / 2;
            if(ang == pi / 2){
               switch(cd){
                  case 0 : sp = cn[0] ; cn[0] = cn[3] ; cn[3] = cn[5] ; cn[5] = cn[2] ; cn[2] = sp ;
                           cx ++ ;
                           break ;
                  case 1 : sp = cn[0] ; cn[0] = cn[1] ; cn[1] = cn[5] ; cn[5] = cn[4] ; cn[4] = sp ;
                           cy -- ;
                           break ;
                  case 2 : sp = cn[0] ; cn[0] = cn[2] ; cn[2] = cn[5] ; cn[5] = cn[3] ; cn[3] = sp ;
                           cx -- ;
                           break ;
                  case 3 : sp = cn[0] ; cn[0] = cn[4] ; cn[4] = cn[5] ; cn[5] = cn[1] ; cn[1] = sp ;
                           cy ++ ;
                           break ;
               }
               td[cy][cx] = 1;
               ang = 0;
               fg = 0;
               if(cn[0] != 1)th.suspend();
            }
            Thread.sleep(5);
         }
         catch (InterruptedException e){
         }
         repaint();
      }
   }
   public void update( Graphics g ){
      paint( g ) ;
   }
}