@Override
  public void notifyClientOfTimeLeft(int playerID, int timeLeft) {
    RaceTrackMessage answer = new TimeLeftMessage(timeLeft);

    answer.addClientID(playerID);
    sendMessage(answer);
  }
  @Override
  public void playerDisconnects(int playerToDisconnect) {

    int playerToDisconnectPosition = -1;

    if (getPlayerMap().get(playerToDisconnect) != null) {

      int session = getPlayerMap().get(playerToDisconnect).getSessionID();

      if (lobbyMap.get(session) != null) {
        playerToDisconnectPosition =
            lobbyMap.get(session).getGroupPositionByClientID(playerToDisconnect);

        List<Integer> playersInSameSession = getPlayerIdsInSameSession(playerToDisconnect);

        if (session != NO_LOBBY_ID) {

          lobbyMap.get(session).deletePlayer(getPlayerMap().get(playerToDisconnect));

          if (moveTimerMap.get(session) != null && lobbyMap.get(session) != null) {
            int currentPlayer =
                getPlayerIDByGroupPosition(lobbyMap.get(session).getNextPlayer(), session);
            if (moveTimerMap.get(session).getPlayer() == currentPlayer) {

              moveTimerMap.get(session).setFinished(true);

              if (lobbyMap.get(session).isGameRunning()) {
                moveTimerMap.put(
                    session,
                    new MoveTimer(currentPlayer, this, lobbyMap.get(session).getCurrentPlayMode()));
              }
            }
          }

          if (!lobbyMap.get(session).isGameRunning()) {
            ILobbyInformation info = lobbyMap.get(session).generateLobbyInformation();

            RaceTrackMessage answer = new SendOptionsMessage(info);
            for (Integer i : playersInSameSession) answer.addClientID(i);
            sendMessage(answer);
          }
        }
        getPlayerMap().remove(playerToDisconnect);

        controller.disconnectPlayerFromServer(playerToDisconnect);

        RaceTrackMessage playerDisconnectsMessage =
            generateDisconnectMessage(playerToDisconnectPosition, session, playersInSameSession);

        sendMessage(playerDisconnectsMessage);

        sendWinnerMessage(playerDisconnectsMessage);
      }
    }
    return;
  }
  /**
   * generates a message object beeing sent to every client in a specific session informing them,
   * that one player disconnects
   *
   * @param playerToDisconnect the player which disconnected
   * @param session the session in which the player dropped
   * @return RaceTrackMessage containing information about the disconnected player, and the next
   *     player to move
   */
  private RaceTrackMessage generateDisconnectMessage(
      int playerToDisconnect, int session, List<Integer> playersInSameSession) {
    RaceTrackMessage answer = null;
    DebugOutputHandler.printDebug(
        "Player: " + playerToDisconnect + " disconnected, sending now a message to each client");

    if (session != NO_LOBBY_ID && lobbyMap.get(session) != null) {
      //			lobbyMap.get(session).playerDisconnected(playerToDisconnect);
      int nextPlayer = lobbyMap.get(session).getNextPlayer();
      answer = new DisconnectMessage(playerToDisconnect, nextPlayer);

      for (int i : playersInSameSession) {
        answer.addClientID(i);
      }
    }

    return answer;
  }
  /**
   * Sets a client to a random starting position from the current map and informs the other players
   * about that move
   *
   * @param playerID
   * @param sessionID
   */
  private void setRandomStartingPoint(int playerID, int sessionID) {

    List<Integer> playersInSameSession = null;

    if (getPlayerIdsInSameSession(playerID) != null) {
      playersInSameSession = getPlayerIdsInSameSession(playerID);
    }

    Player player = getPlayerMap().get(playerID);

    if (player.hasCrashed() || !player.isParticipating()) {
      return;
    }

    int trackID = lobbyMap.get(sessionID).getTrackId();

    Point2D randomStartingPoint = null;

    do {

      randomStartingPoint = TrackFactory.getRandomStartingPoint(trackID);

    } while (!checkValidityOfClientMove(playerID, randomStartingPoint));

    lobbyMap.get(sessionID).getCollisionPointFromGame(player, randomStartingPoint);

    startNextRoundByPlayerID(playerID);

    int round = getPlayerRoundByPlayerID(playerID);

    int playerWhoMoved = getGroupPositionByPlayerID(playerID);

    int nextPlayerToMove = getNextPlayerToMove(playerID);

    RaceTrackMessage answer =
        VectorMessageServerHandler.generateBroadcastMoveMessage(
            playerWhoMoved, randomStartingPoint, null, nextPlayerToMove, new Point2D(0, 0), round);

    for (int p : playersInSameSession) answer.addClientID(p);

    sendMessage(answer);
  }
  @Override
  public void moveClientDefaultVelocity(int playerID) {
    RaceTrackMessage answer = null;

    int sessionID = getSessionFromClient(playerID);

    // Move player and get collisionpoint if there was one
    if (lobbyMap.get(sessionID) != null
        && sessionID != NO_LOBBY_ID
        && getPlayerMap().get(playerID) != null) {

      if (lobbyMap.get(sessionID).isFirstRound()) {
        setRandomStartingPoint(playerID, sessionID);
        return;
      }

      List<Integer> playersInSameSession = null;

      if (getPlayerIdsInSameSession(playerID) != null) {
        playersInSameSession = getPlayerIdsInSameSession(playerID);
      }

      int playerWhoMoved = getGroupPositionByPlayerID(playerID);

      Player player = getPlayerMap().get(playerID);

      if (player.hasCrashed() || !player.isParticipating()) {
        return;
      }

      Point2D collisionPointFromPlayer = lobbyMap.get(sessionID).makeDefaultMoveForPlayer(player);

      Point2D playerPosition = player.getCurrentPosition();

      startNextRoundByPlayerID(playerID);

      int nextPlayerToMove = getNextPlayerToMove(playerID);

      int playerWhoWon = getPlayerWhoWonByPlayerID(playerID);

      boolean didAPlayerWin = playerWhoWon != -1;

      int round = getPlayerRoundByPlayerID(playerID);

      Point2D playerVelocity = getCurrentPlayerVelocityByPlayerID(playerID);

      if (didAPlayerWin) {
        DebugOutputHandler.printDebug("Player " + playerWhoWon + " did win the game.");

        answer =
            VectorMessageServerHandler.generatePlayerWonMessage(
                playerWhoMoved, playerWhoWon, playerPosition);
        closeGameByPlayerID(playerID);

      } else {
        answer =
            VectorMessageServerHandler.generateBroadcastMoveMessage(
                playerWhoMoved,
                playerPosition,
                collisionPointFromPlayer,
                nextPlayerToMove,
                playerVelocity,
                round);
      }

      for (int p : playersInSameSession) answer.addClientID(p);
      // method on lobby and game which just moves the player by his velocity again! not just by a
      // specific point
    }

    sendMessage(answer);
  }