#include "red_scarf_engine.h"
#include "graphics/rse_graphics.h"
#include "utilities/commons.h"
#include "utilities/errors_common.h"
#include "utilities/time_utils.h"
#include "events/rse_events_manager.h"

struct rse_context_t {
    struct graphics_context_t graphics_context;
    struct events_context_t events_context;
};

static void fps_print(double* start_time)
{
    static uint32_t frame_counts = 0U;

    double now = time_get_sec_from_start();

    frame_counts++;
    if ((now - *start_time) > 1.0) {
        printf("\rFPS: %u", frame_counts);
        fflush(stdout);
        frame_counts = 0;
        *start_time += 1.0;
    }
}

rse_err_t rse_init(rse_context* context)
{
    rse_err_t status = RSE_ERROR_NO_ERROR;
    struct rse_context_t* rse_context = NULL;

    rse_malloc(*context, sizeof(struct rse_context_t));

    rse_context = *context;

    SDL_Init(SDL_INIT_VIDEO);
    SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);

    STATUS_CHECK(time_init());
    STATUS_CHECK(rse_events_init(&rse_context->events_context));
    STATUS_CHECK(rse_graphics_init(&rse_context->graphics_context));

    return RSE_ERROR_NO_ERROR;
}

rse_err_t rse_run(rse_context context)
{
    rse_err_t status = RSE_ERROR_NO_ERROR;
    double start_time;

    start_time = time_get_sec_from_start();

    STATUS_CHECK(rse_graphics_test_function(&context->graphics_context));

    STATUS_CHECK(rse_graphics_run(&context->graphics_context));
    while(true) {
        time_update();
        rse_events_main_loop(&context->events_context);
        if (context->events_context.should_stop == EVENT_SHOULD_STOP_ENGINE_TRUE) {
            break;
        }
        rse_graphics_main_loop(&context->graphics_context);
        fps_print(&start_time);
    }

    rse_graphics_deinit(&context->graphics_context);
    rse_free(context);

    return status;
}
