#ifndef RENDER_TYPES_H
#define RENDER_TYPES_H


//////////////////////////////
//~ 
#if LANG_C
# define r_global extern
#else 
# define r_global no_name_mangle
#endif
#define r_function no_name_mangle

//////////////////////////////
//~ Basic types

typedef struct R_InitReceipt R_InitReceipt;
struct R_InitReceipt
{
  U64 u64[1];
};

//////////////////////////////
//~ Handle types

typedef union R_Handle R_Handle;
union R_Handle
{
  U64 u64[4];
  U32 u32[8];
};

//////////////////////////////
//~ Blending types
typedef enum R_BlendMode
{
  R_BlendMode_Normal,
  R_BlendMode_Additive,
  R_BlendMode_COUNT
}
R_BlendMode;


//////////////////////////////
//~ Texture types
typedef enum R_Tex2DFormat
{
  R_Tex2DFormat_Null,
  R_Tex2DFormat_R8,
  R_Tex2DFormat_RGBA8,
  R_Tex2DFormat_COUNT
} 
R_Tex2DFormat;

typedef enum R_Tex2DSampleKind
{
  R_Tex2DSampleKind_Nearest,
  R_Tex2DSampleKind_Linear,
  R_Tex2DSampleKind_COUNT
}
R_Tex2DSampleKind;

typedef enum R_Tex2DKind
{
  R_Tex2DKind_Static,
  R_Tex2DKind_Dynamic,
}
R_Tex2DKind;

typedef struct R_Slice2F32 R_Slice2F32;
struct R_Slice2F32
{
  R_Handle texture;
  Rng2_F32 region;
};


//////////////////////////////
//~ Instance types
// These are the structures that pass information about render primitives down to the 
// render backend.
typedef struct R_Rect2DInst R_Rect2DInst;
struct R_Rect2DInst
{
  Rng2_F32 dst_rect;
  Rng2_F32 src_rect;
  Vec4_F32 colors[Corner_COUNT];
  F32 corner_radii[Corner_COUNT];
  F32 border_thickness;
  F32 softness;
  F32 omit_texture;
  F32 _unused_[1];
};


//////////////////////////////
//~ Batch type
typedef struct R_Batch R_Batch;
struct R_Batch
{
  R_Batch *next;
  U8 *v;
  U64 byte_count;
  U64 byte_cap;
  U64 instance_count;
  U64 instance_cap;
};

typedef struct R_BatchList R_BatchList;
struct R_BatchList
{
  R_Batch *first;
  R_Batch *last;
  U64 batch_count;
  U64 instance_count;
  U64 byte_count;
};

typedef struct R_BatchGroup2DParams R_BatchGroup2DParams;
struct R_BatchGroup2DParams
{
  R_Handle albedo_tex; // Color texture to go with this batch of 2D renders
  R_Tex2DSampleKind albedo_tex_sample_kind;
  Mat3x3_F32 xform2d;
  Rng2_F32 clip;
};

typedef struct R_BatchGroup2DNode R_BatchGroup2DNode;
struct R_BatchGroup2DNode
{
  R_BatchGroup2DNode *next;
  R_BatchList batches;
  R_BatchGroup2DParams params;
};

typedef struct R_BatchGroup2DList R_BatchGroup2DList;
struct R_BatchGroup2DList
{
  R_BatchGroup2DNode *first;
  R_BatchGroup2DNode *last;
  U64 count;
};




//////////////////////////////
//~ Pass types
typedef enum R_PassKind
{
  R_PassKind_Null,
  R_PassKind_UI,
  R_PassKind_COUNT
}
R_PassKind;

typedef struct R_PassParams_UI R_PassParams_UI;
struct R_PassParams_UI
{
  Rng2_F32 viewport;
  R_BatchGroup2DList rects;
};

typedef struct R_Pass R_Pass;
struct R_Pass
{
  R_PassKind kind;
  union
  {
    void *params;
    R_PassParams_UI *params_ui;
  };
};

typedef struct R_PassNode R_PassNode;
struct R_PassNode
{
  R_PassNode *next;
  R_Pass v;
};

typedef struct R_PassList R_PassList;
struct R_PassList
{
  R_PassNode *first;
  R_PassNode *last;
  U64 count;
};


//////////////////////////////
//~ Handle type functions

root_function R_Handle R_handle_zero(void);
root_function B32 R_handle_match(R_Handle a, R_Handle b);
root_function B32 R_handle_is_zero(R_Handle handle);

//////////////////////////////
//~ Texture type functions
root_function U64 R_bytes_per_pixel_from_tex2d_format(R_Tex2DFormat fmt);
//////////////////////////////
//~ Pass building helper functions
root_function R_Pass *R_pass_list_push(Arena *arena, R_PassList *list, R_PassKind kind);
root_function void *R_batch_list_push(Arena *arena, R_BatchList *list, U64 cap, U64 instance_size);
#define R_batch_list_push_struct(arena, list, cap, type) (type *)R_batch_list_push((arena), (list), (cap), sizeof(type))

//////////////////////////////
//~ Other??


#endif /* RENDER_TYPES_H */
