#include <print>
#include <vector>
#include <fstream>
#include <cassert>

#define VOLK_IMPLEMENTATION
#include <Volk/volk.h>
#define VMA_IMPLEMENTATION
#include <vma/vk_mem_alloc.h>
#include <GLFW/glfw3.h>

#include "renderer/init.h"
#include "renderer/renderer.h"
#include "renderer/texture.h"

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

GLFWwindow *window;

int32_t window_width  = 640;
int32_t window_height = 480;

uint64_t t           = 0;
uint64_t accumulator = 0;

uint64_t dt = 0;

int main() {
    if (!glfwInit())
        return -1;

    dt = (uint64_t) (1.0 / 60.0 * glfwGetTimerFrequency());

    std::println("Hello, Sailor!");

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    window = glfwCreateWindow(window_width, window_height, "Hello World", nullptr, nullptr);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    createInstance(window);
    createSurface(window);
    createDevice();

    createSwapchain(window);

    slang::createGlobalSession(slangGlobalSession.writeRef());

    Renderer renderer(window);

    texture_manager.load("assets/boy.png", renderer);

    uint64_t current_time = glfwGetTimerValue();

    while (!glfwWindowShouldClose(window)) {

        uint64_t new_time = glfwGetTimerValue();
        uint64_t frame_time = new_time - current_time;
        current_time = new_time;

        accumulator += frame_time;

        glfwPollEvents();

        uint64_t updates = 0;

        while (accumulator >= dt) {
            accumulator -= dt;
            t += dt;
            updates++;
        }
        // std::println("Updates: {}", updates);
        // std::println("frame time: {}", ((double) (frame_time) / (double) glfwGetTimerFrequency()));

        renderer.begin_frame();

        double f = 15.0 * (t / (double) glfwGetTimerFrequency());

        renderer.submit_quad(
    {
                100.0 + 10.0 * glm::sin(f),
                100.0 - 10.0 * glm::cos(f),
            },
            {100.0, 100.0});

        renderer.submit_quad({400.0, 400.0}, {20.0, 20.0});

        // renderer.submit_sprite();

        renderer.end_frame();

    }

    vkDeviceWaitIdle(device);


    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}
