package jrummikub.control; import jrummikub.control.network.ConnectionControl; import jrummikub.control.network.NetworkControl; import jrummikub.model.GameSettings; import jrummikub.model.GameState; import jrummikub.model.IRoundState; import jrummikub.server.DedicatedServer; import jrummikub.server.DedicatedServer.ServerStatus; import jrummikub.util.Connection; import jrummikub.util.IListener; import jrummikub.util.IListener1; import jrummikub.util.IListener3; import jrummikub.util.LoginData; import jrummikub.view.IQuitWarningPanel.QuitMode; import jrummikub.view.IView; import jrummikub.view.IView.BottomPanelType; /** * The application control controls the settings for a new games and create the * game control */ public class ApplicationControl { private SettingsControl settingsControl; private LoginControl loginControl; private NetworkControl networkControl; private SaveControl saveControl; private GameControl gameControl; private Connection tempConnection; private DedicatedServer server; private IView view; /** * Creates a new application control * * @param view * the view to use */ public ApplicationControl(final IView view) { this.view = view; saveControl = new SaveControl(view); addQuitGameHandlers(); addSaveLoadHandlers(); addNewNetworkGameHandler(); saveControl.getLoadEvent().add( new IListener3() { @Override public void handle(GameSettings settings, GameState gameState, IRoundState roundState) { abortControls(); gameControl = new GameControl(settings, saveControl, view); addGameControlListeners(gameControl); gameControl.continueGame(gameState, roundState); } }); saveControl.getLoadErrorEvent().add(new IListener() { @Override public void handle() { view.showLoadingError(); } }); } private void addSaveLoadHandlers() { view.getLoadEvent().add(new IListener() { @Override public void handle() { if (!isGameRunning()) { abortControls(); startApplication(); view.load(); return; } view.getQuitWarningPanel().setMode(QuitMode.QUIT_GAME); view.showQuitWarningPanel(true); tempConnection = view.getQuitWarningPanel().getQuitEvent() .add(new IListener() { @Override public void handle() { abortControls(); startApplication(); view.showQuitWarningPanel(false); view.load(); tempConnection.remove(); } }); } }); } private void addNewNetworkGameHandler() { view.getNetworkGameEvent().add(new IListener() { @Override public void handle() { if (!isGameRunning()) { abortControls(); createLoginControl(true); } else { view.getQuitWarningPanel().setMode(QuitMode.QUIT_GAME); view.showQuitWarningPanel(true); tempConnection = view.getQuitWarningPanel().getQuitEvent() .add(new IListener() { @Override public void handle() { view.showQuitWarningPanel(false); abortControls(); createLoginControl(true); tempConnection.remove(); tempConnection = null; } }); } } }); } private void addQuitGameHandlers() { view.getMenuNewGameEvent().add(new IListener() { @Override public void handle() { showRestartWarning(); } }); view.getQuitEvent().add(new IListener() { @Override public void handle() { if (!isGameRunning()) { System.exit(0); } else { showQuitWarning(); } } }); view.getQuitWarningPanel().getCancelEvent().add(new IListener() { @Override public void handle() { view.showQuitWarningPanel(false); if (tempConnection != null) { tempConnection.remove(); tempConnection = null; } } }); } private void showRestartWarning() { view.getQuitWarningPanel().setMode(QuitMode.QUIT_GAME); view.showQuitWarningPanel(true); tempConnection = view.getQuitWarningPanel().getQuitEvent() .add(new IListener() { @Override public void handle() { abortControls(); startApplication(); view.showQuitWarningPanel(false); tempConnection.remove(); tempConnection = null; } }); } private void showQuitWarning() { view.getQuitWarningPanel().setMode(QuitMode.QUIT_PROCESS); view.showQuitWarningPanel(true); tempConnection = view.getQuitWarningPanel().getQuitEvent() .add(new IListener() { @Override public void handle() { System.exit(0); } }); } /** * Checks if a game is currently running * @return true when a game is running */ public boolean isGameRunning() { return gameControl != null || networkControl != null && networkControl.isGameRunning(); } /** * Create a new network login control */ private void createLoginControl(boolean reset) { loginControl = new LoginControl(view, this); loginControl.getLoginEvent().add(new IListener1() { @Override public void handle(LoginData loginData) { createNetworkControl(loginData); } }); loginControl.getCancelEvent().add(new IListener() { @Override public void handle() { startApplication(); } }); loginControl.startLogin(reset); } /** * End all controls in case of e.g. quit event */ private void abortControls() { if (settingsControl != null) { settingsControl.abort(); settingsControl = null; } if (gameControl != null) { gameControl.abortGame(); gameControl = null; } if (loginControl != null) { loginControl.abort(); loginControl = null; } if (networkControl != null) { networkControl.abort(); networkControl = null; } view.showSidePanel(false); view.showScorePanel(false); view.setBottomPanel(BottomPanelType.START_GAME_PANEL); } /** * Starts the application by showing the game settings dialog panel */ public void startApplication() { view.showSidePanel(false); view.showScorePanel(false); view.setBottomPanel(BottomPanelType.START_GAME_PANEL); saveControl.setGameSettings(null); saveControl.setGameState(null); settingsControl = new SettingsControl(view, new GameSettings()); view.enableSave(false); settingsControl.getStartGameEvent().add(new IListener1() { @Override public void handle(GameSettings settings) { view.enableSave(true); settingsControl = null; saveControl.setGameSettings(settings); gameControl = new GameControl(settings, saveControl, view); addGameControlListeners(gameControl); gameControl.startGame(); } }); settingsControl.startSettings(); } /** * Adds events listeners to game control events * * @param gameControl * of current game */ private void addGameControlListeners(GameControl gameControl) { gameControl.getEndOfGameEvent().add(new IListener() { @Override public void handle() { startApplication(); } }); } /** * Create a new network game control * * @param loginData * users login data for channel */ private void createNetworkControl(LoginData loginData) { ConnectionControl connectionControl = new ConnectionControl(loginData); networkControl = new NetworkControl(loginData, connectionControl, saveControl, view); networkControl.getStopNetworkEvent().add(new IListener() { @Override public void handle() { startApplication(); } }); networkControl.getBackToLoginEvent().add(new IListener() { @Override public void handle() { networkControl = null; createLoginControl(false); } }); networkControl.startNetwork(); } /** * Ensure the dedicated server is running * * @param password * password to use, if empty "jrummikub" is used * @return whether the server could be started */ public boolean startDedicatedServer(String password) { if (server == null) { DedicatedServer newServer = new DedicatedServer(password); ServerStatus status = newServer.start(); switch (status) { case STARTED: server = newServer; break; case ALREADY_RUNNING: view.showServerStartupError(true); return false; case ERROR: view.showServerStartupError(false); return false; } } server.setServerPassword(password); view.getLoginPanel().setServer(server.getHostName()); view.getLoginPanel().setChannel( "jrummikub@play." + server.getHostName()); view.getLoginPanel().setDedicatedServerRunning(true); return true; } /** * If the login given is to our own dedicated server, update it's password * to match * * @param loginData * login data of user trying to connect */ public void updateDedicatedServerPassword(LoginData loginData) { if (server != null && server.getHostName() == loginData.getServerName()) { server.setServerPassword(loginData.getPassword()); } } }