//by Eric Tedjamulia
import java.awt.*; 
import java.applet.*; 
import java.awt.event.*;
import java.util.ArrayList;

public class dodge extends Applet implements MouseMotionListener {
	private Thread t = new Thread(); 
	private ArrayList blocks; 
	private Block me; 
	private int count, timeLeft; 
	private boolean hit, killer; 
	private final int WIDTH = 600; //Width of screen -- set in the html
	private Graphics dbg; private Image dbImage; // Used for double buffering
	
	//Methods runs when applet loads
	public void init() { 
		setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		blocks = new ArrayList(); me = new Block (WIDTH/2,WIDTH/2); count = 0; hit = false; killer = false;
		timeLeft = 0;
		addMouseMotionListener(this);
		for (int i = 0; i < 10; i++) addNewBlock();
	}
	
	public void addNewBlock(){
		int r = (int)(Math.random()*4) + 1; //Which side of ths screen (1-4)
		int r2 = (int)(Math.random()*WIDTH); //Where on the screen it appears
		int speed = (int)(Math.random()*10) + 1; //Speed of block
		boolean bad = (int)(Math.random()*50) != 0 ; // 1/50 chance to be a "good" block
		if (r == 1) blocks.add(new Block(0,r2,speed,0, bad)); 
		if (r == 2) blocks.add(new Block(WIDTH,r2,-1 * speed,0, bad));
		if (r == 3) blocks.add(new Block(r2,0,0,speed, bad));
		if (r == 4) blocks.add(new Block(r2,WIDTH,0,-1 * speed, bad));
	}
	//Paints the screen
	public void paint(Graphics g) {
		try {t.sleep(5);}catch(InterruptedException e){}
		if (killer) g.setColor(Color.green); else g.setColor(Color.blue); 
		g.fill3DRect(me.x,me.y,me.size,me.size,false);
		g.setColor(Color.black);
		for (int i = 0; i < blocks.size(); i++) {
			Block temp = (Block)blocks.get(i);
			if (!temp.isBad)
				g.setColor(Color.green);
			else
				g.setColor(Color.black);
			g.fillOval(temp.x,temp.y,10,10);
			check(temp);
			temp.x += temp.sX; temp.y += temp.sY;
			if (temp.x < 0 || temp.x > WIDTH || temp.y < 0 || temp.y> WIDTH) 
				blocks.remove(i);
		}
		if (count % 15 == 0) addNewBlock();
		if (count % 10 == 0) me.size++;
		count++;
		if (killer) {
			timeLeft--;
			g.setColor(Color.blue);
			g.setFont(new Font("Arial", Font.PLAIN,  20));
			g.drawString("TimeLeft="+timeLeft,WIDTH/2 - 20,WIDTH/2);
			if (timeLeft <= 0)
				killer = false;
		}
		if (!hit) repaint();
		else {
			g.setColor(Color.red);
			g.drawString("Score="+count,WIDTH/2 - 20,WIDTH/2);
		}
	}
	//checks for collisions
	public void check(Block temp) {
		if (me.x + me.size > temp.x && me.y + me.size > temp.y) 
			if (me.x < temp.x + 10 && me.y < temp.y + 10)
				if (!killer) {
					if (temp.isBad)
						hit = true;
					else {
						killer = true;
						timeLeft = 300;
					}
				}
				else {
					me.size -= 5;
					temp.x = 1000;
				}
	}
	//Method runs when mouse is moved
	public void mouseMoved(MouseEvent e) {		
		me.x = e.getX()- me.size/2 ; 
	    me.y = e.getY() - me.size/2 ;
	}
	
	//Double-buffering... add this method in if you want to avoid flickering in your program
	public void update(Graphics g){
		if (dbImage == null){
			dbImage = createImage (this.getSize().width, this.getSize().height);
			dbg = dbImage.getGraphics ();
		}
		dbg.setColor (getBackground ());
		dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
		dbg.setColor (getForeground());
		paint (dbg);
		g.drawImage (dbImage, 0, 0, this);
	}
	
	//Block class
	private class Block {
		private int x,y,sX,sY,size;
		private boolean isBad;
		public Block (int posX, int posY){ x = posX; y = posY; size = 10; }
		public Block (int posX, int posY, int sX, int sY, boolean bad){ 	
			this.sX = sX; this.sY = sY;
			x = posX; y = posY; size = 10;
			isBad = bad;
		}
	}
	//Required methods for the interface
	public void mouseDragged(MouseEvent e) {if(hit) init(); repaint();} //If Game Over, click to restart
	public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e) {} 
}