/**
   * Method that calculates the enemies movement speed and direction
   *
   * <p>The speed is calculated by finding out time left and number of steps left. This is dynamic
   * since enemies tend to get killed.
   */
  private void moveEnemies() {
    if (enemies.isEmpty()) return;

    long current_time = System.currentTimeMillis() - startTime;

    if (animationFrame > numberOfAnimationUnits) {
      if (current_time > lastEnemyUpdate + enemyPauseTime) animationFrame = 1;
      return;
    }

    int width = currentLevel.getEnemyWidth();
    int height = currentLevel.getEnemyHeight();

    if (animationFrame == 1) {
      boolean goDown = false;
      int jumpGoal = width;
      calculationTime = current_time;
      if (enemies.get(0).goingRight) {
        if (EnemyHandler.getLargestX(enemies) > GameConstants.WINDOW_WIDTH - (width * 2)) {
          goDown = true;
          jumpGoal = height;
        }
      } else {
        if (EnemyHandler.getSmallestX(enemies) < width) {
          goDown = true;
          jumpGoal = height;
        }
      }
      for (Enemy badGuy : enemies) {
        badGuy.goingDown = goDown;
        badGuy.setJumpGoal(jumpGoal);
      }
    }

    int moveDistance = width / numberOfAnimationUnits;
    for (Enemy badGuy : enemies) {
      badGuy.move(moveDistance);
    }

    animationFrame++;
    if (animationFrame > numberOfAnimationUnits) {
      for (Enemy badGuy : enemies) {
        badGuy.goToJumpGoal();
      }

      enemyPauseTime = calculateEnemyJumpTime(current_time, current_time - calculationTime);
      lastEnemyUpdate = current_time;
      System.out.println("Pause time: " + enemyPauseTime);
      System.out.println("Run Time: " + current_time / 1000);
    }
  }
 /** Is any part of the lowest enemy ship on the players row? */
 private void calculateEnemyReachingPlayer() {
   int y = EnemyHandler.getSmallestY(enemies);
   if (y < player1.y + player1.height) {
     System.out.println("******************");
     System.out.println("Smallest Y: " + y);
     System.out.println("Player X: " + player1.x);
     System.out.println("Player Y: " + player1.y);
     gameStatus = GameConstants.GAME_STATUS_OUTRO;
   }
 }
  /**
   * Calculates the minimun number of steps left for enemies to reach player
   *
   * @return
   */
  private int calculateStepsLeft() {
    boolean goingRight = enemies.get(0).goingRight;
    int smallestX = EnemyHandler.getSmallestX(enemies);
    int largestX = EnemyHandler.getLargestX(enemies);
    int smallestY = EnemyHandler.getSmallestY(enemies);
    int width = currentLevel.getEnemyWidth();
    int height = currentLevel.getEnemyHeight();
    int stepsLeftOnRow = 0;

    if (goingRight) {
      stepsLeftOnRow = (GameConstants.WINDOW_WIDTH - (largestX + width)) / width;
    } else {
      stepsLeftOnRow = smallestX / width;
    }

    int stepsOnEachRow = (GameConstants.WINDOW_WIDTH - (largestX + width - smallestX)) / width;

    int rowsLeft = (smallestY - player1.height) / height;

    return stepsLeftOnRow + (stepsOnEachRow * rowsLeft) + rowsLeft;
  }
  /**
   * Sets (or resets) game variables And loads level data
   *
   * @param levelNo
   */
  public void loadLevel(int levelNo) {
    score = 0;
    startTime = System.currentTimeMillis();
    lastShot = -shotTime;
    lastEnemyUpdate = 0;
    projectiles = new ArrayList<>();
    animationFrame = 1;
    /*if(enemies != null)
    enemies.clear();*/
    enemies = new ArrayList<>();

    if (levelNo == 1) {
      currentLevel = new Level1Data();
      enemies = spawnPit.getEnemies(currentLevel, imageHandler);
    }

    explosions = new ArrayList<>();

    int pWidth = currentLevel.getPlayerWidth();
    int pHeight = currentLevel.getPlayerHeight();
    player1 =
        new Player(
            (GameConstants.WINDOW_WIDTH / 2) - pWidth / 2,
            10,
            pWidth,
            pHeight,
            imageHandler.getTexture(ImageConstants.PLAYER),
            imageHandler.getTexture(ImageConstants.PLAYER_LEFT),
            imageHandler.getTexture(ImageConstants.PLAYER_RIGHT));

    gameStatus = GameConstants.GAME_STATUS_INTRO;
    int smallY = EnemyHandler.getSmallestY(enemies);
    intro_enemy_offset = GameConstants.WINDOW_HEIGHT - smallY + intro_speed;
    intro_player_offset = player1.y + 1 + player1.height;

    if (enemy_hero != null) {
      enemy_hero = null;
    }
  }