////////////////////////////////////////////////
////////////////////////////////////////////////
///////////////   INTRODUCTION   ///////////////
////////////////////////////////////////////////
////////////////////////////////////////////////

/*
**
** TODO: instructions will go here
**
*/

#if !defined(MR4TH_BASE_H)
# error mr4th_buffer_operators.h should be included after mr4th_base.h
#endif


////////////////////////////////////////////////
////////////////////////////////////////////////
///////////////   DECLARATIONS   ///////////////
////////////////////////////////////////////////
////////////////////////////////////////////////

#if !defined(MR4TH_ASCII_DECLARATIONS)
#define MR4TH_ASCII_DECLARATIONS

////////////////////////////////
// Types: Histogram

typedef struct HIST_Data{
  F32 *vals;
  U64 stride;
  U64 count;
} HIST_Data;

typedef struct HIST_Stats{
  F32 mean;
  F32 sd;
  F32 min;
  F32 max;
} HIST_Stats;

typedef struct HIST_ControlParams{
  B32 integer;
  F32 precision;
  U32 width;
  U32 height;
} HIST_ControlParams;

typedef struct HIST_Bar{
  F32 height;
  U32 data_point_count;
  U32 first_bucket_idx;
} HIST_Bar;

////////////////////////////////
// Functions: Histogram

MR4TH_SYMBOL HIST_Data  hist_data(F32 *vals, U64 stride, U64 count);
MR4TH_SYMBOL HIST_Stats hist_stats(HIST_Data *data);
MR4TH_SYMBOL void       hist_stats_str8(Arena *arena, String8List *out, HIST_Stats *stats);
MR4TH_SYMBOL void       hist_stats_fprint(FILE *out, HIST_Stats *stats);

MR4TH_SYMBOL void hist_print(STREAM *stream, HIST_Data *data, HIST_ControlParams *params);
MR4TH_SYMBOL void hist_fprint(FILE *out, HIST_Data *data, HIST_ControlParams *params);


////////////////////////////////
// Types: Table

typedef U32 TABLE_CellFlags;
enum{
  TABLE_CellFlag_LeftAlign   = 0x0,
  TABLE_CellFlag_RightAlign  = 0x1,
  TABLE_CellFlag_CenterAlign = 0x2,
  TABLE_CellFlag_AlignMask   = 0x3,
};

typedef struct TABLE_Cell{
  struct TABLE_Cell *next;
  String8 string;
  TABLE_CellFlags flags;
} TABLE_Cell;

typedef struct TABLE_Row{
  struct TABLE_Row *next;
  TABLE_Cell *first_cell;
  TABLE_Cell *last_cell;
  U64 cell_count;
  B32 has_hz_separator;
} TABLE_Row;

typedef struct TABLE{
  TABLE_Row *first_row;
  TABLE_Row *last_row;
  U64 row_count;
  U64 col_count;
  TABLE_CellFlags default_cell_flags;
} TABLE;

typedef struct TABLE_Style{
  U8 height[3];
  U8 width[3];
  char *knots[3][3];
  char *hz_sep[3];
  char *vr_sep[3];
} TABLE_Style;

////////////////////////////////
// Functions: Table

MR4TH_SYMBOL TABLE* table_begin(Arena *arena);

MR4TH_SYMBOL void   table_default_align(TABLE *table, TABLE_CellFlags align);

MR4TH_SYMBOL void   table_row(Arena *arena, TABLE *table);
MR4TH_SYMBOL void   table_hz_separator(Arena *arena, TABLE *table);

MR4TH_SYMBOL void   table_cell(Arena *arena, TABLE *table, String8 string);
MR4TH_SYMBOL void   table_cellf(Arena *arena, TABLE *table, char *fmt, ...);

MR4TH_SYMBOL void   table_cell_align(TABLE *table, TABLE_CellFlags align);

MR4TH_SYMBOL void   table_print(STREAM *stream, TABLE *table, TABLE_Style *style);
MR4TH_SYMBOL void   table_fprint(FILE *out, TABLE *table, TABLE_Style *style);

MR4TH_SYMBOL U64    table_get_width(TABLE *table, TABLE_Style *style);

MR4TH_SYMBOL_STATIC TABLE_Style table_plain_style = {
  /* height */ {0},
  /* width  */ {0, 1, 0},
  /* knots  */ {0},
  /* hz_sep */ {0},
  /* vr_sep */ {0, " ", 0},
};

MR4TH_SYMBOL_STATIC TABLE_Style table_wire_style = {
  /* height */ {1, 1, 1},
  /* width  */ {2, 3, 2},
  /* knots  */ {{"+-", "+-", "+-"}, {"-+-", "-+-", "-+-"}, {"-+", "-+", "-+"}},
  /* hz_sep */ {"-", "-", "-"},
  /* vr_sep */ {"| ", " | ", " |"},
};

MR4TH_SYMBOL_STATIC TABLE_Style table_matrix_style = {
  /* height */ {0},
  /* width  */ {2, 1, 2},
  /* knots  */ {0},
  /* hz_sep */ {0},
  /* vr_sep */ {"[ ", " ", " ]"},
};

#endif /* MR4TH_ASCII_DECLARATIONS */


// TODO(allen): yuck
////////////////////////////////////////////////
////////////////////////////////////////////////
//////////////////   TESTS   ///////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////

#if defined(MR4TH_ASCII_TESTS)
MR4TH_SYMBOL_STATIC void ascii_test1(void);
#endif /* MR4TH_ASCII_TESTS */

/*
** TODO:
**
** [ ] Built in indent management printing system?
** 
** [ ] Explore the "Render" Approach
**     -> would let me place small grids within bigger grids
**        like the histogram bars within the larger diagram
**
** [ ] Histogram Features
**     [ ] Title [ ] Labels [ ] Scales
** 
** [ ] Table Features:
**     [ ] Left/Right/Center align text in each cell
**     [ ] Support Newlines in Cells?
**     [ ] Newlines in Cells Modes?
**
** [ ] Pluggable str8_pushf/m4_fprintf programming
**
*/

