#pragma once

#include "pxl8_math.h"
#include "pxl8_types.h"

#ifdef __cplusplus
extern "C" {
#endif

#define PXL8_MESH_MAX_VERTICES 65536
#define PXL8_MESH_MAX_INDICES  65536

typedef enum pxl8_blend_mode {
    PXL8_BLEND_OPAQUE = 0,
    PXL8_BLEND_ALPHA_TEST,
    PXL8_BLEND_ALPHA,
    PXL8_BLEND_ADDITIVE,
} pxl8_blend_mode;

typedef struct pxl8_gfx_material {
    u32 texture_id;
    u32 lightmap_id;
    u8 alpha;
    u8 blend_mode;
    bool dither;
    bool double_sided;
    bool dynamic_lighting;
    bool per_pixel;
    bool vertex_color_passthrough;
    bool wireframe;
    f32 emissive_intensity;
} pxl8_gfx_material;

typedef struct pxl8_vertex {
    pxl8_vec3 position;
    pxl8_vec3 normal;
    f32 u, v;
    f32 lu, lv;
    u8 color;
    u8 light;
    u8 _pad[2];
} pxl8_vertex;

typedef struct pxl8_mesh {
    pxl8_vertex* vertices;
    u16* indices;
    u32 vertex_count;
    u32 index_count;
    u32 vertex_capacity;
    u32 index_capacity;
} pxl8_mesh;

pxl8_mesh* pxl8_mesh_create(u32 vertex_capacity, u32 index_capacity);
void pxl8_mesh_destroy(pxl8_mesh* mesh);
void pxl8_mesh_clear(pxl8_mesh* mesh);

u16 pxl8_mesh_push_vertex(pxl8_mesh* mesh, pxl8_vertex v);
void pxl8_mesh_push_triangle(pxl8_mesh* mesh, u16 i0, u16 i1, u16 i2);
void pxl8_mesh_push_quad(pxl8_mesh* mesh, u16 i0, u16 i1, u16 i2, u16 i3);

void pxl8_mesh_push_box(pxl8_mesh* mesh, pxl8_vec3 center, pxl8_vec3 half_extents, u8 color);
void pxl8_mesh_push_box_uv(pxl8_mesh* mesh, pxl8_vec3 center, pxl8_vec3 half_extents, u8 color, f32 u_scale, f32 v_scale);

static inline u32 pxl8_mesh_triangle_count(const pxl8_mesh* mesh) {
    return mesh->index_count / 3;
}


#ifdef __cplusplus
}
#endif
