/* date = July 11th 2022 1:57 pm */

#ifndef RENDER_ABS_H
#define RENDER_ABS_H

// NOTE(allen): Defines the backend facing part
// of the render layer. A render implementor must
// implement these functions and only observes
// these types.
//
// These details are *NOT* hidden from the user.
// The user must also see this part of the API.


/* TODO(allen): 
** 
** RESEARCH
**  [ ] Anti-aliasing for rotated quads
**  [ ] Fix banding in very large gradients
*/

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

typedef U32 R_QuadFlags;
enum{
  R_QuadFlag_SharpCornerTR = (1 << 0),
  R_QuadFlag_SharpCornerTL = (1 << 1),
  R_QuadFlag_SharpCornerBR = (1 << 2),
  R_QuadFlag_SharpCornerBL = (1 << 3),
  R_QuadFlag_HzGradient    = (1 << 4),
  R_QuadFlag_Clipped       = (1 << 5),
};

typedef struct R_Quad{
  // shape
  RectF32 xy;
  F32 radius;
  F32 thick;
  F32 theta;
  
  // color
  U32 c[2];
  
  // uv
  RectF32 uv;
  
  // flags
  R_QuadFlags flags;
  
  // clip
  RectF32 clip;
} R_Quad;

typedef struct R_QuadNode{
  struct R_QuadNode *next;
  R_Quad *quads;
  U64 count;
} R_QuadNode;

typedef void R_Texture;


////////////////////////////////
// NOTE(allen): Render Abstract API Functions

//// backend hider API ////
function B32  r_backend_is_inited(void);
function B32  r_backend_init(void);
function B32  r_backend_equip_window(GFX_Window *window);
function void r_backend_begin(GFX_Window *window);
function void r_backend_end(void);

//// rendering ////
function B32 r_renderer_is_inited(void);
function B32 r_renderer_init(void);

function B32 r_canvas_init(V2S32 canvas_dim);
function B32 r_show_canvas_on_activated_window(void);

// submits must occur between begin and end
function B32 r_submit_quads(R_QuadNode *first_node, U64 total_count,
                            R_Texture *texture);

// texture width and height must be positive powers of 2.
function R_Texture* r_texture_create(void *data, U32 w, U32 h);
function B32        r_texture_update(R_Texture *texture,
                                     void *data, U32 w, U32 h,
                                     U32 x, U32 y);
function B32        r_texture_destroy(R_Texture *texture);
function B32        r_texture_valid(R_Texture *texture);

#endif //RENDER_ABS_H
