package it.polimi.ingsw.gc14.Model.GamePackage;

import it.polimi.ingsw.gc14.Model.Player;
import it.polimi.ingsw.gc14.Model.Slot;
import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
import java.io.Serializable;

/**
 * Represents the current state of the game.
 * A CurrentState object stores the current player, slot, era, round,
 * remaining upper and lower cards, and the current game stage.
 */
public class CurrentState implements Serializable {
    // region Getters

    /**
     * The current player associated with the game state.
     */
    private Player player;

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

    /**
     * The current slot associated with the game state.
     */
    private Slot slot;

    /**
     * Returns the current slot.
     *
     * @return the current slot.
     */
    public Slot getSlot(){
        return slot;
    }

    /**
     * The current era of the game.
     */
    private int Era;

    /**
     * Returns the current era of the game.
     *
     * @return the current era of the game.
     */
    public int getEra(){
        return Era;
    }

    /**
     * The current round of the game.
     */
    private int round;

    /**
     * Returns the current round of the game.
     *
     * @return the current round of the game.
     */
    public int getRound(){
        return round;
    }

    /**
     * The number of upper cards currently available.
     */
    private int NUpper;

    /**
     * Returns the number of upper cards currently available.
     *
     * @return the number of upper cards currently available.
     */
    public int getNUpper(){
        return NUpper;
    }

    /**
     * The number of lower cards currently available.
     */
    private int NLower;

    /**
     * Returns the number of lower cards currently available.
     *
     * @return the number of lower cards currently available.
     */
    public int getNLower(){
        return NLower;
    }

    /**
     * The current stage of the game.
     */
    private GameStages GameStage;

    /**
     * Returns the current stage of the game.
     *
     * @return the current stage of the game.
     */
    public GameStages getGameStage(){
        return GameStage;
    }

    // endregion getters

    // region Setters

    /**
     * Increments the current era by 1.
     */
    public void EraUpdate(){
        Era++;
    }

    /**
     * Increments the current round by 1.
     */
    public void RoundUpdate(){
        round++;
    }

    /**
     * Decrements the number of upper cards by 1.
     */
    public void UpperDrawn(){
        NUpper--;
    }

    /**
     * Decrements the number of lower cards by 1.
     */
    public void LowerDrawn(){
        NLower--;
    }

    /**
     * Updates the current game stage.
     *
     * @param GameStage the new game stage.
     */
    public void GameStageUpdate(GameStages GameStage){
        this.GameStage = GameStage;
    }
    // endregion setters

    // region Constructors

    /**
     * Creates a new CurrentState object with default initial values.
     * The initial player and slot are {@code null}, the era and round are set to 1,
     * the number of upper and lower cards is set to 0, and the game stage is set to {@code WAITING}.
     */
    public CurrentState(){
        this.player = null;
        this.slot = null;
        this.Era = 1;
        this.round = 1;
        this.NUpper = 0;
        this.NLower = 0;
        this.GameStage = GameStages.WAITING;
    }
    // endregion constructors

    // region Functions

    /**
     * Updates the current player and slot.
     * If the specified slot is {@code null}, the numbers of upper and lower cards are both set to 0.
     * Otherwise, the numbers of upper and lower cards are updated using the values of the specified slot.
     *
     * @param player the new current player.
     * @param slot the new current slot.
     */
    public void PlayerUpdate(Player player, Slot slot){
        this.player = player;
        this.slot = slot;
        if(slot == null){
            this.NUpper = 0;
            this.NLower = 0;
        }
        else{
            this.NUpper = slot.getNUpper();
            this.NLower = slot.getNLower();
        }

    }
    // endregion functions
}
