#include "screenManager.h"

using namespace std;
using namespace quokka_gfx;
//------------------------------------------------------------
/* Default constructor */
ScreenManager::ScreenManager()
  : m_screenTransition(this)
{
  // Nothing to do
}
//------------------------------------------------------------
/* Set the current screen, replacing any existing screens on the stack */
void ScreenManager::setScreen(std::unique_ptr<Screen> screen)
{
  // Clear the stack of screens
  while (!m_screenStack.empty())
  {
    // Call on_exit for the current screen
    m_screenStack.top()->on_exit();

    // Remove the current screen
    m_screenStack.pop();
  }

  // Insert the new screen on the stack
  m_screenStack.push(std::move(screen));

  // Call on_enter for the new screen
  if (!m_screenStack.empty())
    m_screenStack.top()->on_enter();
}
//------------------------------------------------------------
/* Push a new screen onto the stack */
void ScreenManager::pushScreen(std::unique_ptr<Screen> screen)
{
  // Insert the new screen on top of the stack
  m_screenStack.push(std::move(screen));

  // Call on_enter for the new screen
  if (!m_screenStack.empty())
    m_screenStack.top()->on_enter();
}
//------------------------------------------------------------
/* Pop the current screen from the stack */
void ScreenManager::popScreen()
{
  if (!m_screenStack.empty())
  {
    // Call on_exit for the current screen
    m_screenStack.top()->on_exit();

    // Remove the current screen
    m_screenStack.pop();
  }
}
//------------------------------------------------------------
/* Handle events for the current screen */
void ScreenManager::handleEvents()
{
  // If a screen transition is in progress, block event handling for the current screen
  if (m_screenTransition.getState() != ScreenTransition::State::None)
    return;

  if (!m_screenStack.empty())
    m_screenStack.top()->handleEvents();
}
//------------------------------------------------------------
/* Update the current screen */
void ScreenManager::update(const double deltaTime)
{
  if (!m_screenStack.empty())
    m_screenStack.top()->update(deltaTime);

  // Update the screen transition
  m_screenTransition.update(deltaTime);
}
//------------------------------------------------------------
/* Render the current screen */
void ScreenManager::render(RendererManager *renderer)
{
  if (!m_screenStack.empty())
    m_screenStack.top()->render(renderer);

  // Render the screen transition
  m_screenTransition.render(renderer);
}
//------------------------------------------------------------
/* Get the current screen */
Screen *ScreenManager::getCurrentScreen() const
{
  if (!m_screenStack.empty())
    return m_screenStack.top().get();
  return nullptr;
}
//------------------------------------------------------------
