package jrummikub.control; import java.awt.Color; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; 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.IListener; import jrummikub.util.IListener1; import jrummikub.util.IListener2; import jrummikub.view.ISettingsPanel; import jrummikub.view.IView; /** * Abstract control class managing joined methods and attributes of all * different (network, default...) settings controls */ public abstract class AbstractSettingsControl { protected IView view; protected List connections = new ArrayList(); protected GameSettings settings; /** * Create a new settings control * * @param view * the view to use * @param settings * initial game settings */ protected AbstractSettingsControl(IView view, GameSettings settings) { this.view = view; this.settings = settings; view.getSettingsPanel().setPlayerNamesEditable( Collections. emptyList()); view.getSettingsPanel() .setPlayerColors( new HashSet(Arrays .asList(ISettingsPanel.PLAYER_COLORS))); } /** * Add event listeners to abstract settings control */ protected void addListeners() { addPlayerSettingsListeners(); addOptionListeners1(); addOptionListeners2(); addVariantListeners(); } /** * Add event listeners to the player settings panel */ 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); } })); } /** * Add the first half of event listeners to option panel */ 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(); } })); } /** * Add the second half of event listeners to option panel */ 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(); } })); connections.add(view.getSettingsPanel().getChangeSeeHandSizeEvent() .add(new IListener1() { @Override public void handle(Boolean value) { settings.setSeeHandSize(value); update(); } })); } /** * Add event listeners for variants, e.g. standard or children */ private 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(); } })); } /** * Start the operation of the settings control */ public void startSettings() { view.showSettingsPanel(true); } /** * Finds the next unused player color * * @return an unused color */ protected Color findUnusedColor() { Color color = null; colorLoop: for (Color c : ISettingsPanel.PLAYER_COLORS) { color = c; for (PlayerSettings player : settings.getPlayerList()) { if (c == player.getColor()) { continue colorLoop; } } break; } return color; } /** * Sets a player's color * * @param i * index of player * @param color * color to be set */ 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(); } /** * Sets a player's name * * @param i * index of player * @param name * name to be set */ private void setPlayerName(int i, String name) { settings.getPlayerList().get(i).setName(name); update(); } /** * Removes a player from the planned game * * @param i * index of player */ private void removePlayer(int i) { settings.getPlayerList().remove(i); update(); } /** * Checks the settings for ambiguous or missing data and sets error/warning * if necessary * * @return boolean check correct */ protected boolean checkSettings() { if (!checkName()) { return false; } if (!checkErrors()) { return false; } view.getSettingsPanel().setError(ISettingsPanel.SettingsError.NO_ERROR); view.getSettingsPanel().enableStartGameButton(true); checkWarnings(); return true; } /** * Checks if unique player name is present for each player * * @return is player name ok */ private boolean checkName() { 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) { PlayerSettings player1 = settings.getPlayerList().get(i); String name = player1.getName(); Type type = player1.getType(); if (type == Type.VACANT) { continue; } for (int j = i + 1; j < settings.getPlayerList().size(); ++j) { PlayerSettings player2 = settings.getPlayerList().get(j); if (player2.getName().equals(name) && player2.getType() == type) { view.getSettingsPanel() .setError( ISettingsPanel.SettingsError.DUPLICATE_PLAYER_NAME_ERROR); view.getSettingsPanel().enableStartGameButton(false); return false; } } } return true; } /** * Check options leading to errors * * @return options ok */ private boolean checkErrors() { int totalStonesDealt = settings.getNumberOfStonesDealt() * settings.getPlayerList().size(); int totalStones = settings.getTotalStones(); 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; } /** * Check all options and player settings for entries causing warnings */ 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.getType() == Type.HUMAN) { humanPlayerFound = true; break; } } if (!humanPlayerFound) { view.getSettingsPanel().setError( ISettingsPanel.SettingsError.COMPUTER_PLAYERS_ONLY_WARNING); return; } } /** * Abort settings control once settings are set */ public void abort() { view.showSettingsPanel(false); for (Connection c : connections) { c.remove(); } } /** * Add new player to the planned game */ abstract protected void addPlayer(); /** * Set the type of a player * * @param i * index of player * @param type * type to be set */ abstract protected void setPlayerType(int i, Type type); /** * Show newly chosen options in view */ abstract protected void update(); }