#if !defined(LD_DRAW_CORE_H_)
#define LD_DRAW_CORE_H_

#define D_MAX_RECTS (262144)

typedef struct D_Glyph D_Glyph;
struct D_Glyph {
	F32 advance;

	V2f offset;
	V2f dim;

	R2f box;
};

typedef struct D_Font D_Font;
struct D_Font {
	D_Font *next;

	U32 id;

	F32 line_advance;
	F32 ascent;
	F32 descent;

	F32     *kerning; // @incomplete: we don't load this
	D_Glyph *glyphs;

	Vk_Image image;
};

typedef struct D_Image D_Image;
struct D_Image {
	Str8     name;
	Vk_Image image;
};

typedef struct D_Rect D_Rect;
struct D_Rect {
	U32 texture;

	U32  c[4]; // per-vertex colours
	F32 uv[4];

	F32 angle;
	F32 x, y;
	F32 w, h;

	U32 p0, p1;
};

StaticAssert(sizeof(D_Rect) == 64);

typedef struct D_Animation D_Animation;
struct D_Animation {
	U32 id;

	U32 rows;
	U32 cols;
	F32 frame_time;
	F32 time;

	V2f frame; // size of one frame

	U32 index;
};

struct G_Camera;

#define D_ASSET_HASH_COUNT 128

typedef struct D_AssetHash D_AssetHash;
struct D_AssetHash {
	D_AssetHash *next;

	Str8 value;
	U64  hash;
	U32  id; // texture id
};

typedef struct D_Context D_Context;
struct D_Context {
	Vk_Buffer *rbo;
	Vk_Buffer staging;

	M_Arena *arena;

	U32 n_pipelines;
	Vk_Pipeline *pipelines;

	U32 n_images;
	D_Image *images;

	U32 n_fonts;
	D_Font *fonts;

	U32 max_rects;
	U32 n_rects;
	D_Rect *rects;

	U32 window_width;
	U32 window_height;

	D_AssetHash *lookup[D_ASSET_HASH_COUNT];

	struct G_Camera *camera;
};

typedef U32 D_RectFlags;
enum D_RectFlags {
	D_RECT_IGNORE_ASPECT     = (1 << 0), // by default only width is used as a "dimension"
	D_RECT_PER_VERTEX_COLOUR = (1 << 1), // split colours per vertex
	D_RECT_UV_ASPECT         = (1 << 2), // get the aspect from the uv rect rather than the full image
	D_RECT_FLIP_X            = (1 << 3),
	D_RECT_FLIP_Y            = (1 << 4)
};

typedef struct D_RectOpts D_RectOpts;
struct D_RectOpts {
	D_RectFlags flags;

	U32 texture;

	R2f uv;
	V2f p;

	F32 angle;

	union {
		V2f dim;

		struct {
			F32 w, h;
		};

		struct {
			F32 scale, _h;
		};
	};

	union {
		V4f c;
		V4f vtxc[4];
	};
};

function U32 D_ImageHandle(D_Context *draw, Str8 name);

function void D_AnimationInit(D_Animation *a, U32 id, U32 rows, U32 cols, F32 time);
function R2f  D_AnimationFrame(D_Animation *a);
function void D_AnimationUpdate(D_Animation *a, F32 dt);

function void D_Begin(D_Context *draw, Vk_Frame *frame, U32 max_rects);
function void D_End(D_Context *draw, Vk_Frame *frame);

function void D_Text(D_Context *draw, D_Font *font, Str8 text, F32 x, F32 y);

function void _D_Rect(D_Context *draw, D_RectOpts *opts);
#define D_Rect(draw, x, y, ...) _D_Rect(draw, &(D_RectOpts) { .p = V2F(x, y), .uv = R2F(V2F(0, 0), V2F(1, 1)), .scale = 1, .c = V4F(1, 1, 1, 1), ##__VA_ARGS__ })

function void D_FontLoad(D_Context *draw, Str8 path, F32 size);

#endif  // LD_DRAW_CORE_H_
