/**
   * Get all cells in range of a unit.
   *
   * @param unitPosition
   * @return List of pos.
   */
  private List<Pos> cellInRangeOfAttack(Pos unitPosition) {
    Unit unit = getCellAtASpecificPos(unitPosition).getUnitOnThisCell();
    List<Pos> listOfCellInRangeOfAttack = new LinkedList<Pos>();
    List<Pos> tempList = new LinkedList<Pos>();
    int unitRange = unit.getRange();
    tempList.add(unitPosition);

    while (unitRange > 0) {
      // For every already reachable positions (in term of range), we add
      // every which are one cell further.
      for (int i = 0; i < tempList.size(); i++) {
        if (tempList.get(i).getXCoord() + 1 < this.gridWidth)
          listOfCellInRangeOfAttack.add(tempList.get(i).newPos(1, 0));
        if (tempList.get(i).getXCoord() - 1 >= 0)
          listOfCellInRangeOfAttack.add(tempList.get(i).newPos(-1, 0));
        if (tempList.get(i).getYCoord() + 1 < this.gridHeight)
          listOfCellInRangeOfAttack.add(tempList.get(i).newPos(0, 1));
        if (tempList.get(i).getYCoord() - 1 >= 0)
          listOfCellInRangeOfAttack.add(tempList.get(i).newPos(0, -1));
      }
      unitRange--;
      tempList.addAll(listOfCellInRangeOfAttack);
    }
    return listOfCellInRangeOfAttack;
  }
  /**
   * Gets all possible moves for a unit on a position.
   *
   * @param unitPosition - The Unit to use.
   * @return The list of possible moves.
   */
  private List<Pos> possiblesMoves(Pos unitPosition) {

    Unit unit = getCellAtASpecificPos(unitPosition).getUnitOnThisCell();
    List<Pos> listOfCell = new LinkedList<Pos>();
    List<Pos> tempList = new LinkedList<Pos>();
    int currentmovementPoints = unit.getMovementPoints();

    tempList.addAll(possiblesMovesAroundASpecificPosition(unitPosition));

    for (int i = unit.getMovementPoints(); i > 0; i--) {
      currentmovementPoints--;
      listOfCell.clear();
      listOfCell.addAll(tempList);
      // Before adding moves, we must check if the unit has enough
      // movement points.
      // So, if the unit has at least 1mp, it can forward 1 cell
      // further than every current moves available.
      if (currentmovementPoints > 0) {
        for (int j = 0; j < listOfCell.size(); j++) {
          // Then, for every already reachable positions, we check if
          // the unit is able to go one cell further.
          tempList.addAll(possiblesMovesAroundASpecificPosition(listOfCell.get(j)));
          // Then, we remove duplicates. (It does not perfectly work
          // but I don't know why)
          for (int index = 0; index < tempList.size(); index++) {
            for (int index2 = index + 1; index2 < tempList.size(); index2++) {
              if (tempList.get(index2).equals(tempList.get(index))) tempList.remove(index2);
            }
          }
        }
      }
    }

    listOfCell.clear();
    listOfCell.addAll(tempList);

    for (int index = 0; index < listOfCell.size(); index++) {
      for (int index2 = index + 1; index2 < listOfCell.size(); index2++) {
        if (listOfCell.get(index2).equals(listOfCell.get(index))) listOfCell.remove(index2);
      }
    }

    return listOfCell;
  }
  public boolean attackAUnit(Pos unit1Position, Pos unit2Position) {

    List<Pos> cellsInRange = new LinkedList<Pos>();
    cellsInRange = possiblesAttackCellsAroundASpecificPosition(unit1Position);
    Unit selectedUnit1 = getCellAtASpecificPos(unit1Position).getUnitOnThisCell();
    Unit selectedUnit2 = getCellAtASpecificPos(unit2Position).getUnitOnThisCell();

    for (int index = 0; index < cellsInRange.size(); index++) {
      for (int index2 = index + 1; index2 < cellsInRange.size(); index2++) {
        if (cellsInRange.get(index2).equals(cellsInRange.get(index))) cellsInRange.remove(index2);
      }
    }

    if (getCellAtASpecificPos(unit2Position).getUnitOnThisCell() != null
        && !unit1Position.equals(unit2Position)) {
      if (!cellsInRange.contains(unit2Position)) {
        return false;
      } else {
        selectedUnit2.setLife(selectedUnit2.getLife() - selectedUnit1.getAttackDamage());
        if (selectedUnit2.getLife() <= 0) {
          getCellAtASpecificPos(unit2Position)
              .getUnitOnThisCell()
              .getOwner()
              .removeOneUnitToPlayerCounter();
          getCellAtASpecificPos(unit2Position).removeUnitFromThisCell();
        }
        return true;
      }
    }
    return false;
  }
  /**
   * Upgrade a unit.
   *
   * @param unit
   * @return True if the unit is upgraded, false otherwise.
   */
  public boolean upgradeUnit(Unit unit) {
    if (unit.getType() == UnitType.BOWMAN
        && unit.getOwner().getPlayerGold() >= Bowman.BOWMAN_COST * unit.getLevel()
        && unit.getLevel() <= 5) {
      // The bowman can be upgraded 5 times.
      unit.getOwner().removeGoldToThePlayer(Bowman.BOWMAN_COST * unit.getLevel());
      unit.levelUpUnit();
      return true;
    }

    if (unit.getType() == UnitType.SOLDIER
        && unit.getOwner().getPlayerGold() >= Soldier.SOLDIER_COST * unit.getLevel()
        && unit.getLevel() <= 5) {
      // The soldier can be upgraded 5 times.
      unit.getOwner().removeGoldToThePlayer(Soldier.SOLDIER_COST * unit.getLevel());
      unit.levelUpUnit();
      return true;
    }

    if (unit.getType() == UnitType.HORSEMAN
        && unit.getOwner().getPlayerGold() >= Horseman.HORSEMAN_COST * unit.getLevel()
        && unit.getLevel() <= 5) {
      // The horseman can be upgraded 5 times.
      unit.getOwner().removeGoldToThePlayer(Horseman.HORSEMAN_COST * unit.getLevel());
      unit.levelUpUnit();
      return true;
    }

    if (unit.getType() == UnitType.COMMANDER
        && unit.getOwner().getPlayerGold() >= Commander.COMMANDER_COST * unit.getLevel()
        && unit.getLevel() <= 3) {
      // The commander can be upgraded 3times.
      unit.getOwner().removeGoldToThePlayer(Commander.COMMANDER_COST * unit.getLevel());
      unit.levelUpUnit();
      return true;
    }

    return false;
  }