#include <GLFW/glfw3.h>
#include <ctime>
#include <cstdlib>
#include "log.h"
#include "window.h"
#include <input.h>
#include <render/render.h>
#include "color.h"
#include "resources.h"
#include "game/game.h"
#include "editor/editor.h"
#include "imgui/imgui.h"
#include "imgui/imgui_impl_glfw_gl3.h"
#include <app.h>

void init();
void close();

void _glfwError(int, const char*);

int main()
{
    init();

    App::Init();
    game::Init();

    ImGuiContext *ctx = ImGui::CreateContext();
    ImGui::SetCurrentContext(ctx);

    ImGui_ImplGlfwGL3_Init(window::getHandler(), true);

    ImGui::GetIO().Fonts->AddFontFromFileTTF("data/fonts/font.ttf", 24, nullptr, ImGui::GetIO().Fonts->GetGlyphRangesDefault());

    render::setClearColor(color::hsv2rgba(vec3f(rand()%360, 1, 0.05)));
    render::mode2D();

    game::SetState(game::gameState::stateMenu);

    while(!window::shouldClose()) {
        App::Update();

        ImGui_ImplGlfwGL3_NewFrame();

        game::Update();

        render::clearScreen();

        game::Render();

        render::flush();
        ImGui::Render();
        window::swapBuffers();
        window::pollEvents();
    }

    ImGui::DestroyContext(ctx);

    game::Free();
    ImGui_ImplGlfwGL3_Shutdown();
    close();
}

void init()
{
    Logger::Open();
    srand(time(0));
    glfwSetErrorCallback(_glfwError);
    glfwInit();
    Logger::Debug("GLFW version: %s\n", glfwGetVersionString());

    window::createWindow({960, 544}, u8"IGDC#165");

    render::init();

    resources::init();
}

void close()
{
    render::free();
    App::Free();
    window::closeWindow();
    glfwTerminate();
    Logger::Close();
    exit(0);
}

void _glfwError(int type, const char* error)
{
    switch(type) {
        case GLFW_NO_CURRENT_CONTEXT:
        case GLFW_OUT_OF_MEMORY:
        case GLFW_API_UNAVAILABLE:
        case GLFW_VERSION_UNAVAILABLE:
        case GLFW_PLATFORM_ERROR:
            Logger::Error("GLFW error: %s\n", error);
            Logger::Close();
            abort();
            break;
        default:
            Logger::Warning("GLFW error: %s\n", error);
    }
}

