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

public class billiards extends Applet implements Runnable{

   Thread th = null;
   Image os;
   Graphics og;
   int bd[][][] = {{{11,12,13,14,15},{7,8,9,10,-1},{4,5,6,-1,-1},{2,3,-1,-1,-1},{1,-1,-1,-1,-1}},
                   {{0,0,0,0,0},{0,0,0,0,-1},{0,0,0,-1,-1},{0,0,-1,-1,-1},{0,-1,-1,-1,-1}}};
   int td[][][] = new int[2][5][5];
   double r3 = 1.7321;
   int bn = 2,hn,pf,tf,af,sp;
   int px,py,mx,my;

   public void init(){
      os = createImage(690,320);
      og = os.getGraphics();
      d_set();

      addMouseListener(
         new MouseAdapter(){
            public void mousePressed(MouseEvent e){
               if(e.getX() < 330){
                  tf = 0;
               }else if(e.getX() > 360){
                  tf = 1;
               }
               if(tf == 0){
                  py = (e.getY()-30) / (int)(30*r3);
                  px = (e.getX()-30*py-30) / 60;
               }else{
                  py = (e.getY()-30) / (int)(30*r3);
                  px = (e.getX()-30*py-360) / 60;
               }
               if((px >= 0)&&(px < 5)&&(py >= 0)&&(py < 5)){
                  if(pf == 0){
                     if((td[tf][py][px] != -1)&&(td[tf][py][px] != 0)){
                        hn = td[tf][py][px];
                        td[tf][py][px] = 0;
                        pf = 1;
                     }
                  }else{
                     if(td[tf][py][px] == 0){
                        td[tf][py][px] = hn;
                        pf = 0;
                     }else if(td[tf][py][px] != -1){
                        sp = td[tf][py][px];
                        td[tf][py][px] = hn;
                        hn = sp;
                     }
                  }
               }
               if((pf == 0)&&(Math.abs(e.getX()-345) < 15)&&(Math.abs(e.getY()-200) < 150)){
                  bn ++;
                  if(bn > 5)bn = 2;
                  d_set();
               }

               repaint();
            }
         } 
      );

      addMouseMotionListener(
         new MouseMotionAdapter(){
            public void mouseMoved(MouseEvent e){
               mx = e.getX()-30;
               my = e.getY()-30;
               repaint();
            }
         }
      );

   }

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

      og.setColor(Color.gray);
      for(int dx = 0;dx < 5;dx ++){
         for(int dy = 5-bn;dy < 5;dy ++){
            if(td[0][dy][dx] != -1){
               og.drawOval(60*dx+30*dy+31,(int)(30*r3*dy)+30,58,58);
            }
            if(td[1][dy][dx] != -1){
               og.drawOval(60*dx+30*dy+361,(int)(30*r3*dy)+30,58,58);
            }
         }
      }
      for(int dx = 0;dx < 5;dx ++){
         for(int dy = 5-bn;dy < 5;dy ++){
            if(td[0][dy][dx] != -1){
               if(td[0][dy][dx] != 0)ball(td[0][dy][dx],60*dx+30*dy+30,(int)(30*r3*dy)+30);
            }
            if(td[1][dy][dx] != -1){
               if(td[1][dy][dx] != 0)ball(td[1][dy][dx],60*dx+30*dy+360,(int)(30*r3*dy)+30);
            }
         }
      }
      og.setColor(Color.blue);
      for(int dl = 0;dl < bn;dl ++)og.fill3DRect(330,220-25*dl,30,20,true);

      og.setColor(Color.black);
      og.setFont(new Font("",Font.BOLD,14));
      og.drawString("retray",321,262);
      og.drawString("or",335,275);
      og.drawString("level change",300,288);

      af = 1;
      for(int dx = 0;dx < 5;dx ++){
         for(int dy = 5-bn;dy < 5;dy ++){
            og.setColor(Color.red);
            if(dy == 5-bn){
               if(td[1][dy][dx] == 0)af = 0;
            }else{
               if((td[1][dy][dx] != 0)&&(td[1][dy][dx] != -1)){
                  if(td[1][dy][dx] != Math.abs(td[1][dy-1][dx]-td[1][dy-1][dx+1])){
                     og.fill3DRect(60*dx+30*dy+380,(int)(30*r3*dy)+57,20,5,true);
                     af = 0;
                  }
               }
               if(td[1][dy][dx] == 0)af = 0;
            }
         }
      }
      og.setFont(new Font("",Font.BOLD,36));
      if(af == 1)og.drawString("clear!!",285,210);
      if(pf == 1)ball(hn,mx,my);

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

   }

   public void d_set(){
      for(int dx = 0;dx < 5;dx ++){
         for(int dy = 0;dy < 5;dy ++){
            for(int dz = 0;dz < 2;dz ++){
               if(dy > 4-bn){
                  td[dz][dy][dx] = bd[dz][dy][dx];
               }else{
                  td[dz][dy][dx] = -1;
               }
            }
         }
      }
   }

   public void ball(int in,int bx,int by){
      switch (in){
         case 1 : og.setColor(new Color(255,255,0)) ; break ;
         case 2 : og.setColor(new Color(0,0,255)) ; break ;
         case 3 : og.setColor(new Color(255,0,0)) ; break ;
         case 4 : og.setColor(new Color(0,0,128)) ; break ;
         case 5 : og.setColor(new Color(255,69,0)) ; break ;
         case 6 : og.setColor(new Color(0,128,0)) ; break ;
         case 7 : og.setColor(new Color(176,0,0)) ; break ;
         case 8 : og.setColor(new Color(0,0,0)) ; break ;
         case 9 : og.setColor(new Color(255,255,0)) ; break ;
         case 10 : og.setColor(new Color(0,0,255)) ; break ;
         case 11 : og.setColor(new Color(255,0,0)) ; break ;
         case 12 : og.setColor(new Color(0,0,128)) ; break ;
         case 13 : og.setColor(new Color(255,69,0)) ; break ;
         case 14 : og.setColor(new Color(0,128,0)) ; break ;
         case 15 : og.setColor(new Color(176,0,0)) ; break ;
      }
      og.fillOval(bx,by,60,60);
      if(in > 8){
         og.setColor(Color.white);
         og.fillOval(bx+5,by,50,45);
      }
      og.setFont(new Font("",Font.BOLD,18));
      og.setColor(Color.white) ;
      og.fillOval(bx+15,by+5,30,30);
      og.setColor(Color.black) ;
      og.drawOval(bx+15,by+5,30,30);
      og.drawString(""+in,bx+24-in/10*6,by+26);

   }

   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(100);
         }
         catch (InterruptedException e){
         }
      }
   }

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