/**
   * Accepted requests are: {@link JoinGameRequest}, {@link CreateGameRequest}, {@link
   * UpdateAvailableGameListRequest}, In case of any other type of request client will be
   * disconnected.
   */
  @Override
  public void onReceive(ProMaSiClient client, String recData) {
    try {
      Object object = new XMLDecoder(new ByteArrayInputStream(recData.getBytes())).readObject();
      if (object instanceof JoinGameRequest) {
        try {
          _logger.info("Received message :'" + JoinGameRequest.class.toString() + "'");
          JoinGameRequest request = (JoinGameRequest) object;
          MultiPlayerGame game;
          game = _server.joinGame(_clientId, request.getGameId());

          JoinGameResponse response =
              new JoinGameResponse(
                  game.getGameName(), game.getGameDescription(), game.getGamePlayers());
          client.removeListener(this);
          client.addListener(
              new WaitingGameClientState(_clientId, _server, client, request.getGameId(), game));
          client.sendMessage(response);
        } catch (IllegalArgumentException e) {
          client.sendMessage(new JoinGameFailedResponse());
        }

      } else if (object instanceof CreateGameRequest) {
        _logger.info("Received message :'" + CreateGameRequest.class.toString() + "'");
        CreateGameRequest request = (CreateGameRequest) object;
        GameModelMemento gameModel = request.getGameModel();
        if (gameModel == null) {
          _logger.warn("Invalid message detected gameModel == null, client will be disconnected");
          client.sendMessage(new WrongProtocolResponse());
          client.disconnect();
          return;
        }

        MarketPlaceMemento marketPlace = gameModel.getMarketPlace();
        if (marketPlace == null) {
          _logger.warn("Invalid message detected marketPlace == null, client will be disconnected");
          client.sendMessage(new WrongProtocolResponse());
          client.disconnect();
        }

        CompanyMemento company = gameModel.getCompany();
        if (company == null) {
          _logger.warn("Invalid message detected company == null, client will be disconnected");
          client.sendMessage(new WrongProtocolResponse());
          client.disconnect();
        }

        Queue<ProjectMemento> sProjects = gameModel.getProjects();
        if (sProjects == null) {
          _logger.warn("Invalid message detected projects == null, client will be disconnected");
          client.sendMessage(new WrongProtocolResponse());
          client.disconnect();
        }

        Queue<Project> projects = new LinkedList<Project>();
        for (ProjectMemento currentProject : sProjects) {
          projects.add(currentProject.getProject());
        }

        MultiPlayerGame game =
            new MultiPlayerGame(
                _clientId,
                request.getGameId(),
                gameModel.getGameDescription(),
                marketPlace.getMarketPlace(),
                company.getCompany(),
                projects);

        if (_server.createGame(request.getGameId(), game)) {
          CreateGameResponse response =
              new CreateGameResponse(
                  request.getGameId(), gameModel.getGameDescription(), game.getGamePlayers());
          client.sendMessage(response);
          client.removeListener(this);
          client.addListener(
              new WaitingPlayersClientState(_clientId, request.getGameId(), client, game, _server));
        } else {
          _logger.warn("Create game failed");
        }
      } else if (object instanceof UpdateAvailableGameListRequest) {
        _logger.info("Received message :'" + UpdateAvailableGameListRequest.class.toString() + "'");
        UpdateGameListRequest request = new UpdateGameListRequest(_server.getAvailableGames());
        client.sendMessage(request);
      } else {
        _logger.warn("Received an invalid message type '" + object.toString() + "'");
        client.sendMessage(new WrongProtocolResponse());
        client.disconnect();
      }
    } catch (Exception e) {
      _logger.warn("Internal error client will be disconnected");
      client.sendMessage(new InternalErrorResponse());
      client.disconnect();
    }
  }