#include "application.hpp"

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

namespace VE
{
  application::application(std::string app_name) : m_glfw{ std::make_unique<glfw>() }
  {
    m_instance = std::unique_ptr<application>(this);

    m_glfw->init(app_name);
    m_glfw->set_event_fn(VE_EVENT_FN);

    m_gui = std::make_unique<gui>(m_glfw);
  }

  void application::run()
  {
    while(!glfwWindowShouldClose(m_glfw->get_win()))
    {
      m_glfw->clear();

      m_gui->begin_frame();
      for (auto l : m_layers_stack) l->render();
      m_gui->end_frame();

      m_glfw->update();
    }
  }

  std::unique_ptr<glfw>& application::get_glfw()
  {
    return m_glfw;
  }

  std::unique_ptr<application>& application::get()
  {
    return m_instance;
  }

  void application::attach_layers()
  {
    for (auto l : m_layers_stack) l->on_attach();
  }

  void application::set_event_fn()
  {
    for (const auto l : m_layers_stack) l->set_event_fn(VE_EVENT_FN);
  }

  void application::on_event(event e)
  {
    if (e.is_parallele) 
      for (auto l : m_layers_stack) auto future = std::async(std::launch::async, [&]() { l->on_event(e); });
    else 
      for (auto l : m_layers_stack) l->on_event(e);
  }
}
