#ifndef RENDERING_INTERNAL_API_H
#define RENDERING_INTERNAL_API_H

#include "townengine/textures/internal_api.h"
#include "townengine/util.h"
#include "townengine/macros/option.h"

#include <SDL2/SDL.h>
#include <glad/glad.h>

#include <stdbool.h>

struct sprite_primitive {
    t_frect rect;
    t_color color;
    float rotation;
    t_texture_key texture_key;
    bool flip_x;
    bool flip_y;
    bool repeat;

    m_option_list(
        t_fvec2, texture_origin )
};

struct rect_primitive {
    t_frect rect;
    t_color color;
};

struct circle_primitive {
    float radius;
    t_color color;
    t_fvec2 position;
};

struct text_primitive {
    t_color color;
    t_fvec2 position;
    char *text;
    const char *font;
    int height_px;
};

enum primitive_2d_type {
    PRIMITIVE_2D_SPRITE,
    PRIMITIVE_2D_RECT,
    PRIMITIVE_2D_CIRCLE,
    PRIMITIVE_2D_TEXT,
};

struct primitive_2d {
    enum primitive_2d_type type;

    union {
        struct sprite_primitive sprite;
        struct rect_primitive rect;
        struct circle_primitive circle;
        struct text_primitive text;
    };
};

/* union for in-place recalculation of texture coordinates */
union uncolored_space_triangle {
    /* pending for sending, uvs are not final as texture atlases could update */
    struct uncolored_space_triangle_primitive {
        t_fvec3 v0;
        t_fvec2 uv0; /* in pixels */
        t_fvec3 v1;
        t_fvec2 uv1; /* in pixels */
        t_fvec3 v2;
        t_fvec2 uv2; /* in pixels */
    } primitive;

    /* TODO: have it packed? */
    /* structure that is passed in opengl vertex array */
    struct uncolored_space_triangle_payload {
        t_fvec3 v0;
        t_fvec2 uv0;
        t_fvec3 v1;
        t_fvec2 uv1;
        t_fvec3 v2;
        t_fvec2 uv2;
    } payload;
};

/* batch of primitives with overlapping properties */
struct mesh_batch {
    GLuint buffer;          /* server side storage */
    uint8_t *primitives;
};

struct mesh_batch_item {
    t_texture_key key;
    struct mesh_batch value;
};

struct text_cache {
    struct font_data **data;
};

/* renders the background, then the primitives in all render queues */
void render(void);

/* clears all render queues */
void render_queue_clear(void);

#endif
