#ifndef TWN_ENGINE_CONTEXT_C_H
#define TWN_ENGINE_CONTEXT_C_H

#include "twn_context.h"
#include "twn_textures_c.h"
#include "twn_audio_c.h"
#include "twn_input_c.h"
#include "twn_engine_api.h"
#include "rendering/twn_draw_c.h"

#include <SDL2/SDL.h>
#include <toml.h>

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


typedef struct EngineContext {
    /* user code facing context */
    Context game_copy;
    /* engine-side context, copied to `game_copy` before every frame */
    Context game;

    InputState input;

    /* the program's actual argc and argv */
    int argc;
    char **argv;
    /* where the app was run from, used as the root for packs */
    char *base_dir;
    char *title;

    Vec2 window_dims;
    Rect viewport_rect;
    float viewport_scale;

    /* configuration */
    toml_table_t *config_table;
    int64_t base_render_width;
    int64_t base_render_height;
    int64_t ticks_per_second;
    int64_t keybind_slots;
    int64_t texture_atlas_size;
    int64_t font_texture_size;
    int64_t font_oversampling;
    TextureFilter font_filtering;

    /* rendering */
    Primitive2D *render_queue_2d;
    MeshBatchItem *uncolored_mesh_batches;
    MeshBatchItem *billboard_batches;
    TextCache text_cache;
    TextureCache texture_cache;

    /* audio */
    AudioChannelItem *audio_channels;
    AudioChannel *unnamed_audio_channels;
    SDL_AudioDeviceID audio_device;
    int audio_stream_frequency;
    SDL_AudioFormat audio_stream_format;
    uint8_t audio_stream_channel_count;

    /* main loop machinery */
    int64_t delta_time; /* preserves real time frame delta with no manipilation */
    int64_t clocks_per_second;
    int64_t prev_frame_time;
    int64_t desired_frametime;  /* how long one tick should be */
    int64_t frame_accumulator;
    int64_t delta_averager_residual;
    int64_t time_averager[4];

    SDL_GLContext *gl_context;
    SDL_Window *window;
    uint32_t window_id;

    Color background_color;

    bool is_running;
    bool window_size_has_changed;
    bool resync_flag;
    bool was_successful;
    bool render_double_buffered;
    /* signals mouse focus, used to disable mouse capture */
    bool window_mouse_resident;
    bool audio_initialized;
    bool push_audio_model;
    bool cull_faces;
} EngineContext;

/* TODO: does it need to be marked with TWN_API? */
TWN_API extern EngineContext ctx;

#endif
