using System;
using SlatedGameToolkit.Framework.Graphics.Window;

namespace SlatedGameToolkit.Framework.StateSystem.States
{
    public interface IState
    {
        /// <summary>
        /// Called when this state should be deactivated.
        /// Deactivate may be called multiple times:
        /// When this method returns false,
        /// and
        /// When the next state to be activated has not indicated it is ready.
        /// </summary>
        /// <returns>True if this state was successfully deactivated and false otherwise.</returns>
        bool Deactivate();

        /// <summary>
        /// Called when this state is the active state.
        /// This method will be called until:
        /// This method returns true,
        /// and
        /// until the previous state indicates it is ready to be deactivated.
        /// </summary>
        /// <returns>True if this state was successfully activated and can be shown. False otherwise.</returns>
        bool Activate();

        /// <summary>
        /// Called in intervals dependent on game loop chosen for every update cycle.
        /// Only called on if this state is the active state, indicated on the last status method called on this implementation (acitvate, and deactivate).
        /// </summary>
        /// <param name="timeStep">The change in time between the updates in seconds. If fixed, this amounts to the portion of time between the set update rate. If unlocked, represents the actual amount of time passed since the last update.</param>
        void Update(double timeStep);

        /// <summary>
        /// Called in intervals dependent on game loop chose for every render cycle.
        /// Only called on if this state is the active state, indicated on the last status method called on this implementation (acitvate, and deactivate).
        /// </summary>
        /// <param name="delta">If in time-step mode, normalized value representing the time until the next update. Otherwise, the time passed since the last update.</param>
        void Render(double delta);

        /// <summary>
        /// Called at the game managers convenience, but always before it it shown.
        /// Should be used to set up this state.
        /// </summary>
        /// <param name="manager">The manager that made this call.</param>
        void Initialize(StateManager manager);

        /// <summary>
        /// The name of this state.
        /// The name is used to refer to this state.
        /// The name needs to be unique in a manager.
        /// </summary>
        /// <return>A string representing the name of this state.</return>
        string getName();

        /// <summary>
        /// Called when this state is being removed from the manager, and likely not used again in this games life cycle.
        /// Any unmanaged resources that needs to be disposed of should be done so here.
        /// </summary>
        void Deinitialize();
    }
}