package model;

import java.util.List;

import util.Position;

/**
 * This interface represents a generic board for modeling various state-based
 * systems.
 *
 * @param <S> The type of state represented on the board.
 */
public interface Board<S> {

  /**
   * Get the state of the board at a specific position.
   *
   * @param position The position on the board for which to retrieve the state.
   * @return The state at the specified position.
   */
  S getStates(Position position);

  /**
   * Set the state of a specific position on the board to the specified state.
   *
   * @param state    The state to set for the given position.
   * @param position The position on the board for which to set the state.
   */
  void setSquare(S square);

  /**
   * Get the number of rows in the board.
   *
   * @return The number of rows in the board.
   */
  int rowCount();

  /**
   * Get the number of columns in the board.
   *
   * @return The number of columns in the board.
   */
  int columnCount();

  /**
   * Update the board to its next generation or state. This method may modify the
   * internal state of the board and return a list of positions that have changed
   * during the update.
   *
   * @return A list of positions that have changed during the update.
   */
  List<Position> updateToNextGeneration();

  /**
   * Reset the board to its initial state.
   */
  void reset();

  /**
   * Get the current step number or generation of the board.
   *
   * @return The current step number or generation.
   */
  int stepNumber();

  public int getStepNumber();

  // Le booléen replaceState permet de forcer le remplacement des cases vides
  public void setSquare(S square, boolean replaceStates);

  public boolean doesPositionExist(Position position);

  public void clearCaseFrom(Entity entity, Position position);

  public Position getNearestEntity(Position fromPos, Class<?> entityType);

  public boolean doesSquareContainEntity(Position squarePos, Class<?> entityType);

  public void addEntityAtSquare(Entity entity, Position position);

  //Return if the position is completely free
  public boolean isPositionEmpty(Position position);

  //Return if the position is available for the specified priority
  public boolean isPositionFree(Position position, int priority);
  
  
}