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

/**
 * This class reads PARAM tags from its HTML host page and sets
 * the color and label properties of the applet. Program execution
 * begins with the init() method. 
 */
public class Applet1 extends Applet implements Runnable
{
  public Playfield field;
  public Thread mainthread;
  public AnimatedSprite monkey, smiley, fight, dyingmonkey, smileywin, fatality;
  public Playfield p;
  public boolean lockdraw;
  public boolean monkeyhead=false;
  public boolean monkeywalk=false;
  public boolean smileywalk=false;
  public boolean done=false;
  public boolean monkeyjump=false;
  public int monkeyheadcount=0;
  public boolean smileyjump=false;
  public boolean smileybob=false;
  public boolean monkeydead=false;
  public boolean monkeydying=false;
  public int monkeydir=0, monkeyup=0;
  public int smileydir=0, smileyup=0;
  public int dietick=0;
  public Image output;
  public boolean win=false;
  
  public void init()
  {
    field=new Playfield(getImage(getCodeBase(), "portal.gif"));
    monkey=new AnimatedSprite(getImage(getCodeBase(), "MonkAni.gif"), 7);
    monkey.addtrack(new int[]{3, 0, 1, 2, 3, 4, 3, 2, 1});
    monkey.addtrack(new int[]{3, 2, 5, 6, 5, 2});
    monkey.addtrack(new int[]{5, 2});
    smiley=new AnimatedSprite(getImage(getCodeBase(), "smiley.gif"), 1);
    fight=new AnimatedSprite(getImage(getCodeBase(), "fight.gif"), 1);
    fight.x=200;
    fight.y=20;
    dyingmonkey=new AnimatedSprite(getImage(getCodeBase(), "dyingmonkey.gif"), 6);
    dyingmonkey.addtrack(new int[]{1, 0, 1, 2, 3, 4, 5});
    dyingmonkey.addtrack(new int[]{5, 5});
    smileywin=new AnimatedSprite(getImage(getCodeBase(), "win.gif"), 1);
    smileywin.x=150;
    smileywin.y=20;
    fatality=new AnimatedSprite(getImage(getCodeBase(), "fatality.gif"), 1);
    fatality.x=150;
    fatality.y=50;
    reset();
    mainthread=new Thread(this);
    mainthread.start();
    mainthread.suspend();
  }
  
  private final String labelParam = "label";
  private final String backgroundParam = "background";
  private final String foregroundParam = "foreground";
  
  public void reset()
  {
    field.deleteSprite(dyingmonkey);
    field.deleteSprite(fatality);
    field.deleteSprite(smileywin);
    smiley.x=-50;
    smiley.y=260;
    monkey.x=500;
    monkey.y=150;
    monkeyhead=false; done=false; monkeyjump=false; monkeyheadcount=0; smileyjump=false; smileybob=false;
    monkeydead=false; monkeydying=false;
    field.addSprite(monkey);
    field.addSprite(smiley);
    monkeywalk=true;
    smileywalk=true;
    monkey.chgtrack(1);
    dietick=0;
  }
  
  public void stop()
  {
    mainthread.suspend();
  }
  
  public void start()
  {
    mainthread.resume();
  }
  
  public void run()
  {
    while (true)
      {
	synchronized(this)
	  {
	    p=(Playfield)field.getclone();
	    if (smileywalk)
	      {
		smiley.x++;
		if (smiley.x>70)
		  {
		    smileywalk=false;
		  }
	      }
	    if (monkeywalk)
	      {
		monkey.x-=1;
		if (monkey.x < 360)
		  {
		    monkeywalk=false;
		    monkey.chgtrack(3);
		    field.addSprite(fight);
		  }
	      }
	    if (smileyjump || smileybob)
	      {
		smiley.x+=smileydir;
		if (smiley.x<0) smiley.x=0;
		if (smiley.x>480) smiley.x=480;
		smiley.y+=smileyup;
		if (smileybob)
		  {
		    smileyup--;
		    if (smiley.y<260)
		      {
			smiley.y=260;
			smileybob=false;
		      }
		  }
		else if (smileyjump)
		  {
		    smileyup++;
		    if (smiley.y>260)
		      {
			smiley.y=260;
			smileyjump=false;
		      }
		  }
	      }
	    if (monkeyjump)
	      {
		monkey.x+=monkeydir;
		if (monkey.x<0) monkey.x=0;
		if (monkey.x>440) monkey.x=440;
		monkey.y+=monkeyup;
		monkeyup++;
		if (monkey.y>150)
		  {
		    monkey.y=150;
		    monkeyjump=false;
		    monkey.chgtrack(3);
		  }
	      }
	    if (monkeyhead)
	      {
		monkeyheadcount++;
		if (monkeyheadcount > 50)
		  {
		    monkeyhead=false;
		    monkeyheadcount=0;
		    monkey.chgtrack(3);
		  }
	      }
	
	    if (smiley.x<monkey.x+100 && smiley.x>monkey.x+20 && smiley.y<monkey.y && smiley.y > monkey.y-50 && !monkeydying && !done && !win && !monkeydead)
	      {
		monkeyjump=false;
		monkeyhead=false;
		smileybob=false;
		smileyjump=false;
		monkeydying=true;
		dyingmonkey.x=monkey.x;
		dyingmonkey.y=monkey.y;
		field.addSprite(dyingmonkey);
		field.deleteSprite(monkey);
		dyingmonkey.chgtrack(1);
		System.out.println("Added dyingmonkey");
	      }
	    if (monkeydying)
	      {
		System.out.println("dying");
		dietick++;
		if (dietick==12)
		  {
		    System.out.println("dead");
		    monkeydying=false;
		    monkeydead=true;
		    dyingmonkey.chgtrack(2);
		  }
		smiley.y+=3;
		if (smiley.y>260)
		  smiley.y=260;
	      }
	    if (monkeydead)
	      {
		monkeydying=false;
		monkeydead=false;
		win=true;
		dietick=0;
		field.addSprite(smileywin);
	      }
	    if (win)
	      {
		dietick++;
		if (dietick>10)
		  {
		    monkeydying=false;
		    field.addSprite(fatality);
		    done=true;
		    win=false;
		  }
	      }
	    
	    field.Draw();
	    if (p==null)
	      {
		output=field.toImage();
		System.out.println("orig");
	      }
	    else
	      output=p.toImage();
	  }
	repaint();
      }
  }
  
  public boolean mouseDown(Event e, int x, int y)
  {
    if (!done)
    {
      if (!monkeywalk)
	{
	  field.deleteSprite(fight);
	  Raster r = field.pixelowner(x, y);
	  if (r != field)
	    {
	      if (r == smiley && !smileyjump && !smileybob)
		{	// smiley: 48x48
		  if (y-smiley.y<24)
		    {
		      smileybob=true;
		      smileyup=6;
		      smileydir=0;
		    }
		  else if (x-smiley.x<24)
		    {
		      smileyjump=true;
		      smileyup=-20;
		      smileydir=1;
		    }
		  else
		    {
		      smileyjump=true;
		      smileyup=-20;
		      smileydir=-1;
		    }
		}
	      if (r == monkey && !monkeyjump && !monkeyhead)
		{	// monkey: 897x180 -> 128x180
		  if (y-monkey.y<50)
		    {
		      monkeyhead=true;
		      monkeyheadcount=0;
		      monkey.chgtrack(2);
		    }
		  else if (x-monkey.x<64)
		    {
		      monkeyjump=true;
		      monkey.chgtrack(1);
		      monkeydir=1;
		      monkeyup=-20;
		    }
		  else
		    {
		      monkeyjump=true;
		      monkey.chgtrack(1);
		      monkeydir=-1;
		      monkeyup=-20;
		    }
		}
	    }
	}
    }
    else
      {
	done=false;
	//	field.deleteSprite(dyingmonkey);
	reset();
      }
    return true;
  }
  
  
  public void paint(Graphics g)
  {
    update(g);
  }
  
  public void update(Graphics g)
  {
    //    System.out.println("Paint!");
    synchronized (this)
      {
	g.drawImage(output, 0, 0, this);
      }
  }
  
  /**
   * Reads parameters from the applet's HTML host and sets applet
   * properties.
   */
  //	private void usePageParams()
  //	{
  //		final String defaultLabel = "Default label";
  //		final String defaultBackground = "C0C0C0";
  //		final String defaultForeground = "000000";
  //		String labelValue;
  //		String backgroundValue;
  //		String foregroundValue;
  
  /** 
   * Read the <PARAM NAME="label" VALUE="some string">,
   * <PARAM NAME="background" VALUE="rrggbb">,
   * and <PARAM NAME="foreground" VALUE="rrggbb"> tags from
   * the applet's HTML host.
   */
  //		Labelvalue = getParameter(labelParam);
  //		backgroundValue = getParameter(backgroundParam);
  //		foregroundValue = getParameter(foregroundParam);
  
  //		if ((labelValue == null) || (backgroundValue == null) ||
  //			(foregroundValue == null))
  //		{
  /**
   * There was something wrong with the HTML host tags.
   * Generate default values.
   */
  //			labelValue = defaultLabel;
  //			backgroundValue = defaultBackground;
  //			foregroundValue = defaultForeground;
  //		}
  
  /**
   * Set the applet's string label, background color, and
   * foreground colors.
   */
  //		label1.setText(labelValue);
  //		label1.setBackground(stringToColor(backgroundValue));
  //		label1.setForeground(stringToColor(foregroundValue));
  //		this.setBackground(stringToColor(backgroundValue));
  //		this.setForeground(stringToColor(foregroundValue));
  //	}
  
  /**
   * Converts a string formatted as "rrggbb" to an awt.Color object
   */
  private Color stringToColor(String paramValue)
  {
    int red;
    int green;
    int blue;
    
    red = (Integer.decode("0x" + paramValue.substring(0,2))).intValue();
    green = (Integer.decode("0x" + paramValue.substring(2,4))).intValue();
    blue = (Integer.decode("0x" + paramValue.substring(4,6))).intValue();
    
    return new Color(red,green,blue);
  }
  
  /**
   * External interface used by design tools to show properties of an applet.
   */
  public String[][] getParameterInfo()
  {
    String[][] info =
    {
      { labelParam, "String", "Label string to be displayed" },
      { backgroundParam, "String", "Background color, format \"rrggbb\"" },
      { foregroundParam, "String", "Foreground color, format \"rrggbb\"" },
    };
    return info;
  }
  
  Label label1 = new Label();
  
  /**
   * Intializes values for the applet and its components
   */
  //	void initForm()
  //	{
  //		this.setBackground(Color.lightGray);
  //		this.setForeground(Color.black);
  //		label1.setText("label1");
  //		this.setLayout(new BorderLayout());
  //		this.add("North",label1);
  //	}
}
