#include <blt/gfx/window.h>
#include <blt/gfx/shader.h>
#include <blt/gfx/texture.h>
#include <blt/gfx/model.h>
#include <blt/gfx/state.h>
#include <blt/std/logging.h>
#include <imgui.h>
#include "blt/gfx/imgui/IconsFontAwesome5.h"

#include "blt/gfx/renderer/resource_manager.h"
#include "blt/gfx/renderer/batch_2d_renderer.h"


blt::gfx::matrix_state_manager global_matrices;
blt::gfx::resource_manager resources;
blt::gfx::batch_renderer_2d renderer_2d(resources);
float x = 0, y = 0, z = 0;
float bx = 500, by = 500;
float mx = 0, my = -9.8;

void handle_input()
{
    using namespace blt::gfx;
    float moveAtX = 0;
    float moveAtZ = 0;
    if (isKeyPressed(GLFW_KEY_W))
        moveAtX = 1;
    else if (isKeyPressed(GLFW_KEY_S))
        moveAtX = -1;
    else
        moveAtX = 0;
    if (isKeyPressed(GLFW_KEY_A))
        moveAtZ = 1;
    else if (isKeyPressed(GLFW_KEY_D))
        moveAtZ = -1;
    else
        moveAtZ = 0;
    const float speed = 270;
    y -= static_cast<float>(moveAtX * speed * getFrameDeltaSeconds());
    x += static_cast<float>(moveAtZ * speed * getFrameDeltaSeconds());
    
    blt::mat4x4 view;
    view.translate(x, y, z);
    global_matrices.setView(view);
}

void init()
{
    using namespace blt::gfx;
    
    resources.enqueue("../resources/textures/cumdollar.jpg", "ibuythat");
    resources.enqueue("../resources/textures/dfoedbi-28157978-1555-45c3-b2f4-d5e5fe25b253.png", "niko");
    
    global_matrices.create_internals();
    resources.load_resources();
    renderer_2d.create();
}

void update(std::int32_t width, std::int32_t height)
{
    global_matrices.update_perspectives(width, height);
    ImGui::ShowDemoWindow();
    ImGui::SetNextWindowSize(ImVec2(150, 85));
    ImGui::Begin("Debug Info Panel", nullptr, ImGuiWindowFlags_NoResize);
    ImGui::Text("%s FPS: %f", ICON_FA_WRENCH, 1.0e9 / static_cast<double>(blt::gfx::getFrameDelta()));
    ImGui::Text("Draw Count: %zu", renderer_2d.draw_count());
    ImGui::End();
    
    handle_input();
    
    global_matrices.update();
    
    const float w = 120, h = 120, cf = 30, rf = 15, crf = 10;
    
    renderer_2d.drawRectangle("ibuythat", blt::gfx::rectangle_t(width/2.0, height/2.0, width, height, 90));
    renderer_2d.drawRectangle("niko", {bx, by, w, h});
    renderer_2d.drawRectangle({bx / width, ((bx / width) + (bx / height)) / 2.0f, by / height}, {bx + w, by + h, w, h});
    
    bx += mx * blt::gfx::getFrameDeltaSeconds() * cf;
    by += my * blt::gfx::getFrameDeltaSeconds() * cf;
    
    if (bx < w / 2.0 || bx > width - w / 2.0)
    {
        mx = -mx;
        my += (static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * rf + crf) - (rf + crf) / 2.0f;
    }
    if (by < h / 2.0 || by > height - h / 2.0)
    {
        my = -my;
        mx += (static_cast<float>(rand()) / static_cast<float>(RAND_MAX) * rf + crf) - (rf + crf) / 2.0f;
    }
    if (mx > 100 || mx < -100)
    {
        mx = mx * 0.2;
    }
    if (my > 100 || my < -100)
        my = my * 0.2;
    
    renderer_2d.render();
}

int main()
{
    blt::gfx::init(blt::gfx::window_data{"My Sexy Window", init, update}.setSyncInterval(1));
    global_matrices.cleanup();
    resources.cleanup();
    renderer_2d.cleanup();
    blt::gfx::cleanup();
    return 0;
}
