/* date = July 12th 2023 6:01 pm */

#ifndef RENDER_HELPER_H
#define RENDER_HELPER_H

// NOTE(allen): Defines helpers for the user of
// the render layer. The user may bypass this layer
// (and in fact must most of the time).

////////////////////////////////
// NOTE(allen): Render Types

#if !defined(R_BATCH_CHUNK_MAX)
# define R_BATCH_CHUNK_MAX Thousand(14)
#endif

typedef struct R_Batch{
  // chaining
  struct R_Batch *next;
  
  // batch vertex data
  R_QuadNode *first;
  R_QuadNode *last;
  U64 node_count;
  U64 total_count;
  
  // batch uniform data
  R_Texture *texture;
} R_Batch;

typedef struct R_List{
  R_Batch *first_batch;
  R_Batch *last_batch;
  U64 batch_count;
} R_List;

typedef struct R_Ctx{
  // state
  FONT_Baked *font;
  R_Texture *texture;
  B32 clip_enabled;
  RectF32 clip_rect;
  
  // outputs
  Arena *arena;
  R_List *list;
} R_Ctx;

typedef struct R_Font{
  FONT_Baked *baked;
  R_Texture  *texture;
} R_Font;

////////////////////////////////
// NOTE(allen): Render Helper Functions

//// render wrappers ////

// init selected graphics API & the renderer backend
function B32  r_init(void);

// flushing a list (submitting all batches)
function void r_flush(R_List *list);

// font preperation
function R_Font*
r_font_bake_and_build_texture(Arena *arena, FONT_Loose *loose,
                              FONT_PackParams *packp);

//// render batch helpers ////

// directly operating on a batch
function void r_batch_push_quad(Arena *arena, R_Batch *batch, R_Quad *quad);
function void r_batch_push_string(Arena *arena, R_Batch *batch,
                                  FONT_Baked *font, String8 string,
                                  V2F32 p, U32 c, RectF32 *clip_maybe);

// using a local render context
function R_Ctx r_ctx_make(Arena *out_arena, R_List *out_list);
function void  r_ctx_font(R_Ctx *ctx, R_Font *font);
function void  r_ctx_clip(R_Ctx *ctx, B32 enable, RectF32 rect);

function void r_quad(R_Ctx *ctx, R_Quad *quad, R_Texture *tex);

function void r_rect(R_Ctx *ctx, RectF32 xy, F32 r, U32 c_lin);
function void r_vrt_line(R_Ctx *ctx, F32 x, RangeF32 y, U32 c_lin);
function void r_segment(R_Ctx *ctx, V2F32 p0, V2F32 p1, F32 r, U32 c_lin);
function void r_string(R_Ctx *ctx, String8 string, V2F32 p, U32 c_lin);
function void r_char(R_Ctx *ctx, U64 cp, V2F32 p, U32 c_lin);

// helpers for applying context state
function void r_ctx_apply_clip(R_Ctx *ctx, R_Quad *quad_inout);


// NOTE(allen): These calls start a new batch on the render list. The
// rest of the calls use this automatically to handle texture
// parameters for the user. The user should generally not need to
// call them.
function void r_new_batch(Arena *arena, R_List *list);
function void r_prep_batch(Arena *arena, R_List *list, R_Texture *texture);

#endif //RENDER_USER_H
