//
// Created by Vicente Ferrari Smith on 06.03.26.
//

#ifndef V_RENDERER_H
#define V_RENDERER_H

#ifdef __EMSCRIPTEN__
#include <GLFW/emscripten_glfw3.h>
#else
#include <GLFW/glfw3.h>
#endif
#include <glm/glm.hpp>
#include <webgpu/webgpu.h>

#include "../sprite.h"

enum class PROJECTION_TYPE : uint8_t {
    NONE,
    ORTHOGRAPHIC_WORLD,
    ORTHOGRAPHIC_WINDOW,
    PERSPECTIVE_WORLD,
    PERSPECTIVE_WINDOW,
    COUNT,
};

// commands

enum class PipelineType : uint8_t {
    None,
    TexturedQuad,
    ColoredQuad,
    Line,
    Text,
    Chunk
};

struct TexturedQuadCmd {
    glm::vec2 pos;
    glm::vec2 scale;
    glm::vec2 uv0;
    glm::vec2 uv1;
    glm::vec4 colour;
    WGPUTextureDescriptor texture;
};

struct ColoredQuadCmd {
    glm::vec2 pos;
    glm::vec2 scale;
    glm::vec4 colour;
};

struct LineCmd {
    glm::vec2 start;
    glm::vec2 end;
    glm::vec4 color;
};


struct SortKey {
    uint16_t depth; // world Z or Y-sorted depth
    uint16_t materialID; // texture sheet, font atlas, etc.
    uint8_t pipeline; // PipelineType

    bool operator<(const SortKey& b) const;
};

struct RenderCommand {

    SortKey      key;
    PipelineType pipeline;

    union {
        TexturedQuadCmd textured_quad;
        ColoredQuadCmd  colored_quad;
        LineCmd         line;
        // TextCmd         text;
        // ChunkCmd        chunk;
    };
};

struct Renderer {
    std::vector<RenderCommand> commands{};

    WGPURenderPipeline textured_quad_pipeline;

    size_t elementCount = 64;
    WGPUComputePipeline compute_pipeline;

    WGPUBuffer input_buffer;
    WGPUBuffer output_buffer;
    WGPUBuffer staging_buffer;

    Renderer() = default;
    Renderer(GLFWwindow *window);

    void begin_frame();
    void end_frame(GLFWwindow *window);
    void submit_sprite(glm::vec2 pos, const sprite_t &sprite);

    void create_render_pipeline();
    void create_compute_pipeline();
};


#endif //V_RENDERER_H