/*
 * Puzzle.java
 *
 * Provide a question for the COSC 198, Spring 1999 Exam 2
 *
 * written by mike slattery - mar 1999
 */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class Puzzle extends Applet implements Runnable
{
	SqrSprite square;
	WallSprite scenery[];
	Rectangle goal;
	Thread anim;
	Image buffer;
	Graphics bufgr;
	Font font;
	boolean switch1=false, switch2=false;
	String code;

	public static final int FRAME_DELAY = 50;

	public void init()
	{
		addMouseListener(new mseL());
		addKeyListener(new keyL());

		buffer = createImage(400,300);
		bufgr = buffer.getGraphics();
		font = new Font("TimesRoman",Font.ITALIC,30);
		scenery = new WallSprite[8];
		scenery[0] = new WallSprite(175,70,5,60);
		scenery[1] = new WallSprite(175,70,60,5);
		scenery[2] = new WallSprite(175,125,60,5);
		scenery[3] = new WallSprite(230,70,5,60);
		scenery[4] = new WallSprite(0,0,399,5);
		scenery[5] = new WallSprite(0,294,399,5);
		scenery[6] = new WallSprite(394,0,5,299);
		scenery[7] = new WallSprite(0,0,5,299);
		square = new SqrSprite(50,135,20,20,scenery);
		goal = new Rectangle(180,75,50,50);
	}

	public void start()
	{
		anim = new Thread(this);
		anim.start();
	}

	public void stop()
	{
		anim.stop();
		anim = null;
	}

	public void run()
	{
		while(true)
		{
			// Check for special conditions
			if (switch1 && switch2)
				scenery[3].suspend();
			else if (!(scenery[3].isActive()))
				scenery[3].restore();

			square.update();
			repaint();
			try
			{
				Thread.sleep(FRAME_DELAY);
			} catch (InterruptedException e)
				{}
		}
	}

	private boolean wonGame()
	{
		return goal.contains(square.getX(),square.getY()) &&
			scenery[3].isActive();
	}

	public void update(Graphics g)
	{
		paint(bufgr);
		g.drawImage(buffer,0,0,this);
	}

	public void paint(Graphics g)
	{
		//System.out.println("Begin paint");
		g.setColor(Color.white);
		g.fillRect(0,0,400,300);
		//System.out.println("Begin scenery");
		for (int i = 0; i < scenery.length; i++)
		{
			scenery[i].paint(g);
		}
		square.paint(g);

		if (wonGame())
		{
			if (code==null)
				code = Spinner.getCode();
			g.setColor(Color.black);
			g.setFont(font);
			g.drawString("Code="+code,60,250);
		}

	}

	private class mseL extends MouseAdapter
	{
		public void mouseClicked(MouseEvent e)
		{
			requestFocus();
			square.headTo(e.getX(),e.getY());
		}
	}

	private class keyL extends KeyAdapter
	{
		public void keyPressed(KeyEvent e)
		{
			int key = e.getKeyCode();
			switch (key)
			{
				case KeyEvent.VK_A: break;
				case KeyEvent.VK_C: switch1 = true;
							break;
				case KeyEvent.VK_W: switch2 = true;
							break;
			}
		}
		public void keyReleased(KeyEvent e)
		{
			int key = e.getKeyCode();
			if (key == KeyEvent.VK_C) switch1 = false;
			if (key == KeyEvent.VK_W) switch2 = false;
				
		}
	}
}

class WallSprite extends RectSprite
{

	public WallSprite(int x, int y, int w, int h)
	{
		super(x, y, w, h, Color.red);
		fill = true;
	}
	
	public Rectangle getBoundingBox()
	{
		return new Rectangle(locx, locy, width, height);
	}
}

class SqrSprite extends RectSprite
{
	int vx, vy;
	WallSprite scenery[];

	static final int SPEED = 5;

	SqrSprite(int x, int y, int w, int h, WallSprite s[])
	{
		super(x, y, w, h, Color.blue);
		fill = true;
		scenery = s;
		setVelocity(0,0);
	}

	public void setVelocity(int x, int y)
	{
		vx = x; vy = y;
	}

	public void headTo(int x, int y)
	{
		int dx = x - locx;
		int dy = y - locy;
		float len = (float)Math.sqrt(dx*dx+dy*dy);
		setVelocity((int)(dx*SPEED/len), (int)(dy*SPEED/len));
	}

	public Rectangle getBoundingBox()
	{
		return new Rectangle(locx, locy, width, height);
	}

	public int getX()
	{
		return locx;
	}

	public int getY()
	{
		return locy;
	}

	public boolean collision(WallSprite h)
	{
		if (h.isActive())
		{
			Rectangle bb = getBoundingBox();
			return bb.intersects(h.getBoundingBox());
		}
		else
			return false;
	}

	public void update()
	{
		locx += vx; locy += vy;
		for (int i = 0; i < scenery.length; i++)
		{
			if (collision(scenery[i]))
			{
				// Hit something solid, back up and stop
				locx -= vx; locy -= vy;
				setVelocity(0,0);
			}
		}
	}

}


