#include <raylib.h>
#include <imgui.h>
#include <rlImGui.h>
#include <rlgl.h>

#include "viewport.h"

typedef struct game_object_t {
    char name[128];
} game_object;

const char* gl_versions[7] = {
    "UNKNOWN",
    "1.1",
    "2.1",
    "3.3",
    "4.3",
    "ES 2.0",
    "ES 3.0"
};

Camera camera;

int main() {
    SetConfigFlags(FLAG_WINDOW_RESIZABLE);
    InitWindow(800, 600, "gear");
    //InitViewport();

    rlImGuiSetup(true);
    /*ImGuiIO *ioptr = igGetIO();
    ioptr->ConfigFlags |= ImGuiConfigFlags_DockingEnable;*/

    camera = (Camera){};
    camera.position = (Vector3) { 10.0f, 10.0f, 10.0f };
    camera.target = (Vector3) { 0.0f, 0.0f, 0.0f };
    camera.up = (Vector3) { 0.0f, 1.0f, 0.0f };
    camera.fovy = 70.0f;
    camera.projection = CAMERA_PERSPECTIVE;

    //SetTargetFPS(60);
    
        ImVec4* colors = ImGui::GetStyle().Colors;
    colors[ImGuiCol_Text]                              = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
    colors[ImGuiCol_TextDisabled]              = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
    colors[ImGuiCol_WindowBg]                          = ImVec4(0.29f, 0.34f, 0.26f, 1.00f);
    colors[ImGuiCol_ChildBg]                                = ImVec4(0.29f, 0.34f, 0.26f, 1.00f);
    colors[ImGuiCol_PopupBg]                                = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
    colors[ImGuiCol_Border]                          = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
    colors[ImGuiCol_BorderShadow]              = ImVec4(0.14f, 0.16f, 0.11f, 0.52f);
    colors[ImGuiCol_FrameBg]                                = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
    colors[ImGuiCol_FrameBgHovered]          = ImVec4(0.27f, 0.30f, 0.23f, 1.00f);
    colors[ImGuiCol_FrameBgActive]            = ImVec4(0.30f, 0.34f, 0.26f, 1.00f);
    colors[ImGuiCol_TitleBg]                                = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
    colors[ImGuiCol_TitleBgActive]            = ImVec4(0.29f, 0.34f, 0.26f, 1.00f);
    colors[ImGuiCol_TitleBgCollapsed]          = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
    colors[ImGuiCol_MenuBarBg]                        = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
    colors[ImGuiCol_ScrollbarBg]                    = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
    colors[ImGuiCol_ScrollbarGrab]            = ImVec4(0.28f, 0.32f, 0.24f, 1.00f);
    colors[ImGuiCol_ScrollbarGrabHovered]   = ImVec4(0.25f, 0.30f, 0.22f, 1.00f);
    colors[ImGuiCol_ScrollbarGrabActive]    = ImVec4(0.23f, 0.27f, 0.21f, 1.00f);
    colors[ImGuiCol_CheckMark]                        = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_SliderGrab]                      = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
    colors[ImGuiCol_SliderGrabActive]          = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
    colors[ImGuiCol_Button]                          = ImVec4(0.29f, 0.34f, 0.26f, 0.40f);
    colors[ImGuiCol_ButtonHovered]            = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
    colors[ImGuiCol_ButtonActive]              = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
    colors[ImGuiCol_Header]                          = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
    colors[ImGuiCol_HeaderHovered]            = ImVec4(0.35f, 0.42f, 0.31f, 0.6f);
    colors[ImGuiCol_HeaderActive]              = ImVec4(0.54f, 0.57f, 0.51f, 0.50f);
    colors[ImGuiCol_Separator]                        = ImVec4(0.14f, 0.16f, 0.11f, 1.00f);
    colors[ImGuiCol_SeparatorHovered]          = ImVec4(0.54f, 0.57f, 0.51f, 1.00f);
    colors[ImGuiCol_SeparatorActive]                = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_ResizeGrip]                      = ImVec4(0.19f, 0.23f, 0.18f, 0.00f); // grip invis
    colors[ImGuiCol_ResizeGripHovered]        = ImVec4(0.54f, 0.57f, 0.51f, 1.00f);
    colors[ImGuiCol_ResizeGripActive]          = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_Tab]                                    = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
    colors[ImGuiCol_TabHovered]                      = ImVec4(0.54f, 0.57f, 0.51f, 0.78f);
    colors[ImGuiCol_TabActive]                        = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_TabUnfocused]              = ImVec4(0.24f, 0.27f, 0.20f, 1.00f);
    colors[ImGuiCol_TabUnfocusedActive]      = ImVec4(0.35f, 0.42f, 0.31f, 1.00f);
    colors[ImGuiCol_DockingPreview]          = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_DockingEmptyBg]          = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
    colors[ImGuiCol_PlotLines]                        = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
    colors[ImGuiCol_PlotLinesHovered]          = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_PlotHistogram]            = ImVec4(1.00f, 0.78f, 0.28f, 1.00f);
    colors[ImGuiCol_PlotHistogramHovered]   = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
    colors[ImGuiCol_TextSelectedBg]          = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_DragDropTarget]          = ImVec4(0.73f, 0.67f, 0.24f, 1.00f);
    colors[ImGuiCol_NavHighlight]              = ImVec4(0.59f, 0.54f, 0.18f, 1.00f);
    colors[ImGuiCol_NavWindowingHighlight]  = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
    colors[ImGuiCol_NavWindowingDimBg]        = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
    colors[ImGuiCol_ModalWindowDimBg]          = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);

    ImGuiStyle& style = ImGui::GetStyle();
    style.FrameBorderSize = 1.0f;
    style.WindowRounding = 0.0f;
    style.ChildRounding = 0.0f;
    style.FrameRounding = 0.0f;
    style.PopupRounding = 0.0f;
    style.ScrollbarRounding = 0.0f;
    style.GrabRounding = 0.0f;
    style.TabRounding = 0.0f; 

    bool show_demo = false;
    bool show_debug = true;

    /*sl_vec(game_object*) game_objects = { 0 };
    for(int i = 0; i < 10000; i++) {
        game_object* obj = calloc(sizeof(game_object), 1);
        snprintf(obj->name, 128, "bob %d", i);
        sl_vec_push(game_objects, obj);
    }*/

    game_object* selected = NULL;

    while(!WindowShouldClose()) {
        //UpdateViewport();

        BeginDrawing();
        {
            ClearBackground(BLACK); 

            /*BeginViewport();
            {
                ClearBackground(BLACK);
                BeginMode3D(camera);
                {
                    DrawCube((Vector3){0.0f, 0.0f, 0.0f}, 5.0f, 5.0f, 5.0f, RED);
                    DrawGrid(10, 10);
                }
                EndMode3D();

                DrawFPS(10, 10);
                //DrawText(TextFormat(

                int y = 50;
                for(sl_vec_it(obj, game_objects)) {
                    DrawText(obj->name, 10, y, 20, WHITE);
                    y += 20;
                }
            }
            EndViewport();*/

            rlImGuiBegin();
            {
                if(ImGui::BeginMainMenuBar()) {
                    if(ImGui::BeginMenu("File", true)) {
                        if(ImGui::MenuItem("Quit", "ESC", false, true)) {
                            CloseWindow();
                        }
                        ImGui::EndMenu();
                    }

                    if(ImGui::BeginMenu("Debug", true)) {
                        ImGui::Checkbox("Show demo window", &show_demo);
                        ImGui::EndMenu();
                    }

                    ImGui::EndMainMenuBar();
                }

                //ImGui::DockSpaceOverViewport(NULL, 0, NULL);
                
                if(show_demo)
                    ImGui::ShowDemoWindow(&show_demo);
                
                //RenderViewport();

                ImGui::Begin("Game Objects", NULL, 0);
                {
                    /*for(sl_vec_it(obj, game_objects)) {
                        char* name = (*obj)->name;
                        if(strcmp(name, "") == 0) name = " "; 
                        if(igSelectable_Bool(name, selected == *obj, 0, (ImVec2){0, 0}))
                            selected = *obj;
                    }*/
                }
                ImGui::End();
 
                ImGui::Begin("Properties", NULL, 0);
                {
                    if(selected != NULL) {
                        ImGui::InputText("##name", selected->name, 128, 0, NULL, NULL);
                    }
                }
                ImGui::End();

                if(show_debug) {
                    ImGui::Begin("Debug", &show_debug, 0);
                    {
                        ImGui::Text("raylib %s", RAYLIB_VERSION);
                        ImGui::Text("OpenGL %s", gl_versions[rlGetVersion()]);
                        ImGui::Text("FPS: %d", GetFPS());
                        ImGui::Text("Frame time: %f", GetFrameTime());
                        ImGui::Text("Cursor hidden: %d", IsCursorHidden());

                        ImGui::Text("\nResolutions");
                        ImGui::Text("Window: %dx%d", GetScreenWidth(), GetScreenHeight());
                        for(int i = 0; i < GetMonitorCount(); i++) {
                            ImGui::Text("%s: %dx%d@%d", GetMonitorName(i), GetMonitorWidth(i),
                                    GetMonitorHeight(i), GetMonitorRefreshRate(i));
                        }
                    }
                    ImGui::End();
                }
            }
            rlImGuiEnd();
        }
        EndDrawing();
    }

    rlImGuiShutdown();
    CloseWindow();
}