/*
 * Created on 2005/5/30
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author clchen
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class BlockJump extends Applet implements MouseListener,Runnable
  {
  Image Img[] = new Image[16]; //array of 16 images consisting BJ protrait or MI protrait 
  MediaTracker track; //
  Thread Mover; // control thread
  Graphics G;
  Image ImgBuffer; // interesting piece that allow smooth graphic update
  Font fnt1;
  int dx,dy,x,y,Label,sa,workFlag;
  int ground[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,0};

  public void init()
    {
	setLayout(new FlowLayout(FlowLayout.RIGHT, 10,10));
	add(new Button("BJ"));
	add(new Button("MI"));
	layout();
    fnt1 = new Font("TimesRoman", Font.PLAIN, 20);
    track = new MediaTracker(this);
    for(int i=0;i<=15;i++) Img[i] = getImage(getCodeBase(),"Block"+i+".GIF"); // fill the array with images Block1-16.GIF
    for(int i=0;i<=15;i++) track.addImage(Img[i],i); 

    addMouseListener(this);
    resize(400,300);
    }
	
  public boolean action(Event evt, Object btn)
	{
	if (evt.target instanceof Button) {
		String btn1=(String)btn;
		if (btn1.equals("BJ")); {
		for(int i=0;i<=15;i++) Img[i] = getImage(getCodeBase(),"Block"+i+".GIF"); // fill the array with images Block1-16.GIF
		for(int i=0;i<=15;i++) track.addImage(Img[i],i); 
		
		
		Label=5;
		repaint();
		
		
		}
		if (btn1.equals("MI")) {
		for(int i=0;i<=15;i++) Img[i] = getImage(getCodeBase(),"mi"+i+".GIF"); // fill the array with images Block1-16.GIF
		for(int i=0;i<=15;i++) track.addImage(Img[i],i);
		
		
		Label=5;
		repaint();
		
		}
		}
	return true;
	}
	
  public void start()
    {
    Mover = new Thread(this);
    Mover.start();
    Label = 0;
           
    }

  public void stop()
    {
    }

  public void run()
    {
    ImgBuffer = createImage(400,300);
    G = ImgBuffer.getGraphics();
    try
      {
      track.waitForAll(0);
      }
    catch(InterruptedException e)
      {
      return;
      }
    repaint();
    }

  public void paint(Graphics g)
    {
    switch (Label) //switch selected image with the blank block 
      {
      case 0:
        G.setColor(new Color(255,255,255));
        G.fillRect(0,0,400,300);
        G.setColor(new Color(0,0,0));
        G.setFont(fnt1);

        Rect1(G,304,52,363,74,2);
        Rect1(G,304,82,363,104,2);

        G.setColor(new Color(153,204,102));
        G.drawString("Start",310,70);
        G.setColor(new Color(153,204,102));
        G.drawString("Reset",310,100);
        Label = 1;
        sa = 0;
        workFlag = 1;
        Mover.stop();
        Mover = null;

      break;

      case 1:
      if (y > 0)
        {
        if (ground[x*4+y-1] == 0)
          {
          Rect1(G,x*70+5,y*70+5,x*70+74,y*70+74,2);
          G.drawImage(Img[ground[x*4+y]-1],x*70+5,(y-1)*70+5,this);
          Rect2(G,x*70+5,(y-1)*70+5,x*70+74,(y-1)*70+74,2);
          ground[x*4+y-1] = ground[x*4+y];
          ground[x*4+y] = 0;
          }
        }

      if (y < 3)
        {
        if (ground[x*4+y+1] == 0)
          {
          Rect1(G,x*70+5,y*70+5,x*70+74,y*70+74,2);
          G.drawImage(Img[ground[x*4+y]-1],x*70+5,(y+1)*70+5,this);
          Rect2(G,x*70+5,(y+1)*70+5,x*70+74,(y+1)*70+74,2);
          ground[x*4+y+1] = ground[x*4+y];
          ground[x*4+y] = 0;
          }
        }

      if (x < 3)
        {
        if (ground[(x+1)*4+y] == 0)
          {
          Rect1(G,x*70+5,y*70+5,x*70+74,y*70+74,2);
          G.drawImage(Img[ground[x*4+y]-1],(x+1)*70+5,y*70+5,this);
          Rect2(G,(x+1)*70+5,y*70+5,(x+1)*70+74,y*70+74,2);
          ground[(x+1)*4+y] = ground[x*4+y];
          ground[x*4+y] = 0;
          }
        }

      if (x > 0)
        {
        if (ground[(x-1)*4+y] == 0)
          {
          Rect1(G,x*70+5,y*70+5,x*70+74,y*70+74,2);
          G.drawImage(Img[ground[x*4+y]-1],(x-1)*70+5,y*70+5,this);
          Rect2(G,(x-1)*70+5,y*70+5,(x-1)*70+74,y*70+74,2);
          ground[(x-1)*4+y] = ground[x*4+y];
          ground[x*4+y] = 0;
          }
        }

      workFlag = 1;
      break;

      case 2:
      G.drawImage(Img[15],215,215,this);
      Rect2(G,215,215,284,284,2);

      for (int i=0;i<=3;i++) for (int j=0;j<=3;j++) ground[i*4+j] = j*4+i+1;
      Label = 5;
      workFlag = 1;
      repaint();
      break;

      case 3:
      G.setColor(new Color(153,204,102));
      G.drawString("Start",310,70);
      G.setColor(new Color(153,204,102));
      G.drawString("Reset",310,100);
      ground[15] = 0;

      int ax = 3,ay =3;
      for(int i=0;i<=300;i++)
      {
      switch((int)(Math.random()*1000)%4+1)
        {
        case 1:
        if (ay > 0) ay = ay - 1; else break;
        if (ay < 3)
          {
          if (ground[ax*4+ay+1] == 0)
            {
            Rect1(G,ax*70+5,ay*70+5,ax*70+74,ay*70+74,2);
            G.drawImage(Img[ground[ax*4+ay]-1],ax*70+5,(ay+1)*70+5,this);
            Rect2(G,ax*70+5,(ay+1)*70+5,ax*70+74,(ay+1)*70+74,2);
            ground[ax*4+ay+1] = ground[ax*4+ay];
            ground[ax*4+ay] = 0;
            }
          }
        break;
        case 2:
        if (ay < 3) ay = ay + 1; else break;

        if (ay > 0)
          {
          if (ground[ax*4+ay-1] == 0)
            {
            Rect1(G,ax*70+5,ay*70+5,ax*70+74,ay*70+74,2);
            G.drawImage(Img[ground[ax*4+ay]-1],ax*70+5,(ay-1)*70+5,this);
            Rect2(G,ax*70+5,(ay-1)*70+5,ax*70+74,(ay-1)*70+74,2);
            ground[ax*4+ay-1] = ground[ax*4+ay];
            ground[ax*4+ay] = 0;
            }
        }
        break;
        case 3:
        if (ax > 0) ax = ax - 1; else break;

        if (ax < 3)
          {
          if (ground[(ax+1)*4+ay] == 0)
            {
            Rect1(G,ax*70+5,ay*70+5,ax*70+74,ay*70+74,2);
            G.drawImage(Img[ground[ax*4+ay]-1],(ax+1)*70+5,ay*70+5,this);
            Rect2(G,(ax+1)*70+5,ay*70+5,(ax+1)*70+74,ay*70+74,2);
            ground[(ax+1)*4+ay] = ground[ax*4+ay];
            ground[ax*4+ay] = 0;
            }
        }
        break;
        case 4:
        if (ax < 3) ax = ax + 1; else break;

        if (ax > 0)
          {
          if (ground[(ax-1)*4+ay] == 0)
            {
            Rect1(G,ax*70+5,ay*70+5,ax*70+74,ay*70+74,2);
            G.drawImage(Img[ground[ax*4+ay]-1],(ax-1)*70+5,ay*70+5,this);
            Rect2(G,(ax-1)*70+5,ay*70+5,(ax-1)*70+74,ay*70+74,2);
            ground[(ax-1)*4+ay] = ground[ax*4+ay];
            ground[ax*4+ay] = 0;
            }
          }
        break;
        }
      }
      workFlag = 1;
      sa = 1;
      break;

      case 4:
      workFlag = 1;
      break;

      case 5:
      for (int i=0;i<=3;i++) for (int j=0;j<=3;j++) ground[i*4+j] = j*4+i+1;

      for(int j=0;j<=3;j++)
        for(int i=0;i<=3;i++)
          {
          G.drawImage(Img[j+i*4],j*70+5,i*70+5,this);
          Rect2(G,j*70+5,i*70+5,j*70+74,i*70+74,2);
          }

      G.setColor(new Color(153,204,102));
      G.drawString("Start",310,70);
      G.setColor(new Color(153,204,102));
      G.drawString("Reset",310,100);
      Label = 1;
      sa = 0;
      workFlag = 1;
      repaint();
      break;

      case 6:
      workFlag = 1;
      break;

      case 7:
      workFlag = 1;
      break;

      case 8:
      workFlag = 1;
      break;

      }
   if (workFlag == 1) g.drawImage(ImgBuffer,0,0,this);
   workFlag = 0;
   }

  public void update(Graphics g)
    {
    paint(g);
    }

  public void mousePressed(MouseEvent e)
    {
    dx = e.getX();
    dy = e.getY();
    if (dx>6 & dy>6 & dx<283 & dy <283)
      {
      x = (dx - 6) / 70;
      y = (dy - 6) / 70;

      if (dx > x*70+6 & dx < (x+1)*70+3 & dy > y*70+6 & dy < (y+1)*70+3 & sa > 0)
        {
        Label = 1;
        repaint();
        }
      }

    if (dx>306 & dy>54 & dx<362 & dy <72 & sa == 0)
      {
      Label = 3;
      repaint();
      }

    if (dx>306 & dy>84 & dx<362 & dy <102 & sa == 1)
      {
      Label = 5;
      repaint();
      }

    if (dx>306 & dy>114 & dx<362 & dy <132)
      {
      Label = 7;
      repaint();
      }

    }

  public void mouseReleased(MouseEvent e)
    {
    dx = e.getX();
    dy = e.getY();

    if (dx>306 & dy>54 & dx<362 & dy <72)
      {
      Label = 4;
      repaint();
      }

    if (dx>306 & dy>84 & dx<362 & dy <102)
      {
      Label = 6;
      repaint();
      }

    if (dx>306 & dy>114 & dx<362 & dy <132)
      {
      Label = 8;
      repaint();
      }


    }

  public void mouseEntered(MouseEvent e)
    {
    }

  public void mouseExited(MouseEvent e)
    {
    }

  public void mouseClicked(MouseEvent e)
    {
    }


  public void Rect1(Graphics g,int x1,int y1,int x2,int y2,int w)
    {
    int i;
    for(i=0;i<w;i++)
      {
      g.drawLine(x1+i,y1+i,x2-i,y1+i);
      g.drawLine(x2-i,y2-i,x1+i,y2-i);
      g.drawLine(x1+i,y1+i,x1+i,y2-i);
      g.drawLine(x2-i,y2-i,x2-i,y1+i);
      }
    g.fillRect(x1+w,y1+w,x2-x1-w*2+1,y2-y1-w*2+1);
    }

  public void Rect2(Graphics g,int x1,int y1,int x2,int y2,int w)
    {
    int i;
    for(i=0;i<w;i++)
      {
      g.drawLine(x1+i,y1+i,x2-i,y1+i);
      g.drawLine(x2-i,y2-i,x1+i,y2-i);
      g.drawLine(x1+i,y1+i,x1+i,y2-i);
      g.drawLine(x2-i,y2-i,x2-i,y1+i);
      }
    }

  }