package jrummikub.control.turn;

import jrummikub.model.GameSettings;
import jrummikub.model.IHand;
import jrummikub.model.ITable;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;
import jrummikub.util.IEvent3;
import jrummikub.view.IView;

/**
 * Interface containing shared methods of human and computer turn control
 * 
 */
public interface ITurnControl {
	/**
	 * Start the turn
	 * 
	 * @param info
	 *            the current turn state
	 * 
	 * @param settings
	 *            the game settings
	 * @param view
	 *            view for user interaction.
	 */
	public void setup(TurnInfo info, GameSettings settings, IView view);

	/**
	 * Get the event that is emitted when the turn is over
	 * 
	 * @return end of turn event
	 */
	public IEvent3<IHand, ITable, ITable> getEndOfTurnEvent();

	/**
	 * Emitted when the round is aborted and needs to be restarted
	 * 
	 * @return the event
	 */
	public IEvent getRedealEvent();

	/**
	 * Start the turn
	 */
	public void startTurn();

	/**
	 * Abort the turn
	 */
	public void abortTurn();

	/**
	 * Emitted in network when the table changes during player turn
	 * 
	 * @return the event
	 */
	public IEvent1<ITable> getTableUpdateEvent();

	/**
	 * The TurnInfo class encapsulates all information concerning the current
	 * turn
	 */
	public class TurnInfo {
		private ITable table;
		private IHand hand;
		private boolean hasLaidOut;
		private TurnMode turnMode;

		/**
		 * Creates a new TurnInfo instance
		 * 
		 * @param table
		 *            the current table
		 * @param hand
		 *            the current player's hand
		 * @param hasLaidOut
		 *            has the player laid out yet?
		 * @param turnMode
		 *            the turn mode
		 */
		public TurnInfo(ITable table, IHand hand, boolean hasLaidOut,
				TurnMode turnMode) {
			this.table = table;
			this.hand = hand;
			this.hasLaidOut = hasLaidOut;
			this.turnMode = turnMode;
		}

		/**
		 * Gets the current table
		 * 
		 * @return the table
		 */
		public ITable getTable() {
			return table;
		}

		/**
		 * Gets the current player's hand
		 * 
		 * @return the hand
		 */
		public IHand getHand() {
			return hand;
		}

		/**
		 * Returns if the current player has laid out yet
		 * 
		 * @return if the player has laid out
		 */
		public boolean getLaidOut() {
			return hasLaidOut;
		}

		/**
		 * Gets the current turn's mode
		 * 
		 * @return the turn mode
		 */
		public TurnMode getTurnMode() {
			return turnMode;
		}
	}
}