package jrummikub.view;

import java.awt.Color;
import java.io.File;
import java.util.Collection;

import jrummikub.model.Stone;
import jrummikub.model.StoneSet;
import jrummikub.util.IEvent;
import jrummikub.util.IEvent1;

/**
 * The top-level view interface
 */
public interface IView {
	/**
	 * Returns the settings panel
	 * 
	 * @return the settings panel
	 */
	public ISettingsPanel getSettingsPanel();

	/**
	 * Returns the score panel
	 * 
	 * @return the score panel
	 */
	public IScorePanel getScorePanel();

	/**
	 * Returns the table
	 * 
	 * @return the table
	 */
	public ITablePanel getTablePanel();

	/**
	 * Returns the side panel
	 * 
	 * @return the side panel
	 */
	public ISidePanel getSidePanel();

	/**
	 * @return the board where the players hand stones are displayed
	 */
	public IHandPanel getHandPanel();

	/**
	 * Returns the player panel
	 * 
	 * @return the playerPanel
	 */
	public IPlayerPanel getPlayerPanel();

	/**
	 * Sets the current player's name
	 * 
	 * @param playerName
	 *          the player name
	 */
	public void setCurrentPlayerName(String playerName);

	/**
	 * Sets the name of the player that has redealt last
	 * 
	 * @param name
	 *          the player name
	 */
	public void setRedealedPlayerName(String name);

	/**
	 * Sets the name of the player that has drawn the last stone
	 * 
	 * @param name
	 *          the player name
	 */
	public void setLastStonePlayerName(String name);

	/**
	 * Sets the stones that are to be painted selected
	 * 
	 * @param stones
	 *          the stones to be painted selected
	 */
	public void setSelectedStones(Collection<Stone> stones);

	/**
	 * The start turn event is emitted when the player wants to start his turn
	 * 
	 * @return the event
	 */
	public IEvent getStartTurnEvent();

	/**
	 * The start turn event is emitted when the player knows what invalid stones
	 * he played
	 * 
	 * @return the event
	 */
	public IEvent getAcknowledgeInvalidEvent();

	/**
	 * The acknoledge connection lost event is emitted when the user has
	 * acknowledged that the network connection was lost
	 * 
	 * @return the event
	 */
	public IEvent getAcknowledgeConnectionLostEvent();

	/**
	 * The quit event is emitted when the player wants to quit the game
	 * 
	 * @return the event
	 */
	public IEvent getEndProgramEvent();

	/**
	 * The new round event is emitted when the player wants to start a new round
	 * 
	 * @return the event
	 */
	public IEvent getNewRoundEvent();

	/**
	 * Shows or hides the game settings panel
	 * 
	 * @param show
	 *          specifies if the panel shall be shown or hidden
	 */
	public void showSettingsPanel(boolean show);

	/**
	 * Shows or hides the score panel
	 * 
	 * @param show
	 *          specifies if the panel shall be shown or hidden
	 */
	public void showScorePanel(boolean show);

	/**
	 * Is used for the PlayerPanel and ScorePanel to display a player's color
	 * along with the name
	 * 
	 * @param color
	 *          the current player's color
	 */
	public void setCurrentPlayerColor(Color color);

	/**
	 * Is used for the PlayerPanel to display if a player has laid out along with
	 * the name
	 * 
	 * @param hasLaidOut
	 *          specifies if the current player has laid out or not
	 */
	public void setCurrentPlayerHasLaidOut(boolean hasLaidOut);

	/**
	 * Is emitted if the player wants to end the game and start a new one
	 * 
	 * @return newGameEvent
	 */
	public IEvent getNewGameEvent();

	/**
	 * Sets the bottom panels type
	 * 
	 * @param type
	 *          the type of the bottom panel
	 */
	public void setBottomPanel(BottomPanelType type);

	/**
	 * The menu new game event is emitted when the user selects the new game menu
	 * entry
	 * 
	 * @return the event
	 */
	public IEvent getMenuNewGameEvent();

	/**
	 * The load event is emitted when the user wants to load a previously saved
	 * game state
	 * 
	 * @return the event
	 */
	public IEvent getLoadEvent();

	/**
	 * The save event is emitted when the user wants to save the current game
	 * state
	 * 
	 * @return the event
	 */
	public IEvent1<File> getSaveEvent();

	/**
	 * The pause event is emitted when the user wants to pause the current turn
	 * 
	 * @return the event
	 */
	public IEvent getPauseEvent();

	/**
	 * The end pause event is emitted when the user wants to sresume the game
	 * after a pause
	 * 
	 * @return the event
	 */
	public IEvent getEndPauseEvent();

	/**
	 * Hides all view elements and panels except for the cleared table and an
	 * empty hand panel
	 */
	public void clearView();

	/**
	 * The network game event is emitted when the user chooses a network game
	 * 
	 * @return the event
	 */
	public IEvent getNetworkGameEvent();

	/**
	 * Getter for login panel
	 * 
	 * @return login panel
	 */
	public ILoginPanel getLoginPanel();

	/**
	 * Getter for game list panel
	 * 
	 * @return game list panel
	 */
	public IGameListPanel getGameListPanel();

	/**
	 * Show/hide login panel
	 * 
	 * @param show
	 *          true = login panel is shown
	 */
	public void showLoginPanel(boolean show);

	/**
	 * Clears user input of the resetLoginPanel
	 */
	public void resetLoginPanel();

	/**
	 * Enable/disable pause mode
	 * 
	 * @param enable
	 *          true = enable
	 */
	public void enablePauseMode(boolean enable);

	/**
	 * Show/hide game list panel
	 * 
	 * @param show
	 *          true = show
	 */
	public void showGameListPanel(boolean show);

	/**
	 * Show/hide side panel
	 * 
	 * @param show
	 *          true to show
	 */
	void showSidePanel(boolean show);

	/**
	 * Is set if a player tried to lay out less than initial meld threshold
	 * 
	 * @param points
	 *          initial meld threshold
	 */
	public void setInitialMeldError(int points);

	/**
	 * Show stone collection
	 * 
	 * @param enable
	 *          showing collection
	 */
	public void setStoneCollectionHidden(boolean enable);

	/**
	 * Is set if the player tried to modify the table without laying out first
	 */
	public void setInitialMeldFirstError();

	/**
	 * Set invalid sets to enable showing
	 * 
	 * @param sets
	 *          invalid sets on table
	 */
	public void setInvalidStoneSets(Collection<StoneSet> sets);

	/**
	 * Show when loading is unsuccessful
	 */
	public void showLoadingError();

	/**
	 * Show an error message when the server couldn't be started
	 * 
	 * @param alreadyRunning
	 *          true when the server is already running on this machine
	 */
	public void showServerStartupError(boolean alreadyRunning);

	/**
	 * Enables/disables saving in menu bar
	 * 
	 * @param enable
	 *          saving possible
	 */
	public void enableSave(boolean enable);

	/**
	 * Sets the quit warning panel visible
	 * 
	 * @param show
	 *          is visible
	 */
	public void showQuitWarningPanel(boolean show);

	/**
	 * The quit event is emitted when the user wants to leave the application
	 * 
	 * @return the event
	 */
	public IEvent getQuitEvent();

	/**
	 * Getter for quit warning panel
	 * 
	 * @return the panel
	 */
	public IQuitWarningPanel getQuitWarningPanel();

	/**
	 * The load file event is emitted when the user chose to discard the current
	 * game to save another
	 * 
	 * @return the event
	 */
	public IEvent1<File> getLoadFileEvent();

	/**
	 * Loading a game
	 */
	public void load();

	/**
	 * Set the connect panel visible
	 * 
	 * @param show
	 *          is visible
	 */
	public void showConnectPanel(boolean show);

	/**
	 * Getter for connect panel
	 * 
	 * @return the panel
	 */
	public IConnectPanel getConnectPanel();

	/**
	 * Sets the pause button if pausing should be possible in the current
	 * situation
	 * 
	 * @param mayPause
	 *          pausing possible
	 */
	public void setMayPause(boolean mayPause);

	/**
	 * Different types of bottom panels
	 */
	public enum BottomPanelType {
		/**
		 * The start game panel is displayed at the start of the program and
		 * contains some Bling
		 */
		START_GAME_PANEL,
		/**
		 * The start turn panel is used to separate the players' turns from each
		 * other in hotseat mode
		 */
		START_TURN_PANEL,
		/**
		 * The start redeal turn panel is displayed at the beginning of the players'
		 * turns after a player has redealt
		 */
		START_REDEAL_TURN_PANEL,
		/**
		 * The start redeal turn panel is displayed at the beginning of the players'
		 * turns after a player has drawn the last stone
		 */
		START_LAST_TURN_PANEL,
		/**
		 * The invalid turn panel is displayed when a player is shown what invalid
		 * sets he has layed out
		 */
		INVALID_TURN_PANEL,
		/**
		 * The human hand panel shows a human player's stones
		 * */
		HUMAN_HAND_PANEL,
		/**
		 * The non-human hand panel looks like a human hand panel, but it is
		 * darkened and no stones are displayed
		 */
		NONHUMAN_HAND_PANEL,
		/**
		 * The win panel is displayed when a player has won the game and can choose
		 * between starting a new round, going back to the game setup or quitting
		 * the program
		 **/
		WIN_PANEL,
		/**
		 * The win panel is displayed to a non-host network user when a player has
		 * won the game. He can choose between waiting for the host to start a new
		 * round or ending the game by going back to the game list or quitting the
		 * program
		 **/
		NETWORK_WIN_PANEL,
		/**
		 * The network connection lost panel is displayed when a user that was
		 * participating in the current game has disappeared
		 **/
		NETWORK_CONNECTION_LOST_PANEL,
		/**
		 * The network server connection lost panel is displayed when the connection
		 * to the XMPP server is lost
		 **/
		NETWORK_SERVER_CONNECTION_LOST_PANEL
	}
}
