package jrummikub.control.network; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import jrummikub.control.SaveControl; import jrummikub.model.GameSettings; import jrummikub.util.Connection; import jrummikub.util.Event; import jrummikub.util.GameData; import jrummikub.util.IEvent; import jrummikub.util.IListener; import jrummikub.util.IListener1; import jrummikub.util.LoginData; import jrummikub.view.IView; import jrummikub.view.IView.BottomPanelType; import jrummikub.view.LoginError; /** * Class dealing with network connection, offering and choice of network games */ public class NetworkControl { private IConnectionControl connectionControl; private IView view; private List connections = new ArrayList(); private Event stopNetworkEvent = new Event(); private Event backToLoginEvent = new Event(); private NetworkSettingsControl settingsControl; private GameOfferControl gameOfferControl; private GameJoinControl gameJoinControl; private SaveControl saveControl; private NetworkGameControl gameControl; private List games = new ArrayList(); private Map gameMap = new HashMap(); /** * Creates a new network control * * @param loginData * user's login data * @param connectionControl * current connection for events and messages * @param saveControl * save control if saving will ever be allowed * @param view * for events and handlers */ public NetworkControl(final LoginData loginData, IConnectionControl connectionControl, SaveControl saveControl, final IView view) { this.view = view; this.connectionControl = connectionControl; this.saveControl = saveControl; addConnectionSetupListeners(loginData); addConnectionControlListeners(); addViewEventListeners(); } private void addViewEventListeners() { connections.add(view.getGameListPanel().getJoinEvent() .add(new IListener1() { @Override public void handle(GameData gameData) { join(gameData); } })); connections.add(view.getGameListPanel().getOpenNewGameEvent() .add(new IListener() { @Override public void handle() { createSettingsControl(); } })); connections.add(view.getGameListPanel().getCancelEvent() .add(new IListener() { @Override public void handle() { abort(); stopNetworkEvent.emit(); } })); } private void join(GameData gameData) { view.showGameListPanel(false); connectionControl.joinGame(gameData); } /** * Adds the listeners for connection control events */ private void addConnectionControlListeners() { addOfferUpdateListener(); connections.add(connectionControl.getGameWithdrawalEvent().add( new IListener1() { @Override public void handle(UUID uuid) { games.remove(uuid); gameMap.remove(uuid); updateGameList(); } })); connections.add(connectionControl.getGameJoinAckEvent().add( new IListener1() { @Override public void handle(Boolean ack) { if (ack) { createGameJoinControl(); } else { view.showGameListPanel(true); } } })); addConnectionLostListeners(); } /** * Adds the listeners for lost connection events */ private void addConnectionLostListeners() { connections.add(connectionControl.getParticipantLeftEvent().add( new IListener1() { @Override public void handle(String nickname) { for (Map.Entry entry : gameMap.entrySet()) { if (entry.getValue().getHost().equals(nickname)) { games.remove(entry.getKey()); gameMap.remove(entry.getKey()); break; } } updateGameList(); } })); connections.add(connectionControl.getConnectionLostEvent().add( new IListener() { @Override public void handle() { abort(); view.setBottomPanel(BottomPanelType.NETWORK_SERVER_CONNECTION_LOST_PANEL); connections.add(view.getAcknowledgeConnectionLostEvent().add( new IListener() { @Override public void handle() { abort(); view.setBottomPanel(BottomPanelType.START_GAME_PANEL); backToLoginEvent.emit(); } })); } })); } private void addOfferUpdateListener() { connections.add(connectionControl.getGameOfferEvent().add( new IListener1() { @Override public void handle(GameData gameData) { UUID uuid = gameData.getGameID(); GameData game = gameMap.get(uuid); if (game == null) { game = gameData; gameMap.put(uuid, gameData); games.add(uuid); } else { game.setGameSettings(gameData.getGameSettings()); } updateGameList(); } })); } private void addConnectionSetupListeners(final LoginData loginData) { connections.add(connectionControl.getConnectedEvent().add(new IListener() { @Override public void handle() { view.getGameListPanel().setChannelName(loginData.getChannelName()); view.showConnectPanel(false); view.showGameListPanel(true); } })); connections.add(connectionControl.getConnectionFailedEvent().add( new IListener1() { @Override public void handle(LoginError error) { view.getConnectPanel().setMode(error); view.showConnectPanel(true); } })); connections.add(view.getConnectPanel().getCancelEvent() .add(new IListener() { @Override public void handle() { abort(); backToLoginEvent.emit(); } })); } private void updateGameList() { List gameList = new ArrayList(); for (UUID uuid : games) { gameList.add(gameMap.get(uuid)); } view.getGameListPanel().setGameList(gameList); } /** * Starts a new network connection with the specified data */ public void startNetwork() { view.showConnectPanel(true); view.getConnectPanel().setMode(null); connectionControl.connect(); } /** * Ends the network connection if canceled */ public void abort() { for (Connection c : connections) { c.remove(); } abortControls(); connectionControl.disconnect(); } private void abortControls() { if (settingsControl != null) { settingsControl.abort(); settingsControl = null; } if (gameOfferControl != null) { gameOfferControl.abort(); gameOfferControl = null; } if (gameJoinControl != null) { gameJoinControl.abort(); gameJoinControl = null; } if (gameControl != null) { gameControl.abortGame(); gameControl = null; } view.showGameListPanel(false); view.showConnectPanel(false); view.showSidePanel(false); view.setBottomPanel(BottomPanelType.START_GAME_PANEL); } /** * Getter for stopNetworkEvent * * @return stopNetworkEvent */ public IEvent getStopNetworkEvent() { return stopNetworkEvent; } /** * The back to login event is emitted when the player aborted the connecting * process or when a connection error has occured and been acknowledged * * @return the event */ public IEvent getBackToLoginEvent() { return backToLoginEvent; } private void createSettingsControl() { if (settingsControl != null) { return; } view.showGameListPanel(false); settingsControl = new NetworkSettingsControl( connectionControl.getNickname(), view, new GameSettings()); settingsControl.getOfferGameEvent().add(new IListener1() { @Override public void handle(GameSettings settings) { settingsControl = null; createGameOfferControl(settings); } }); settingsControl.getBackEvent().add(new IListener() { @Override public void handle() { settingsControl = null; view.showGameListPanel(true); } }); settingsControl.startSettings(); } private void createGameJoinControl() { if (gameJoinControl != null) { return; } GameData gameData = connectionControl.getCurrentGame(); gameJoinControl = new GameJoinControl(connectionControl, gameData, view); gameJoinControl.getBackEvent().add(new IListener() { @Override public void handle() { gameJoinControl = null; view.showGameListPanel(true); } }); gameJoinControl.getStartGameEvent().add(new IListener() { @Override public void handle() { createGameControl(null, false); } }); gameJoinControl.startGameJoin(); } private void createGameOfferControl(GameSettings settings) { if (gameOfferControl != null) { return; } gameOfferControl = new GameOfferControl(connectionControl, settings, view); gameOfferControl.getBackEvent().add(new IListener() { @Override public void handle() { gameOfferControl = null; view.showGameListPanel(true); } }); gameOfferControl.getStartGameEvent().add(new IListener1() { @Override public void handle(GameSettings settings) { createGameControl(settings, true); } }); gameOfferControl.startGameOffer(); } private void createGameControl(GameSettings settings, boolean host) { gameControl = new NetworkGameControl(settings, saveControl, view, connectionControl, host); gameControl.getBackEvent().add(new IListener() { @Override public void handle() { view.setBottomPanel(BottomPanelType.START_GAME_PANEL); abortControls(); view.showGameListPanel(true); } }); gameControl.getEndOfGameEvent().add(new IListener() { @Override public void handle() { view.setBottomPanel(BottomPanelType.START_GAME_PANEL); abortControls(); view.showGameListPanel(true); } }); gameControl.startGame(); } /** * Returns if there is a running game * * @return is there a game running */ public boolean isGameRunning() { return gameControl != null; } }