#pragma once

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

#define PXL8_DEFAULT_ATLAS_ENTRY_CAPACITY 64
#define PXL8_DEFAULT_ATLAS_SIZE 1024
#define PXL8_DEFAULT_SPRITE_CACHE_CAPACITY 64
#define PXL8_MAX_ERROR_SIZE 2048
#define PXL8_MAX_KEYS 256
#define PXL8_MAX_PALETTE_SIZE 256
#define PXL8_MAX_PATH 256

typedef float    f32;
typedef double   f64;
typedef int8_t   i8;
typedef int16_t  i16;
typedef int32_t  i32;
typedef int64_t  i64;
typedef uint8_t  u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

#if defined(__SIZEOF_INT128__)
typedef __int128_t  i128;
typedef __uint128_t u128;
#endif

typedef enum pxl8_pixel_mode {
    PXL8_PIXEL_INDEXED = 1,
    PXL8_PIXEL_HICOLOR = 2,
    PXL8_PIXEL_RGBA = 4,
} pxl8_pixel_mode;

typedef enum pxl8_cursor {
    PXL8_CURSOR_ARROW,
    PXL8_CURSOR_HAND
} pxl8_cursor;

typedef enum pxl8_resolution {
    PXL8_RESOLUTION_240x160,
    PXL8_RESOLUTION_320x180,
    PXL8_RESOLUTION_320x240,
    PXL8_RESOLUTION_640x360,
    PXL8_RESOLUTION_640x480,
    PXL8_RESOLUTION_800x600,
    PXL8_RESOLUTION_960x540
} pxl8_resolution;

typedef enum pxl8_result {
    PXL8_OK = 0,
    PXL8_ERROR_ASE_INVALID_FRAME_MAGIC,
    PXL8_ERROR_ASE_INVALID_MAGIC,
    PXL8_ERROR_ASE_MALFORMED_CHUNK,
    PXL8_ERROR_ASE_TRUNCATED_FILE,
    PXL8_ERROR_FILE_NOT_FOUND,
    PXL8_ERROR_INITIALIZATION_FAILED,
    PXL8_ERROR_INVALID_ARGUMENT,
    PXL8_ERROR_INVALID_COORDINATE,
    PXL8_ERROR_INVALID_FORMAT,
    PXL8_ERROR_INVALID_SIZE,
    PXL8_ERROR_NOT_INITIALIZED,
    PXL8_ERROR_NULL_POINTER,
    PXL8_ERROR_OUT_OF_MEMORY,
    PXL8_ERROR_SCRIPT_ERROR,
    PXL8_ERROR_SYSTEM_FAILURE
} pxl8_result;

typedef struct pxl8_bounds {
    i32 x, y;
    i32 w;
    i32 h;
} pxl8_bounds;

typedef struct pxl8_input_state {
    bool keys_down[PXL8_MAX_KEYS];
    bool keys_pressed[PXL8_MAX_KEYS];
    bool keys_released[PXL8_MAX_KEYS];

    bool mouse_buttons_down[3];
    bool mouse_buttons_pressed[3];
    bool mouse_buttons_released[3];
    i32 mouse_wheel_x;
    i32 mouse_wheel_y;
    i32 mouse_x;
    i32 mouse_y;
    i32 mouse_dx;
    i32 mouse_dy;
    bool mouse_relative_mode;
} pxl8_input_state;

typedef struct pxl8_point {
    i32 x, y;
} pxl8_point;

typedef struct pxl8_size {
    i32 w, h;
} pxl8_size;

typedef struct pxl8_viewport {
    i32 offset_x, offset_y;
    i32 scaled_width, scaled_height;
    f32 scale;
} pxl8_viewport;
