package fr.iut_fbleau.GameAPI;

import java.util.Iterator;
import java.util.Deque;

/**
 * An abstract class implementing the interface IBoard.
 *
 * It is used to implement some things to do with the update of the next player
 * which is the same for all turn taking games using a round robin and provides
 * also a minimal implantation of the history mechanism.
 *
 * The current implantation works only for two players.
 *
 * 
 */
public abstract class AbstractBoard implements IBoard{

    private Player currentPlayer ;

    private  Deque<AbstractPly> history;

    private void setNextPlayer(){
	if (this.currentPlayer==Player.PLAYER1){
	    this.currentPlayer= Player.PLAYER2;
	}
	else
	    this.currentPlayer= Player.PLAYER1;
    }

    // Beware not checking if move is legal.
    // To be used in do(AbstractPly c)
    private void addPlyToHistory(AbstractPly c){
	this.history.addLast(c);
    }

    // Beware not checking if history is not empty
    // To be used in undo()
    private void removePlyFromHistory(){
	this.history.removeLast();
    }

    
    /**
     * @return the current player
     */
    public Player getCurrentPlayer(){
	return this.currentPlayer;
    }

    /**
     * Returns the game status
     *
     * @return true iff the game is over
     */
    public abstract boolean isGameOver();

    /**
     *  
     * @return the result (null if not over)
     */
    public abstract Result getResult();

    
    /**
     * checker of the legality of a ply from this position
     *
     * @return true iff the ply is legal
     */
    public abstract boolean isLegal(AbstractPly c);
   
    
    /**
     * constructor of Iterator over legal moves from this position
     *
     * @return the iterator
     */
    public abstract Iterator<AbstractPly> iterator();

    
    
    /**
     * Plays a given move on the plateau.
     * Should update history using removePlyFromHistory
     *
     * @throws IllegalArgumentException if the move is always illegal (say from the wrong game)
     * @throws IllegalStateException if the move is not legal in this position
     *
     * @param AbstractPly to be played
     *
     */
    public abstract void doPly(AbstractPly c);

    /**
     * Resets the plateau to the position before the last move.
     *
     * @throws IllegalStateException if nothing to undo in history
     *
     */
    public abstract void undoPly();

    /**
     * creates a safe copy of the board.
     *
     * @return the copy
     */    
    public abstract IBoard safeCopy();
}
