import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

import java.util.*;

/**
 * The controller for a Can't Atop GUI.
 *
 * @author Jim Glenn
 * @version 0.1 11/24/2008
 */

public class CantStopControl extends JPanel
{
    /**
     * The model this controller manipulates.
     */

    private CantStopGame model;

    /**
     * The text at the bottom of the panel that tells the player what
     * input is expected.
     */

    private JTextField messageField;

    /**
     * The buttons that allow the player to select a move.  The action
     * command on these buttons will be set to the index of the
     * corresponding move into the model's getLegalMoves list.
     */

    private JButton[] moveButtons;

    /**
     * The "Roll" button.
     */

    private JButton rollButton;

    /**
     * The "Stop" button.  When the current roll "blows it" this button
     * displays "Blow It" to let the player acknowledge the bad roll.
     */

    private JButton stopButton;


    /**
     * Creates a controller connected to the given model.
     *
     * @param g a model of Can't Stop
     */

    public CantStopControl(CantStopGame g)
    {
	model = g;

	setLayout(new BorderLayout());
	
	// create the message display the the bottom of the panel

	messageField = new JTextField();
	messageField.setEditable(false);
	add(messageField, BorderLayout.SOUTH);

	// create a 3x3 array of buttons with the move buttons in the top
	// 2 rows

	JPanel buttonPanel = new JPanel(new GridLayout(3, 3));
	moveButtons = new JButton[6];
	for (int i = 0; i < 6; i++)
	    {
		moveButtons[i] = new JButton();
		moveButtons[i].setActionCommand("" + i);
		moveButtons[i].addActionListener(new MoveListener());
		buttonPanel.add(moveButtons[i]);
	    }
	
	// create the roll and stop buttons and place them in the bottom row

	rollButton = new JButton("Roll");
	rollButton.addActionListener(new RollListener());
	stopButton = new JButton();
	stopButton.addActionListener(new StopListener());
	buttonPanel.add(rollButton);
	buttonPanel.add(new JPanel());
	buttonPanel.add(stopButton);

	// add all the buttons to the center of the panel

	add(buttonPanel, BorderLayout.CENTER);

	// set the text on the buttons

	setButtons();
    }

    /**
     * Sets the text on the buttons (and the message text) according
     * to the current state of the model.
     */

    private void setButtons()
    {
	switch (model.getState())
	    {
	    case CantStopGame.START_STATE:
		clearMoveButtons();
		messageField.setText("Click roll to roll the dice.");
		rollButton.setEnabled(true);
		stopButton.setText("Stop");
		stopButton.setEnabled(false);
		break;

	    case CantStopGame.ROLL_STATE:
		clearMoveButtons();
		messageField.setText("Roll again or end your turn.");
		rollButton.setEnabled(true);
		stopButton.setText("Stop");
		stopButton.setEnabled(true);
		break;
  
	    case CantStopGame.ACK_STATE:
		clearMoveButtons();
		messageField.setText("No moves possible -- click \"Blow it\".");
		rollButton.setEnabled(false);
		stopButton.setText("Blow it");
		stopButton.setEnabled(true);
		break;

	    case CantStopGame.MOVE_STATE:
		setMoveButtons();
		messageField.setText("Choose your move");
		rollButton.setEnabled(false);
		stopButton.setText("Stop");
		stopButton.setEnabled(false);
		break;

	    case CantStopGame.WON_STATE:
		clearMoveButtons();
		messageField.setText("You won!");
		rollButton.setEnabled(false);
		stopButton.setText("Stop");
		stopButton.setEnabled(false);
		break;
	    }
    }

    /**
     * Sets all the move buttons to blank and disables them.
     * This is intended to be used to set the buttons at the
     * start of a turn before a roll has been made.
     */

    private void clearMoveButtons()
    {
	for (int i = 0; i < moveButtons.length; i++)
	    {
		moveButtons[i].setText("");
		moveButtons[i].setEnabled(false);
	    }
    }

    /**
     * Sets the text on the move buttons according to the currently
     * level moves and enables them.  This is intended to be used
     * after a good roll (one that doesn't blow it.
     */

    private void setMoveButtons()
    {
	java.util.List moves = model.getLegalMoves();

	for (int i = 0; i < moveButtons.length; i++)
	    {
		if (i < moves.size())
		    {
			java.util.List move = (java.util.List)(moves.get(i));
			String label = "";
			Iterator j = move.iterator();
			while (j.hasNext())
			    {
				label = label + j.next();
				if (j.hasNext())
				    label = label + " - ";
			    }
			moveButtons[i].setText(label);
			moveButtons[i].setEnabled(true);
		    }
		else
		    {
			// disable buttons if fewer than 6 legal moves
			
			moveButtons[i].setText("");
			moveButtons[i].setEnabled(false);
		    }
	    }
    }

    /**
     * Relays clicks on the move buttons to the model.
     */

    private class MoveListener implements ActionListener
    {
	public void actionPerformed(ActionEvent e)
	{
	    model.makeMove(Integer.parseInt(e.getActionCommand()));
	    setButtons();
	}
    }

    /**
     * Relays clicks on the roll button to the model.
     */

    private class RollListener implements ActionListener
    {
	public void actionPerformed(ActionEvent e)
	{
	    // tell the model to roll the dice

	    model.roll();

	    // reset the buttons

	    setButtons();
	}
    }

    /**
     * Relays clicks on the roll/blow it button to the model.
     */

    private class StopListener implements ActionListener
    {
	public void actionPerformed(ActionEvent e)
	{
	    // determine if we're stopping or blowing it

	    if (model.getState() == CantStopGame.ACK_STATE)
		{
		    model.blowIt();
		}
	    else 
		{
		    model.endTurn();
		}

	    // reset the buttons accordingly

	    setButtons();
	}
    }

}

