#include "StateManager.h"
#include "../Engine.h"

void StateManager::PushState(std::unique_ptr<BaseState> state, Engine& engine)
{
    if (!states.empty()) { states.back()->Exit(engine); }
    
    states.push_back(std::move(state));
    states.back()->Enter(engine);
}

void StateManager::PopState(Engine& engine)
{
    if (states.empty())
    {
        SDL_Log("StateManager::PopState() warning: PopState() called on empty stack");
        return;
    }
    
    states.back()->Exit(engine);
    states.pop_back();
    
    if (!states.empty())
    {
        states.back()->Enter(engine);
    }
    else
    {
        SDL_Log("StateManager::PopState() warning: Stack is now empty after PopState");
    }
}

void StateManager::ChangeState(std::unique_ptr<BaseState> state, Engine& engine)
{
    if (!states.empty())
    {
        states.back()->Exit(engine);
        states.pop_back();
    }
    
    states.push_back(std::move(state));
    states.back()->Enter(engine);
}

void StateManager::HandleEvents(Engine& engine, SDL_Event& e)
{
    if (!states.empty())
    {
        states.back()->HandleEvents(engine, e);
    }
}

void StateManager::Update(Engine& engine, float dt)
{
    if (!states.empty())
    {
        states.back()->Update(engine, dt);
    }
}

void StateManager::Render(Engine& engine)
{
    // TODO: Check if this should be here
    //for (const auto& state : states)
    //{
    //    state->Render(engine);
    //}
    
    if (!states.empty())
    {
        states.back()->Render(engine);
    }
}

void StateManager::RenderImGui(Engine& engine)
{
    if (!states.empty())
    {
        states.back()->RenderImGui(engine);
    }
}

BaseState* StateManager::GetCurrentState() const
{
    if (!states.empty())
    {
        return states.back().get();
    }
    
    return nullptr;
}

std::vector<std::string> StateManager::GetStack() const
{
    std::vector<std::string> stackNames;
    stackNames.reserve(states.size());
    for (const auto& statePtr : states)
    {
        if (statePtr)
        {
            std::string name = typeid(*statePtr).name();
            if (name.find("MainMenuState") != std::string::npos)
            {
                name = "MainMenuState";
            }
            else if (name.find("PauseState") != std::string::npos)
            {
                name = "PauseState";
            }
            else if (name.find("GamePlayState") != std::string::npos)
            {
                name = "GamePlayState";
            }
            
            stackNames.push_back(name);
        }
    }
    
    return stackNames;
}