package com.goatsandtigers.tictactoe;

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import com.goatsandtigers.minimax.VanillaMinimax;

public class TicTacToeApplet extends Applet implements MouseListener, ActionListener
{

	public static final int    SQUARE_WIDTH           = 70;
	public static final String newGameButtonLabel     = "New Game";
	public static final String randomMoveButtonLabel  = "Make Random Move";
	public static final String perfectMoveButtonLabel = "Make Perfect Move";

	private TicTacToeBoard board = new TicTacToeBoard();
	private Font           font  = new Font("Arial", Font.PLAIN, 18);

	/**
	 * Called automatically when the applet is instantiated.
	 * Enable trapping of mouse events and button clicks and create a
	 * panel containing buttons at the bottom of the form.
	 */
	public void init()
	{
		this.addMouseListener(this);
		Panel panel = new Panel();
		panel.setLayout(new GridLayout(3, 1));
		Button newGameButton     = new Button(TicTacToeApplet.newGameButtonLabel);
		Button randomMoveButton  = new Button(TicTacToeApplet.randomMoveButtonLabel);
		Button perfectMoveButton = new Button(TicTacToeApplet.perfectMoveButtonLabel);
		panel.add(newGameButton);
		panel.add(randomMoveButton);
		panel.add(perfectMoveButton);
		newGameButton.addActionListener(this);
		randomMoveButton.addActionListener(this);
		perfectMoveButton.addActionListener(this);
		this.setLayout(new BorderLayout());
		this.add(panel, BorderLayout.PAGE_END);
	}

	/**
	 * Erases the previous frame and draws the board
	 */
	public void paint(Graphics g)
	{
		// Ease the previous frame
		g.setColor(Color.WHITE);
		g.fillRect(1, 1, 600, 600);

		// Draw the lines of the board
		g.setColor(Color.BLACK);
		g.drawLine(0,
				TicTacToeApplet.SQUARE_WIDTH,
				TicTacToeApplet.SQUARE_WIDTH * 3,
				TicTacToeApplet.SQUARE_WIDTH);

		g.drawLine(0,
				TicTacToeApplet.SQUARE_WIDTH * 2,
				TicTacToeApplet.SQUARE_WIDTH * 3,
				TicTacToeApplet.SQUARE_WIDTH * 2);

		g.drawLine(TicTacToeApplet.SQUARE_WIDTH,
				0,
				TicTacToeApplet.SQUARE_WIDTH,
				TicTacToeApplet.SQUARE_WIDTH * 3);

		g.drawLine(TicTacToeApplet.SQUARE_WIDTH * 2,
				0,
				TicTacToeApplet.SQUARE_WIDTH * 2,
				TicTacToeApplet.SQUARE_WIDTH * 3);

		// Draw the noughts and crosses on the board
		g.setFont(this.font);
		for(int i = 0; i < 3; i++)
		{
			for(int j = 0; j < 3; j++)
			{
				if(this.board.getSquare(i, j) == TicTacToeBoard.NOUGHT)
				{
					g.drawString("O", i * TicTacToeApplet.SQUARE_WIDTH + 30, j * TicTacToeApplet.SQUARE_WIDTH + 40);
				}
				else if(this.board.getSquare(i, j) == TicTacToeBoard.CROSS)
				{
					g.drawString("X", i * TicTacToeApplet.SQUARE_WIDTH + 30, j * TicTacToeApplet.SQUARE_WIDTH + 40);
				}
			}
		}
	}

	/**
	 * Handle mouse click events. If an empty square was clicked on then
	 * make a move in that square. 
	 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	 */
	public void mouseClicked(MouseEvent me)
	{
		Point p = new Point(me.getX() / TicTacToeApplet.SQUARE_WIDTH,
				me.getY() / TicTacToeApplet.SQUARE_WIDTH);

		if(this.board.getSquare(p.x, p.y) == TicTacToeBoard.EMPTY_SQUARE)
		{
			this.board.doMove(p);
			this.repaint();
		}
	}

	public void mouseEntered(MouseEvent arg0) {}
	public void mouseExited(MouseEvent arg0) {}
	public void mousePressed(MouseEvent arg0) {}
	public void mouseReleased(MouseEvent arg0) {}

	/**
	 * Handle click events for buttons on the form.
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent ae)
	{
		String command = ae.getActionCommand();
		if(command.equals(TicTacToeApplet.newGameButtonLabel))
		{
			this.board = new TicTacToeBoard();
			this.repaint();
		}
		else if(command.equals(TicTacToeApplet.perfectMoveButtonLabel))
		{
			this.board.makePerfectMove(VanillaMinimax.UNLIMITED_SEARCH_DEPTH);
			this.repaint();
		}
		else if(command.equals(TicTacToeApplet.randomMoveButtonLabel))
		{
			int startingSquare = (int)(Math.random() * 9);
			for(int i = 0; i < 9; i++)
			{
				Point p = new Point((startingSquare + i / 3) % 3,
						(startingSquare + 1) % 3);
				if(this.board.getSquare(p.x, p.y) == TicTacToeBoard.EMPTY_SQUARE)
				{
					this.board.doMove(p);
					break;
				}
			}
			this.repaint();
		}
	}
}