//

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

public class block extends Applet
implements Runnable,KeyListener
{
   private int s2[][];
   private int s1[][];
   private int s3[][];
   private int board[][];
   private int x0,t;
   private int y0,score,level;
   private boolean begin,end,stop; 
   Button b1;
   Font f1,f2;   
   Thread a;
   Color color[];
   AudioClip a1,a2;
   public void init()
    {
     a1=getAudioClip(getDocumentBase(),"1.au");
     a2=getAudioClip(getDocumentBase(),"2.au");
     f1=new Font("Helvetica",1,16);
     f2=new Font("Helvetica",1,11);
     color=new Color[10];
     board=new int[14][20];
     color[0]=new Color(0,0,0);
     color[2]=new Color(180,0,0);
     color[1]=new Color(160,80,240);
     color[3]=new Color(80,200,160);
     color[4]=new Color(240,80,160);
     color[5]=new Color(0,180,0);
     color[6]=new Color(180,0,180);
     color[7]=new Color(180,180,0);
     color[8]=new Color(0,140,140);
     color[9]=new Color(140,140,140);
     setLayout(null);
     b1=new Button("Restart");
     add(b1);
     b1.setFont(f1);
     b1.setBackground(Color.black); 
     b1.setForeground(Color.red);    
     b1.setBounds(260,250,120,40);
     a=null;
     begin();
     addKeyListener(this);
   }  
   
   public boolean action(Event event,Object obj)
   {
      if(event.target==b1)
      {
         begin();
      }
      return true;
   }
   
   private void begin()
   {
      begin=false;
      end=false;
      stop=false;      
      score=0;
      level=1;
      t=500;
      s2 = new int[4][4];
      s1= new int[4][4];
      s3=new int[6][6];
      x0=4;y0=0;  
      RandBlock();
      for(int i=0;i<4;i++)for(int j=0;j<4;j++)
      s2[i][j]=s1[i][j];   
      RandBlock();
      if(a==null){a=new Thread(this);
      a.start();} 
      repaint();
      requestFocus(); 
   }
   
   public void keyTyped(KeyEvent keyevent) {
    }
   public void keyReleased(KeyEvent keyevent) {
    }
   public void run()
   {
     while(!end)
     { 
        if(!stop)Down();
        try{Thread.sleep(t);}
        catch(InterruptedException _EX){}
     }
   }
   public void block()
   {}
   public void update(Graphics g)
   {paint(g);
   }
	public void paint(Graphics g)
	{int i,j;
	  	  if(!begin)
     {for( i=0;i<6;i++)
      for( j=0;j<6;j++)
      if(i==0||j==0||i==5||j==5)s3[i][j]=8;
          for( i=0;i<17;i++)
           { 
           board[0][i]=9;board[11][i]=9;
           for ( j=1;j<11;j++)
           board[j][i]=0;
           }
          for( i=0;i<12;i++)
             board[i][17]=9;
     board[1][0]=9;
     board[2][0]=9;
     board[3][0]=9;
     board[8][0]=9;
     board[9][0]=9;
     board[10][0]=9;
     setBackground(Color.black);
     begin=true;
     }
	  for( i=0;i<12;i++)
      for( j=0;j<18;j++)
      {
         g.setColor(color[board[i][j]]);
         g.fill3DRect(i*20,j*20,20,20,true);
      }
      
      if(!stop)
      for( i=0;i<4;i++)
      for( j=0;j<4;j++)
      if(s2[i][j]!=0)
      {
         g.setColor(color[s2[i][j]]);
         g.fill3DRect((x0+i)*20,(y0+j)*20,20,20,true);
      }
      
      
      for( i=0;i<4;i++)
      for( j=0;j<4;j++)
      s3[i+1][j+1]=s1[i][j];
        
        for(i=0;i<6;i++)
        for(j=0;j<6;j++)
        {g.setColor(color[s3[i][j]]);
         g.fill3DRect(260+i*20,40+j*20,20,20,true);
        }   
      g.setColor(Color.black);
      g.fill3DRect(260,170,120,120,true);  
      g.setColor(Color.cyan);
      g.setFont(f1);
      g.drawString("SCORE: "+String.valueOf(score),260,230);
      g.drawString("LEVEL: "+String.valueOf(level),260,200);
      g.setFont(f2);
      g.drawString("Xiangdong Wen",260,325);
      g.drawString("wen@math.temple.edu",260,340);   
	}
	private void RandBlock()
   {
	   int s;int i,j;
	   s=(int)(Math.random()*7D)+1;
	   if(s==8)s=1;
	   
	   for(i=0;i<4;i++)for(j=0;j<4;j++)s1[i][j]=0;
	   if (s==1) 
	   {           
		           s1[1][0]=1;
	    s1[0][1]=1;s1[1][1]=1;s1[2][1]=1;
	   }
	   else if(s==2) 
	   {for(i=0;i<4;i++)s1[i][1]=2;}
     
	   else if(s==3)
	   {
	     	s1[0][0]=3;s1[1][0]=3;
	                 s1[1][1]=3;s1[2][1]=3;
	   }
	   else if(s==4) 
	   {           
	    	           s1[1][0]=4;s1[2][0]=4;
		   s1[0][1]=4;s1[1][1]=4;
	   }
	   else if(s==5) 
	   {
	    	s1[0][0]=5;
	      s1[0][1]=5;s1[1][1]=5;s1[2][1]=5;
	   }
	   else if(s==6)
	   {   
	   	                         s1[2][0]=6;
	    	s1[0][1]=6;s1[1][1]=6;s1[2][1]=6;
	   }
	   else if(s==7) 
   	{
	    	s1[0][0]=7;s1[1][0]=7;
		   s1[0][1]=7;s1[1][1]=7;
	   }
	}
	
	void Left()
   {   
	   int i,j,sum;
      sum=0;
	   for(i=0;i<4;i++)for(j=0;j<4;j++)
		   sum=sum+s2[i][j]*board[x0+i-1][y0+j];
	   if (sum==0){x0-=1;repaint();}
   }

   void Right()
   {
	   int i,j,sum;
      sum=0;
	   for(i=0;i<4;i++)for(j=0;j<4;j++)
		   sum=sum+s2[i][j]*board[x0+i+1][y0+j];
	   if (sum==0){x0+=1;repaint();}
   }

   void Down()
   {
	   int i,j,sum;
      sum=0;
	   for(i=0;i<4;i++)for(j=0;j<4;j++)
		   if(s2[i][j]*board[x0+i][y0+j+1]!=0)sum=1;;	
	   if (sum==0)y0+=1;
      else 
	   {
	      if(y0==0)
	      {
	        stop=true;return;
	      }
	      
	      else
	      {	
	         for(i=0;i<4;i++)for(j=0;j<4;j++)
		         board[x0+i][y0+j]+=s2[i][j];  
            score+=10;a1.play();
            for(i=0;i<4;i++)for(j=0;j<4;j++)
                  s2[i][j]=s1[i][j];     
            RandBlock();
		      int s=0;
		      for (j=16;j>0;j--)
		      {  
		         int t=1;
			      for(i=1;i<11;i++)t*=board[i][j];
		         if (t!=0)
	    	      {  
		            stop=true;
		          	s+=1;
		            for(int m=j;m>1;m--)
		               for(int n=1;n<11;n++)board[n][m]=board[n][m-1];
		            repaint();
		            j+=1;
		            a2.play();
		            try{Thread.sleep(300);}
                  catch(InterruptedException _EX){}
                  stop=false;		         
               }
		      }
		      score+=(s*s)*100;
	         x0=4;y0=0;
	         level=(int)(score/1000)+1;
	         t=500-(level-1)*25;
	 	   } 
	   }
	   repaint();
   }
   public void keyPressed(KeyEvent keyevent) 
   { 
      int i = keyevent.getKeyCode();    
      if(i == keyevent.VK_SPACE)
         begin();      
      if(stop||end)return;
      if(i == 37)
         Left();
      else if(i ==38)
         Rotate();
      else if(i == 39)
         Right();
      else if(i == 40)
         Down();
   }
   void Rotate()
   {
	   int i,j,sum,s[][];
      s=new int[4][4];
      sum=0; 
	   for(i=0;i<3;i++)for(j=0;j<3;j++)
		   sum=sum+s2[i][j]*board[x0+2-j][y0+i];
	   sum+=s2[1][3]*board[x0+3][y0+1];
	   sum+=s2[3][1]*board[x0+1][y0+3];
	   if (sum==0) 
	   { 
	      for(i=0;i<3;i++)for(j=0;j<3;j++)s[i][j]=s2[j][2-i];
	      for(i=0;i<4;i++){s[3][i]=0;s[i][3]=0;}
	      s[1][3]=s2[3][1];
	      s[3][1]=s2[1][3];
	      s2=s;
	   }
	   repaint();
   }
   public void stop()
   {a.stop();
   }
}