#ifndef _PIUMA_RENDER_PRIMITIVES_H_
#define _PIUMA_RENDER_PRIMITIVES_H_

#include "../lib/types.h"
#include "../lib/math.h"
#include "GL/glcorearb.h"

enum r_texture_flags : u32
{
	R_TEXTURE_NONE   = 0x00,

	R_TEXTURE_ALPHA  = 0x01,
	R_TEXTURE_RGB    = 0x02,
	R_TEXTURE_RGBA   = 0x04,
	R_TEXTURE_SRGB   = 0x08,

	R_TEXTURE_HDR    = 0x10,

	R_TEXTURE_NO_MIPMAP = 0x00010000,

	R_TEXTURE_DONT_OWN    = 0x20000000,
	R_TEXTURE_INITIALIZED = 0x40000000,
	R_TEXTURE_DESTROYED   = 0x80000000
};

struct r_texture
{
	u8 *data;
	v2s size;
	u32 flags;

	// OpenGL
	GLuint gl_id;
};

r_texture r_texture_create(u8 *data, v2s size, u32 flags);
void r_texture_destroy(r_texture *texture);
void r_texture_resize(r_texture *texture, v2s size);
void r_texture_update(r_texture *texture, u8 *data, v2s size, v2s position = {0,0}, u32 stride = 0);
s32 r_texture_channels(r_texture *texture);




enum r_cubemap_flags : u32
{
	R_CUBEMAP_NONE   = 0x00,

	// R_TEXTURE_ALPHA  = 0x01,
	// R_TEXTURE_RGB    = 0x02,
	// R_TEXTURE_RGBA   = 0x04,
	// R_TEXTURE_SRGB   = 0x08,

	R_CUBEMAP_DONT_OWN    = 0x20000000,
	R_CUBEMAP_INITIALIZED = 0x40000000,
	R_CUBEMAP_DESTROYED   = 0x80000000
};

struct r_cubemap
{
	float *data[6];
	v2s size;
	u32 flags;

	// OpenGL
	GLuint gl_id;
};

r_cubemap r_cubemap_create(float *data[6], v2s size, u32 flags);
void r_cubemap_destroy(r_cubemap *cubemap);




struct r_2d_mesh
{
	v2 *vertices;
	v4 *colors;
	v2 *uvs;
	u64 count;

	// OpenGL
	GLuint gl_VAO;
	GLuint gl_vertex_buffer;
	GLuint gl_color_buffer;
	GLuint gl_uv_buffer;
};

r_2d_mesh r_2d_mesh_create(u64 count, v2 *vertices, v4 *colors, v2 *uvs = NULL);
void r_2d_mesh_destroy(r_2d_mesh *mesh);
// r_2d_mesh_update/change




struct r_mesh
{
	v3  *vertices;
	v3  *normals;
	v3  *tangents;
	v2  *uvs;
	u64 vertices_count;

	u32 *indices;
	u64 indices_count;

	// OpenGL
	GLuint gl_VAO;
	GLuint gl_vertex_buffer;
	GLuint gl_normal_buffer;
	GLuint gl_tangent_buffer;
	GLuint gl_uv_buffer;
	GLuint gl_index_buffer;
};

r_mesh r_mesh_create(u64 indices_count, u32 *indices, u64 vertices_count, v3 *vertices, v3 *normals = NULL, v3 *tangents = NULL, v2 *uvs = NULL);
void r_mesh_destroy(r_mesh *mesh);
// r_mesh_update/change


// Common meshes
r_mesh r_mesh_build_cube();



// Framebuffers
enum r_framebuffer_flags : u32
{
	R_FRAMEBUFFER_NONE = 0,
	R_FRAMEBUFFER_DEPTH,
};

struct r_framebuffer
{
	u32 gl_id;
	u32 gl_depth_id;
	r_texture color_texture;
	v2s size;
	u32 flags;
};

r_framebuffer r_framebuffer_create(v2s size, u32 flags);
void r_framebuffer_destroy(r_framebuffer *fb);
void r_framebuffer_update_size(r_framebuffer *fb, v2s size);




#endif
