package jrummikub.control;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import jrummikub.model.GameSettings;
import jrummikub.model.PlayerSettings;
import jrummikub.model.PlayerSettings.Type;
import jrummikub.util.Event1;
import jrummikub.util.IEvent1;
import jrummikub.util.IListener;
import jrummikub.view.ISettingsPanel;
import jrummikub.view.ISettingsPanel.SettingsMode;
import jrummikub.view.IView;

/**
 * The settings control controls the settings panel
 */
public class SettingsControl extends AbstractSettingsControl {
	private Event1<GameSettings> startGameEvent = new Event1<GameSettings>();

	/**
	 * Create a new settings control
	 * 
	 * @param view
	 *            the view to use
	 * @param settings
	 *            initial game settings
	 */
	public SettingsControl(IView view, GameSettings settings) {
		super(view, settings);
		view.getSettingsPanel().setSettingsMode(SettingsMode.DEFAULT);

		addPlayer();
		addPlayer();

		addListeners();

		connections.add(view.getSettingsPanel().getStartGameEvent()
				.add(new IListener() {
					@Override
					public void handle() {
						startGame();
					}
				}));
	}

	/**
	 * the start game event is emitted when the user wants to start a game and
	 * the settings made are valid
	 * 
	 * @return the event
	 */
	public IEvent1<GameSettings> getStartGameEvent() {
		return startGameEvent;
	}

	@Override
	protected void addPlayer() {
		if (settings.getPlayerList().size() >= ISettingsPanel.PLAYER_COLORS.length) {
			return;
		}

		// Find unused player name
		int num = settings.getPlayerList().size();

		nameLoop: while (true) {
			num++;
			String playerName = "Spieler " + num;

			for (PlayerSettings player : settings.getPlayerList()) {
				if (playerName.equals(player.getName())) {
					continue nameLoop;
				}
			}
			break;
		}

		settings.getPlayerList().add(
				new PlayerSettings("Spieler " + num, findUnusedColor()));

		update();
	}

	@Override
	protected void setPlayerType(int i, Type type) {
		settings.getPlayerList().get(i).setType(type);
		update();
	}

	@Override
	protected void update() {
		boolean enableRemoveButtons = settings.getPlayerList().size() > 2;
		view.getSettingsPanel().enableRemovePlayerButtons(
				Collections.nCopies(settings.getPlayerList().size(),
						enableRemoveButtons));
		view.getSettingsPanel()
				.enableAddPlayerButton(
						settings.getPlayerList().size() < ISettingsPanel.PLAYER_COLORS.length);

		checkSettings();

		List<List<Type>> choices = new ArrayList<List<Type>>();
		for (int i = 0; i < settings.getPlayerList().size(); i++) {
			choices.add(Arrays.asList(Type.HUMAN, Type.COMPUTER));
		}
		view.getSettingsPanel().setPlayerTypeChoices(choices);
		view.getSettingsPanel().setGameSettings(settings);
	}

	/**
	 * Aborts the settings control and emits a start game event if settings have
	 * been approved
	 */
	private void startGame() {
		if (!checkSettings()) {
			return;
		}

		abort();
		startGameEvent.emit(settings);
	}
}
