/*
	ApplicationFramework
	by John Ryland
	Copyright (c) 2023
*/

////////////////////////////////////////////////////////////////////////////////////
//	Application

#include "Application.h"
#include "GlfwWindowSystem.h"
#include "DearImGuiUiSystem.h"
#include "VulkanRenderer.h"
#include "GlfwVulkanSurface.h"

namespace ApplicationFramework {

Application::Application()
    : m_windowSystem(new GlfwWindowSystem)
    , m_uiSystem(new DearImGuiUiSystem)
    , m_renderSystem(new VulkanRenderer)
    , m_windowRenderSurfaceSystem(new GlfwVulkanSurface(m_windowSystem, m_renderSystem))
{
    AddItem(std::unique_ptr<ICoreSystem>(m_uiSystem));         // ImGui ui impl assumes init before VulkanRenderer impl
    AddItem(std::unique_ptr<ICoreSystem>(m_renderSystem));     // VulkanRenderer impl assumes to shutdown before ImGui ui impl
    AddItem(std::unique_ptr<ICoreSystem>(m_windowSystem));
    AddItem(std::unique_ptr<ICoreSystem>(m_windowRenderSurfaceSystem));
}

// virtual
void Application::MainLoop()
{
    // Done here because it is after the first window has been created which is needed to make the render surface
    Initialize();
    //SetApplication(this);

    while (!m_windowSystem->LastWindowClosed())
    {
        Prepare();
        Update();
        Render();
        Present();
    }

    Shutdown();
}

} // ApplicationFramework namespace
