#include "WindowManager.h"

#include "../Application.h"

using namespace std;
using namespace quokka_gfx;
//--------------------------------------------------------------
/* Register an existing window with the WindowManager */
void WindowManager::RegisterWindow(Window *window)
{
  if (m_windows.empty())
    window->m_appOwner.m_inputManager.m_focusedWindowID = SDL_GetWindowID(window->GetNativeWindow());

  m_windows.push_back(window);
}
//--------------------------------------------------------------
/* Close a window by its SDL window ID */
void WindowManager::CloseWindow(uint32_t windowId)
{
  const auto it = ranges::find_if(m_windows, [windowId](const auto &win)
                                  { return SDL_GetWindowID(win->GetNativeWindow()) == windowId; });
  if (it != m_windows.end())
  {
    delete *it;              // Delete the window instance
    m_windows.erase(it);     // Remove the window from the vector
  }
}
//--------------------------------------------------------------
/* Close a window by its pointer */
void WindowManager::CloseWindow(Window *window)
{
  const auto it = ranges::find_if(m_windows, [window](const auto &win)
                                  { return win == window; });
  if (it != m_windows.end())
  {
    delete *it;              // Delete the window instance
    m_windows.erase(it);     // Remove the window from the vector
  }
}
//--------------------------------------------------------------
/* Get the vector of windows instances */
const WindowManager::WindowList &WindowManager::GetWindows() const noexcept
{
  return m_windows;
}
//--------------------------------------------------------------
/* Check if there are any windows managed by the WindowManager */
bool WindowManager::HasAnyWindow() const noexcept
{
  return !m_windows.empty();
}
//--------------------------------------------------------------
/* Handle event for all windows */
void WindowManager::OnEvent(SDL_Event *event)
{
  // Handle window close events
  if (event->type == SDL_EVENT_WINDOW_CLOSE_REQUESTED)
    CloseWindow(event->window.windowID);

  // Propagate the event to all registered windows
  for (const auto &window : m_windows)
    window->OnEvent(event);
}
//--------------------------------------------------------------
/* Update all windows */
void WindowManager::Update(const float dt) const
{
  // Propagate the Update call to all registered windows
  for (const auto &window : m_windows)
    window->Update(dt);
}
//--------------------------------------------------------------
/* Render all windows */
void WindowManager::Render() const
{
  // Propagate the Render call to all registered windows
  for (const auto &window : m_windows)
    window->Render();
}
//--------------------------------------------------------------
