#pragma once

#include "utils/utils.hpp" // IWYU pragma: keep

namespace VE
{
  enum class event_type
  {
    KEY_PRESSED,
    KEY_RELEASED,
    KEY_REPEATE,

    MOUSE_BUTTON_PRESSED,
    MOUSE_BUTTON_DOUBLE_PRESSED,
    MOUSE_BUTTON_RELEASED,

    MOUSE_CURSOR_POSITION,
    MOUSE_SCROLL,

    WINDOW_RESIZE,
    WINDOW_CLOSE,
    WINDOW_FOCUS,
  };

  enum class event_target
  {
    VE
  };

  struct event
  {
    event(std::any type, std::any data) : m_type{ type }, m_data{ data } {}
    ~event() = default;

    std::any m_type;
    std::any m_data;
  };

  struct event_manager : public hack::patterns::singleton<event_manager>
  {
    std::vector<VE::event_fn<VE::event>> m_funcs;
    void connect(event_fn<event> fn) { m_funcs.push_back(fn); };
    void emit(event e)
    {
      for(auto& f : m_funcs) 
      {
        try
        {
          f(e);
        }
        catch(std::exception& e)
        {
          hack::error()(e.what());
          hack::log()("size funcs", m_funcs.size());
        }
        catch(...)
        {
          hack::error()("ooops...");
        }
      }
    }
  };
}
