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

/**
 * An applet that displays a chess board and allows the user to
 * move pieces around.
 *
 * @author Jim Glenn
 * @version 0.1 12/3/2002
 */

public class ChessApplet extends Applet
{
    /**
     * The model of the chess board.
     */

    private ChessBoard board;

    /**
     * The components that display (crudely) the pieces on the board.
     */

    private SquareView[][] squares;

    /**
     * The state of the input
     */

    private int state;

    /**
     * Whose move it is
     */

    private int whoseMove;

    /**
     * Constants for states/
     */

    private static final int NOTHING_SELECTED = 0;
    private static final int PIECE_SELECTED = 1;

    /**
     * Coordinates of the selected piece (if any)
     */

    private int selectedRow, selectedCol;

    /**
     * Sets up the interface for this applet.
     */

    public void init()
    {
	state = NOTHING_SELECTED;
	whoseMove = ChessBoard.WHITE;

	board = new ChessBoard();

	squares = new SquareView[board.getHeight()][board.getWidth()];

	setLayout(new GridLayout(board.getHeight(), board.getWidth()));

	for (int r = 0; r < squares.length; r++)
	    for (int c = 0; c < squares[r].length; c++)
		{
		    squares[r][c] = new SquareView();
		    squares[r][c].setBackground(getSquareColor(r, c));
		    squares[r][c].addMouseListener(new SquareListener(this, r, c));
		    updateSquare(r, c);
		    add(squares[r][c]);
		}
    }

    /**
     * Invoked when the user clicks on one of the squares.  Note that
     * this applet does not receive mouse events directly; they are
     * passed through SquareListener objects to this applet.
     *
     * @param r the row index of the square clicked on
     * @param c the column index of the square clicked on
     */

    public void mouseClicked(int r, int c)
    {
	if (state == NOTHING_SELECTED)
	    {
		if (!board.isEmpty(r, c) && board.getPieceColor(r, c) == whoseMove)
		    {
			selectedRow = r;
			selectedCol = c;
			state = PIECE_SELECTED;
			squares[r][c].setBackground(Color.green);
		    }
	    }
	else
	    {
		if (board.isLegalMove(selectedRow, selectedCol, r, c))
		    {
			board.makeMove(selectedRow, selectedCol, r, c);
			updateSquare(r, c);
			updateSquare(selectedRow, selectedCol);

			if (whoseMove == ChessBoard.BLACK)
			    whoseMove = ChessBoard.WHITE;
			else
			    whoseMove = ChessBoard.BLACK;
		    }
		squares[selectedRow][selectedCol].setBackground(getSquareColor(selectedRow, selectedCol));
		state = NOTHING_SELECTED;
	    }
    }

    /**
     * Returns the color of the given square on the chess board.
     *
     * @param r the row index of the square
     * @param c the column index of the square
     */

    public Color getSquareColor(int r, int c)
    {
	if (r % 2 == c % 2)
	    return Color.black;
	else
	    return Color.white;
    }

    /**
     * Updates the component at the given location to display what
     * is on the board at that location.
     *
     * @param r the row index of the location to update
     * @param c the column index of the location to update
     */

    private void updateSquare(int r, int c)
    {
	if (!board.isEmpty(r, c))
	    {
		if (board.getPieceColor(r, c) == ChessBoard.WHITE)
		    squares[r][c].setForeground(Color.gray);
		else
		    squares[r][c].setForeground(Color.magenta);
		squares[r][c].setText(String.valueOf(board.getPiece(r, c)));
	    }
	else
	    squares[r][c].setText(" ");
    }
}

