package jrummikub.control; import java.awt.Color; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import jrummikub.model.GameSettings; import jrummikub.model.PlayerSettings; import jrummikub.model.PlayerSettings.Type; import jrummikub.model.StoneColor; import jrummikub.util.Connection; import jrummikub.util.Event1; import jrummikub.util.IEvent1; import jrummikub.util.IListener; import jrummikub.util.IListener1; import jrummikub.util.IListener2; import jrummikub.view.ISettingsPanel; import jrummikub.view.IView; /** * The settings control controls the settings panel */ public class SettingsControl { protected IView view; protected Event1 startGameEvent = new Event1(); private List connections = new ArrayList(); protected GameSettings settings; /** * Create a new settings control * * @param view * the view to use * @param settings * initial game settings */ public SettingsControl(IView view, GameSettings settings) { this.view = view; this.settings = settings; view.getSettingsPanel().enableNetworkMode(false); } /** * 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 getStartGameEvent() { return startGameEvent; } /** * Start the operation of the settings control */ public void startSettings() { addPlayer(); addPlayer(); addPlayerSettingsListeners(); addOptionListeners1(); addOptionListeners2(); connections.add(view.getSettingsPanel().getStartGameEvent() .add(new IListener() { @Override public void handle() { startGame(); } })); view.showSettingsPanel(true); } private void addOptionListeners1() { connections.add(view.getSettingsPanel() .getChangeInitialMeldThresholdEvent() .add(new IListener1() { @Override public void handle(Integer value) { settings.setInitialMeldThreshold(value); update(); } })); connections.add(view.getSettingsPanel().getChangeJokerNumberEvent() .add(new IListener1() { @Override public void handle(Integer value) { settings.setJokerNumber(value); update(); } })); connections.add(view.getSettingsPanel().getChangeStoneSetNumberEvent() .add(new IListener1() { @Override public void handle(Integer value) { settings.setStoneSetNumber(value); update(); } })); connections.add(view.getSettingsPanel() .getChangeNumberOfStonesDealtEvent() .add(new IListener1() { @Override public void handle(Integer value) { settings.setNumberOfStonesDealt(value); update(); } })); } private void addOptionListeners2() { connections.add(view.getSettingsPanel().getChangeHighestValueEvent() .add(new IListener1() { @Override public void handle(Integer value) { settings.setHighestValue(value); update(); } })); connections.add(view.getSettingsPanel().getChangeTimeEvent() .add(new IListener1() { @Override public void handle(Integer value) { settings.setTotalTime(value); update(); } })); connections.add(view.getSettingsPanel().getChangeStoneColorsEvent() .add(new IListener1>() { @Override public void handle(Set value) { settings.setStoneColors(new HashSet(value)); update(); } })); connections.add(view.getSettingsPanel().getChangeNoLimitsEvent() .add(new IListener1() { @Override public void handle(Boolean value) { settings.setNoLimits(value); update(); } })); addVariantListeners(); } /** * Add event listeners for variants, e.g. standard or children */ public void addVariantListeners() { connections.add(view.getSettingsPanel().getSetVariantDefaultEvent() .add(new IListener() { @Override public void handle() { settings.reset(); update(); } })); connections.add(view.getSettingsPanel().getSetVariantChildrenEvent() .add(new IListener() { @Override public void handle() { settings.reset(); settings.setHighestValue(10); settings.setJokerNumber(6); settings.setTotalTime(120); settings.setInitialMeldThreshold(20); update(); } })); } private void addPlayerSettingsListeners() { connections.add(view.getSettingsPanel().getAddPlayerEvent() .add(new IListener() { @Override public void handle() { addPlayer(); } })); connections.add(view.getSettingsPanel().getRemovePlayerEvent() .add(new IListener1() { @Override public void handle(Integer i) { removePlayer(i); } })); connections.add(view.getSettingsPanel().getChangePlayerColorEvent() .add(new IListener2() { @Override public void handle(Integer i, Color color) { setPlayerColor(i, color); } })); connections.add(view.getSettingsPanel().getChangePlayerNameEvent() .add(new IListener2() { @Override public void handle(Integer i, String name) { setPlayerName(i, name); } })); connections.add(view.getSettingsPanel().getChangePlayerTypeEvent() .add(new IListener2() { @Override public void handle(Integer i, Type type) { setPlayerType(i, type); } })); } private 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; } // Next, find unused color Color color = null; colorLoop: for (Color c : ISettingsPanel.PLAYER_COLORS) { color = c; for (PlayerSettings player : settings.getPlayerList()) { if (c == player.getColor()) { continue colorLoop; } } break; } settings.getPlayerList().add( new PlayerSettings("Spieler " + num, color)); update(); } private void removePlayer(int i) { settings.getPlayerList().remove(i); update(); } private void setPlayerColor(int i, Color color) { PlayerSettings player = settings.getPlayerList().get(i); if (player.getColor() == color) { return; } for (PlayerSettings other : settings.getPlayerList()) { if (other.getColor() == color) { other.setColor(player.getColor()); break; } } player.setColor(color); update(); } private void setPlayerName(int i, String name) { settings.getPlayerList().get(i).setName(name); update(); } private void setPlayerType(int i, Type type) { settings.getPlayerList().get(i).setTurnControlType(type); update(); } protected void update() { view.getSettingsPanel().enableRemovePlayerButtons( settings.getPlayerList().size() > 2); view.getSettingsPanel() .enableAddPlayerButton( settings.getPlayerList().size() < ISettingsPanel.PLAYER_COLORS.length); checkSettings(); view.getSettingsPanel().setGameSettings(settings); } private boolean checkSettings() { if (!checkErrors()) { return false; } view.getSettingsPanel().setError(ISettingsPanel.SettingsError.NO_ERROR); view.getSettingsPanel().enableStartGameButton(true); checkWarnings(); return true; } private boolean checkErrors() { for (PlayerSettings player : settings.getPlayerList()) { if (player.getName().isEmpty()) { view.getSettingsPanel().setError( ISettingsPanel.SettingsError.NO_PLAYER_NAME_ERROR); view.getSettingsPanel().enableStartGameButton(false); return false; } } for (int i = 0; i < settings.getPlayerList().size(); ++i) { String name = settings.getPlayerList().get(i).getName(); for (int j = i + 1; j < settings.getPlayerList().size(); ++j) { if (settings.getPlayerList().get(j).getName().equals(name)) { view.getSettingsPanel() .setError( ISettingsPanel.SettingsError.DUPLICATE_PLAYER_NAME_ERROR); view.getSettingsPanel().enableStartGameButton(false); return false; } } } int totalStonesDealt = settings.getNumberOfStonesDealt() * settings.getPlayerList().size(); int totalStones = settings.getHighestValue() * settings.getStoneSetNumber() * settings.getStoneColors().size() + settings.getJokerNumber(); if (totalStones <= totalStonesDealt) { view.getSettingsPanel().setError( ISettingsPanel.SettingsError.NOT_ENOUGH_STONES_ERROR); view.getSettingsPanel().enableStartGameButton(false); return false; } if (settings.getStoneColors().size() < 3) { view.getSettingsPanel().setError( ISettingsPanel.SettingsError.NOT_ENOUGH_COLORS_ERROR); view.getSettingsPanel().enableStartGameButton(false); return false; } return true; } private void checkWarnings() { if (settings.getInitialMeldThreshold() >= 100) { view.getSettingsPanel().setError( ISettingsPanel.SettingsError.TOO_HIGH_THRESHOLD_WARNING); return; } boolean humanPlayerFound = false; for (PlayerSettings player : settings.getPlayerList()) { if (player.getTurnControlType() == Type.HUMAN) { humanPlayerFound = true; break; } } if (!humanPlayerFound) { view.getSettingsPanel().setError( ISettingsPanel.SettingsError.COMPUTER_PLAYERS_ONLY_WARNING); return; } } private void startGame() { if (!checkSettings()) { return; } abort(); startGameEvent.emit(settings); } /** * Abort settings control once settings are set */ public void abort() { view.showSettingsPanel(false); for (Connection c : connections) { c.remove(); } } }