#include "EventManager.h"

#include "../Application.h"
#include "../Window/WindowManager.h"
#include "InputManager.h"

using namespace std;
using namespace quokka_gfx;
//--------------------------------------------------------------
/* Constructor */
EventManager::EventManager(Application &appManager)
  : m_appManager(appManager)
{
  // Nothing to do
}
//--------------------------------------------------------------
/* Set the global event handler function */
void EventManager::SetGlobalEventHandler(const GlobalEventHandler &globalEventHandler)
{
  m_globalEventHandler = globalEventHandler;
}
//--------------------------------------------------------------
/* Poll and process SDL events */
EventManager::PollingResult EventManager::ProcessEvents() const
{
  // Update the input states at the beginning of a new frame (before processing events)
  m_appManager.m_inputManager.updateStates();

  // Handle events
  SDL_Event event;
  while (SDL_PollEvent(&event))
  {
    // Process events
    if (event.type == SDL_EVENT_QUIT)
      return PollingResult::Quit;

    // Call the global event handler if it is set
    if (m_globalEventHandler)
    {
      const EventResult result = m_globalEventHandler(event);
      if (result == EventResult::Veto)
        continue;
    }

    // Update input states based on the event
    m_appManager.m_inputManager.processEvent(event);

    // Handle event for all windows
    switch (event.type)
    {
      case SDL_EVENT_WINDOW_FOCUS_GAINED:     // Update the focused window ID when a window gains focus
      case SDL_EVENT_WINDOW_FOCUS_LOST:       // Update the focused window ID when a window loses focus
      case SDL_EVENT_WINDOW_MOUSE_ENTER:      // Update the hovered window ID when the mouse enters a window
      case SDL_EVENT_WINDOW_MOUSE_LEAVE:      // Update the hovered window ID when the mouse leaves a window
      case SDL_EVENT_KEY_DOWN:                // Update the current key state when a key is pressed
      case SDL_EVENT_KEY_UP:                  // Update the current key state when a key is released
      case SDL_EVENT_MOUSE_MOTION:            // Update the current mouse position when the mouse is moved
      case SDL_EVENT_MOUSE_BUTTON_DOWN:       // Update the current mouse button state when a mouse button is pressed
      case SDL_EVENT_MOUSE_BUTTON_UP:         // Update the current mouse button state when a mouse button is released
      case SDL_EVENT_MOUSE_WHEEL:             // Update the current mouse wheel state when the mouse wheel is scrolled
        // Input events are already processed by InputManager, no need to handle them here
        break;
      default:
        m_appManager.m_windowManager.OnEvent(&event);
    }
  }

  return PollingResult::Continue;
}
//--------------------------------------------------------------
