#include "pch.h"

#include "platform_windows/windows_runtime_shell.h"

#include "app.h"
#include "platform_windows/windows_bootstrap_helpers.h"
#include "platform_windows/windows_main_window_session.h"
#include "platform_windows/windows_platform_services.h"
#include "platform_windows/windows_runtime_flow.h"
#include "platform_windows/windows_runtime_state.h"
#include "platform_windows/windows_stylus_input.h"
#include "platform_windows/windows_window_shell.h"

namespace pp::platform::windows {

int run_main_application(int argc, char** argv)
{
    const auto instance = GetModuleHandle(NULL);

    auto& app = initialize_bound_app_runtime();
    app.set_platform_services(&pp::platform::windows::platform_services());
    app.initLog();

    pp::platform::windows::init_shcore_API();
    pp::platform::windows::initialize_stylus_input();

    if (pp::platform::windows::SetProcessDpiAwareness_fn)
        pp::platform::windows::SetProcessDpiAwareness_fn(PROCESS_PER_MONITOR_DPI_AWARE);

    pp::platform::windows::ensure_runtime_data_directory();

    pp::platform::windows::SplashScreen splash(instance);

    pp::platform::windows::initialize_retained_input_state();

    pp::platform::windows::setup_exception_handler(app);

    pp::platform::windows::read_WMI_info();

    app.create();

    auto startup = pp::platform::windows::initialize_main_window_startup_state(app);
    auto context = pp::platform::windows::OpenGlWindowContext {};
    switch (pp::platform::windows::initialize_main_window_and_gl(
        startup,
        retained_main_window_handle_ref(),
        instance,
        retained_main_window_title_buffer(),
        context))
    {
    case pp::platform::windows::MainStartupResult::Ok:
        break;
    case pp::platform::windows::MainStartupResult::GladLoadFailure:
        release_bound_app();
        return 0;
    case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
        release_bound_app();
        return -1;
    }

    //wglSwapIntervalEXT(1);

    bool start_in_vr = false;
    if (argc > 1)
    {
        switch (const_hash(argv[1]))
        {
        case const_hash("convert"):
            app.initShaders();
            app.cmd_convert(argv[2], argv[3]);
            release_bound_app();
            return 0;
        case const_hash("-vrmode"):
            start_in_vr = true;
            break;
        default:
            break;
        }
    }

    pp::platform::windows::run_bound_main_window_runtime(startup, start_in_vr, instance, splash);
    release_bound_app();
    return 0;
}

}
