#pragma once

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

#include "assets.h"

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

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

typedef unsigned int VertexBuffer;
typedef unsigned int IndexBuffer;
typedef unsigned int PipelineHandle;
typedef unsigned int ShaderHandle;
typedef unsigned int VertexArray;
typedef unsigned int UBO;

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

typedef struct rMesh
{
	rIndexedBuffer buffer;
	apMatProps material;
	u32 texture;
} rMesh;

ArrayType(rMesh);

typedef struct rModel
{
	rMeshArray meshes;
} rModel;

typedef struct Renderer
{
	RGFW_window 	 *window;
	PipelineHandle pipelines[PIPELINE_MAX];
	rIndexedBuffer models[MODEL_ASSET_MAX];
} Renderer;

// ::Init::Decl::

static b32 Init(Renderer *renderer);
static b32 InitModels(Renderer *renderer);
static PipelineHandle CreatePipeline();
static VertexBuffer CreateVertexBuffer();
static IndexBuffer CreateIndexBuffer();
static VertexArray CreateVertexArray();
static ShaderHandle CreateShader(int type);
static PipelineHandle BuildPipeline(PipelineCreateInfo *create_info);
static UBO CreateUBO(rawptr data, u32 size);
static b32 BuildShader(ShaderHandle *handle,  char *asset);

// ::Draw::Decl::

static void DrawIndexedBuffer(rIndexedBuffer *buffer);

// ::Buffers::Decl::

static rIndexedBuffer rLoadModel(char *asset);
static rIndexedBuffer CreateIndexedBuffer(rawptr vert_data, u32 vcount, rawptr idx_data, u32 icount);

// ::Textures::Decl::

static u32 CreateTexture(rawptr data, u32 width, u32 height, u32 channels);

// ::Draw::Decl::

static void DrawMeshBuffer(rIndexedBuffer *mesh);

