#ifndef CONTEXT_H
#define CONTEXT_H


#include "rendering/internal_api.h"
#include "textures/internal_api.h"
#include "input.h"
#include "twn_engine_api.h"

#include <SDL2/SDL.h>

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


typedef struct context {
    /* the program's actual argc and argv */
    int argc;
    char **argv;

    struct texture_cache texture_cache;
    struct input_state input;

    struct primitive_2d *render_queue_2d;
    struct mesh_batch_item *uncolored_mesh_batches;
    struct text_cache text_cache;

    struct audio_channel_item *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 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];
    int64_t delta_time; /* preserves real time frame delta with no manipilation */
    uint64_t tick_count;

    /* set just once on startup */
    uint64_t random_seed;

    /* this should be a multiple of TICKS_PER_SECOND */
    /* use it to simulate low framerate (e.g. at 60 tps, set to 2 for 30 fps) */
    /* it can be changed at runtime; any resulting logic anomalies are bugs */
    unsigned int update_multiplicity;

    SDL_GLContext *gl_context;
    SDL_Window *window;
    uint32_t window_id;
    int window_w;
    int window_h;

    /* you may read from and write to these from game code */
    void *udata;

    bool debug;
    bool is_running;
    bool resync_flag;
    bool was_successful;
    bool window_size_has_changed;
    bool initialization_needed;
} t_ctx;

TWN_API extern t_ctx ctx;

#endif
