// Corresponds roughly to section 6.2 of the Pico 8 manual 
//
// However, all ranges are now half-open.
//
// https://www.lexaloffle.com/dl/docs/pico-8_manual.html
//
#ifndef CROCPARTY_SYS_GRAPHICS_H
#define CROCPARTY_SYS_GRAPHICS_H

#include <stdbool.h>
#include <stdint.h>

#include "sys_data.h"

/**
 * Set the clipping rectangle in pixels.
 * 
 * All drawing operations will be clipped to this rectangle.
 */
void sys_clip_set(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1);

/**
 * Reset the clipping rectangle.
 */
void sys_clip_reset();

/**
 * Set the clipping rectangle in pixels.
 * 
 * This is the same as `sys_clip_set`, but you can pass clip_previous in order 
 * to clip to the previous region.
 */
void sys_clip_set_ext(
    sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, 
    bool clip_previous
);

/**
 * Set the color of the pixel `(x, y)`.
 */
void sys_pixel_set(
    sys_i32 x, sys_i32 y,
    sys_color c
);

/**
 * Get the color of the pixel `(x, y)`.
 * 
 * Returns SYS_COLOR_TRANSPARENT if the pixel is out of bounds.
 */
sys_color sys_pixel_get(
    sys_i32 x, sys_i32 y
);

// TODO: SSET/SGET
// TODO: FGET/FSET
/**
 * Print a string `str` in the color `col`
 */
void sys_print(char* str, sys_i32 x, sys_i32 y, sys_color col);
// TODO: CURSOR? COLOR?

/**
 * Fill the entire screen with color `c`.
 */
void sys_cls(sys_color c);

/**
 * Create a screen offset of `(-x, -y)` for all drawing operations.
 */
void sys_camera_set(sys_i32 x, sys_i32 y);

/**
 * Reset the camera's offset to `(0, 0)`.
 */
void sys_camera_reset();

/**
 * Draw or fill a circle at `(x, y)` with radius `r`.
 * 
 * The circle is centered at the center of the pixel, not at the junction
 * between pixels.
 * 
 * If r is negative, the circle is not drawn.
 * 
 * This is a special case of sys_circ_oval_draw_ext.
 */
void sys_circ_draw(sys_i32 x, sys_i32 y, sys_i32 r, sys_color c);  
void sys_circ_fill(sys_i32 x, sys_i32 y, sys_i32 r, sys_color c);  
void sys_circ_draw_ext(sys_i32 x, sys_i32 y, sys_i32 r, sys_color c, bool fill);

/**
 * Draw or fill an oval in the rectangle from `(x0, y0)` to `(x1, y1)`
 */
void sys_oval_draw(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
void sys_oval_fill(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
void sys_oval_draw_ext(
    sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c, bool fill
);

/**
 * Draw a line from x0 to y0.
 * 
 * The point `(x1, y1)` is not drawn. (because the line is a half-open interval)
 */
void sys_line_draw(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);

/**
 * Draw or fill a rectangle `(x, y, w, h)`
 */
void sys_rect_draw(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
void sys_rect_fill(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
void sys_rect_draw_ext(
    sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c, bool fill
);

/**
 * Set screen palette.
 * 
 * After calling this function, virtual color `c0` will be rendered as
 * real color `rc1`.
 */
void sys_spal_set(sys_color c0, sys_screen_color rc1);

/**
 * Reset screen palette.
 * 
 * After calling this function, all screen colors are (0, 0, 0).
 */
void sys_spal_reset();

/**
 * Set draw palette.
 * 
 * After calling this function, draws using color `c0` will be performed
 * using color `c1` instead.
 * 
 * Any color mapped to `SYS_COLOR_TRANSPARENT` will not actually be drawn.
 */
void sys_dpal_set(sys_color c0, sys_color c1);

/**
 * Reset draw palette.
 * 
 * All colors are mapped to themselves. SYS_COLOR_TRANSPARENT is transparent.
 */
void sys_dpal_reset();

// TODO: SPR
// TODO: SSPR
// TODO: FILLP?


#endif // CROCPARTY_SYS_GRAPHICS_H
