#pragma once

typedef enum Pipeline_e 
{
	PIPELINE_CUBE,
	PIPELINE_GUI,

	PIPELINE_MAX,
} PipelineHandle;

typedef enum PipelineType_e
{
	PIPELINE_TYPE_GRAPHICS = 0,
	PIPELINE_TYPE_COMPUTE = 1,
} PipelineType;

typedef enum RenderBufferType_e
{
	RENDER_BUFFER_TYPE_NONE = 0x0000,
	RENDER_BUFFER_TYPE_VERTEX = 0x001,
	RENDER_BUFFER_TYPE_INDEX = 0x002,
	RENDER_BUFFER_TYPE_UNIFORM = 0x004,
	RENDER_BUFFER_TYPE_STAGING = 0x008,
	RENDER_BUFFER_TYPE_STORAGE = 0x010,
} RenderBufferType;

typedef enum VertexAttrType_e
{
	VERTEX_ATTRIBUTE_TYPE_VERTEX = 0,
	VERTEX_ATTRIBUTE_TYPE_COLOR = 1,
} VertexAttrType;

// Renderer Front End Types

// Declarations

typedef u16 DescHandle;

// @requirement RenderBuffer type;
// @requirement u32 size;
typedef struct RenderBuffer_t RenderBuffer;
typedef struct PushConst_t PushConst;
typedef struct ShaderGlobals_t ShaderGlobals;

// Types
typedef struct RenderBuffers_t
{
	RenderBuffer *buffers;
	u32 					len;
} RenderBuffers;

// Renderer Front End Types END

// Back End API

// ::Initialization::Header::
b32 InitRenderer(Arena *arena);
void DestroyRenderer();

// ::Buffers::Header::
static b32 CreateBuffer(RenderBuffer *buffer);
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count);
static b32 UploadToBuffer(RenderBuffer **buffer, rawptr *ptr, u32 count, u8 thr_ix);
static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr);
static void BindVertexBuffer(RenderBuffer *buffer);
static void BindIndexBuffer(RenderBuffer *buffer);

// ::Uniforms::Header:: ::PushConstants::Header::
static void GetViewportSize(Vec2 *size);
static void SetGlobalUniform(ShaderGlobals *globals);
static void SetPushConstants(PushConst *pc);
static DescHandle UploadImageUniform();

// ::Config::Header::
static void SetRenderResolution(u32 x, u32 y);
static void SetRendererAvailableThreads(u32 n);

// ::Rendering::Header::
static b32 BeginFrame();
static b32 FinishFrame();
static void DrawIndexed(u32 index_count, u32 instance_count);
static void BindPipeline(PipelineHandle handle, PipelineType type);

#if STG_VULKAN_RENDERER
#include "renderer_vulkan.h"
#endif

#if STG_OPENGL_RENDERER
#error Not yet implemented
#endif

#if STG_WEBGL_RENDERER
#error Not yet implemented
#endif

#if STG_DX11_RENDERER && __linux__
#include "renderer_d3d11.h"
#endif
