#ifndef TWN_DRAW_H
#define TWN_DRAW_H

#include "twn_types.h"
#include "twn_option.h"
#include "twn_engine_api.h"

#include <stdbool.h>

/* pushes a sprite onto the sprite render queue */
TWN_API void draw_sprite(char const *texture,
                         Rect        rect,
                         Rect const *texture_region,    /* optional, default: NULL */
                         Color       color,             /* optional, default: all 255 */
                         float       rotation,          /* optional, default: 0 */
                         bool        flip_x,            /* optional, default: false */
                         bool        flip_y,            /* optional, default: false */
                         bool        stretch);          /* optional, default: true */

/* pushes a filled rectangle onto the rectangle render queue */
TWN_API void draw_rectangle(Rect rect, Color color);

/* pushes a filled circle onto the circle render queue */
/* note that its edges may look jagged with a radius larger than 2048 */
TWN_API void draw_circle(Vec2 position, float radius, Color color);

/* TODO: have font optional, with something minimal coming embedded */
TWN_API void draw_text(char const *string,
                       Vec2        position,
                       float       height,              /* optional, default: 22 */
                       Color       color,               /* optional, default: all 0 */
                       char const *font);               /* optional, default: NULL */


TWN_API float draw_text_width(char const *string,
                              float       height,       /* optional, default: 22 */
                              char const *font);        /* optional, default: NULL */

TWN_API void draw_nine_slice(char const *texture,
                             Vec2        corners,
                             Rect        rect,
                             float       border_thickness,  /* optional, default: 0 */
                             Color       color);            /* optional, default: all 255 */

/* pushes a textured 3d triangle onto the render queue */
/* texture coordinates are in pixels */
TWN_API void draw_triangle(char const *texture,
                           Vec3        v0,
                           Vec3        v1,
                           Vec3        v2,
                           Vec2        uv0,
                           Vec2        uv1,
                           Vec2        uv2);

// TODO: decide whether it's needed to begin with?
//       intended usage for it is baked lighting, i would think.
// TODO: instead add optional color parameters to 'draw_triangle'
/* pushes a colored textured 3d triangle onto the render queue */
// void unfurl_colored_triangle(const char *path,
//                              Vec3 v0,
//                              Vec3 v1,
//                              Vec3 v2,
//                              Vec2sh uv0,
//                              Vec2sh uv1,
//                              Vec2sh uv2,
//                              Color c0,
//                              Color c1,
//                              Color c2);

TWN_API void draw_billboard(const char *texture,
                            Vec3 position,
                            Vec2 size,
                            Color color,        /* optional, default: all 255 */
                            bool cylindrical);  /* optional, default: false */

/* sets a perspective 3d camera to be used for all 3d commands */
TWN_API void draw_camera(Vec3 position, float fov, Vec3 up, Vec3 direction);

/* same as draw_camera(), but with specific use case */
/* direction and up vectors are inferred from roll, pitch and yaw parameters (in radians) */
/* return value is direction and up vectors, so that you can use them in logic (such as controllers) */
typedef struct DrawCameraFromPrincipalAxesResult {
    Vec3 direction;
    Vec3 up;
} DrawCameraFromPrincipalAxesResult;
TWN_API DrawCameraFromPrincipalAxesResult draw_camera_from_principal_axes(Vec3 position,
                                                                          float fov,
                                                                          float roll,
                                                                          float pitch,
                                                                          float yaw);

/* expects '*' masks that will be expanded to 6 names: 'up', 'down', 'east', 'west', 'north' and 'south' */
TWN_API void draw_skybox(const char *paths);

TWN_API void draw_fog(float start, float end, float density, Color color);


#ifndef TWN_NOT_C

typedef struct DrawSpriteArgs {
    char const *texture;
    Rect rect;

    m_option_list(
        Rect,    texture_region,
        Color,   color,
        float,   rotation,
        bool,    flip_x,
        bool,    flip_y,
        bool,    stretch )
} DrawSpriteArgs;

TWN_API void draw_sprite_args(DrawSpriteArgs args);
#define m_sprite(...) (draw_sprite_args((DrawSpriteArgs){__VA_ARGS__}))

/* TODO: define more */

#endif /* TWN_NOT_C */

#endif
