#pragma once

#define RGFW_IMPLEMENTATION
#include "../external/rgfw/RGFW.h"

#include "assets.h"

constexpr u64 FRAME_OVERLAP = 2;
constexpr u32 INVALID_INDEX = UINT32_MAX;

typedef enum Pipeline_e
{
	PIPELINE_PBR,
	//PIPELINE_GUI,
	PIPELINE_MAX,
} Pipeline;

typedef enum PBRPropType_e
{
	PPT_NONE = 0x0000,
	PPT_ALBEDO_VALUE = 0x0001,
	PPT_AMBIENT_VALUE = 0x0002,
	PPT_SPECULAR_VALUE = 0x0004,
	PPT_ALBEDO_TEX = 0x0008,
	PPT_AMBIENT_TEX = 0x0010,
	PPT_SPECULAR_TEX = 0x0020,
} PBRPropType;

typedef struct PipelineCreateInfo
{
	char *vertex_shader;
	char *fragment_shader;
} PipelineCreateInfo;

typedef struct rIndexedBuffer
{
	i64 icount, ioffset;
	u32 vao, buffer;
} rIndexedBuffer;

typedef struct rPBRState
{
	u32 channels;
	b32 albedo_tex;
	b32 ambient_tex;
	b32 specular_tex;
} rPBRState;

typedef struct rMesh
{
	apMatTextures textures;
	uintptr				idx_offset;
	u64						length;
	u32 	  			mat_buffer;
	u32						state_buffer;
	u32 					type;
} rMesh;

ArrayType(rMesh);

typedef struct rModel
{
	rIndexedBuffer buffer;
	rMeshArray meshes;
	u32Array   textures;
} rModel;

typedef struct Renderer
{
	RGFW_window 	 *window;
	GLuint				 pipelines[PIPELINE_MAX];
	rModel 				 models[MODEL_ASSET_MAX];
	GLuint				 mat_buf;
	Arena 				 *perm_arena;
	Arena					 *frame_arenas[FRAME_OVERLAP];
} Renderer;

PipelineCreateInfo g_Pipeline_Create_Info[] = {
	{ .vertex_shader = "shaders/pbr.vert", .fragment_shader = "shaders/pbr.frag" },
	//{ .vertex_shader = "shaders/gui.vert", .fragment_shader = "shaders/gui.frag" },
};
