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

/**
 * The user interface and main program for the munch game.
 *
 * This is a two-player game.  Each player controls a caterpillar and
 * attempts to perform manuevers so that it eats as many pellets as
 * possible.  Whoever eats more pellets is the winner.
 *
 * The caterpillars are controlled via keyboard commands.  Caterpillars
 * initially move eastward, but at any moment a user can command the
 * caterpillar to stop moving or else change directions (north, south, 
 * east, or west).  The keyboard commands for each player are as follows:
 *
 * Player one (blue): w=north, s=south, d=east, a=west, q=stop
 *
 * Player two (red):  i=north, k=south, l=east, j=west, p=stop
 *
 * @see Caterpillar
 * @see Pellets
 */
public class MunchGame extends Frame
{
	// The internal state of a munch game
	final static int length = 10;       // length of each caterpillar
	final static int BoardWidth = 60;   // board width ...
	final static int BoardHeight = 40;  // ... and height
	final static int SegmentSize = 10;  // size of each caterpillar segment

	// player one's caterpillar
    private Caterpillar playerOne = new Caterpillar (Color.blue, new Point(20, 10), length, SegmentSize*4);
    // player two's caterpillar
    private Caterpillar playerTwo = new Caterpillar (Color.red, new Point(20, 30), length, SegmentSize*(BoardWidth-4));
    // the pellets
    Pellets pellets = new Pellets (Color.green, 10);

    /**
     * Create a new instance of the munch game.
     */
    public MunchGame()
    {
		setSize((BoardWidth+1)*SegmentSize, BoardHeight*SegmentSize+32);
		setTitle("Munch Game");
		addKeyListener(new KeyReader());
		addWindowListener(new CloseAndQuit());
    }
	
	
    /**
     * Run the caterpillar game.
     */
    public void run()
    {
		while (!pellets.allGone())
		{
		    movePieces();
		    repaint();
		    try
		    {
				Thread.sleep(100);
		    }
		    catch (Exception e) { }
		}
    }
	
	
    /**
     * Redraw the two caterpillars.
     *
     * @param g the graphics pane on which to redraw
     */
    public void paint(Graphics g)
    {
		if (pellets.allGone())
		{
			int playerOneScore = playerOne.score();
			int playerTwoScore = playerTwo.score();
			g.setFont(g.getFont().deriveFont(Font.BOLD, (float)20.0));

			if (playerOneScore > playerTwoScore)
			{
				g.setColor(Color.blue);
				g.drawString("Blue is the winner!", 220,200);
			}
			else if (playerTwoScore > playerOneScore)
			{
				g.setColor(Color.red);
				g.drawString("Red is the winner!", 220,200);
			}
			else
			{
				g.setColor(Color.black);
				g.drawString("A tie game!", 250,200);
			}
		}
		else
		{
			pellets.paint(g);
			playerOne.paint(g);
			playerTwo.paint(g);
		}
    }


    /**
     * For each player, consume the next command and move accordingly.
     */
    public void movePieces() 
    {
		playerOne.move(this);
		playerTwo.move(this);
    }
	
	
    /**
     * Determine whether the given point is free (so that a caterpillar
     * can move into it).
     *
     * @param np the point to test
     * @return true if point np is free
     */
    public boolean canMove(Point np)
    {
		// get x, y coordinate
		int x = np.x;
		int y = np.y;
		// test playing board
		if ((x <= 0) || (y <= 0))
			return false;
		if ((x >= BoardWidth) || (y >= BoardHeight))
			return false;
		// test caterpillars
		if (playerOne.inPosition(np))
			return false;
		if (playerTwo.inPosition(np))
			return false;
		// ok, safe square
		return true;
    }

    // Convert keyboard inputs for the two players into caterpillar commands.
    private class KeyReader extends KeyAdapter
    {
		public void keyPressed (KeyEvent e)
		{
	    	char c = e.getKeyChar();
			switch (c)
			{
				case 'q': playerOne.setDirection('Z'); break;
				case 'p': playerTwo.setDirection('Z'); break;
				case 'a': playerOne.setDirection('W'); break;
				case 'd': playerOne.setDirection('E'); break;
				case 'w': playerOne.setDirection('N'); break;
				case 's': playerOne.setDirection('S'); break;
				case 'j': playerTwo.setDirection('W'); break;
				case 'k': playerTwo.setDirection('S'); break;
				case 'l': playerTwo.setDirection('E'); break;
				case 'i': playerTwo.setDirection('N'); break;
			}
		}
	}

    private class CloseAndQuit extends WindowAdapter
    {
		public void windowClosing (WindowEvent e)
		{
	    	System.exit(0);
		}
    }
    
    
    /**
     * The main method. This creates a new world, displays it, and then
     * starts it running.
     *
     * @param args the command line arguments (all of which are ignored)
     */
    public static void main(String[] args)
    {
		MunchGame world = new MunchGame();
		world.show();
		world.run();
    }
}
