#include "arc/engine/engine.h"

//NOTE: some of this file is temporary, mostly to get smthn running so I can test out different ideas
#include <stdlib.h>
#include "arc/engine/state.h"
#include "arc/graphics/window.h"
#include "arc/graphics/renderer.h"
#include "arc/input/mouse.h"
#include "arc/input/keyboard.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
#include "arc/std/handler.h"

//TODO: remove this
//#include <SDL.h>

void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanFn, ARC_Point windowSize){
    *data = (ARC_EngineData *)malloc(sizeof(ARC_EngineData));
    (*data)->window   = NULL;
    (*data)->renderer = NULL;
    (*data)->input    = NULL;
    (*data)->keyboard = NULL;
    (*data)->mouse    = NULL;

    //TODO: set the destroy callback
    ARC_Handler_Create(&((*data)->state), NULL, cleanFn);

    (*data)->dt = 0.0;
    (*data)->running = ARC_False;
    (*data)->windowSize = windowSize;

    ARC_WindowInfo windowInfo = (ARC_WindowInfo){ "title", (*data)->windowSize.x, (*data)->windowSize.y };
    ARC_Window_Create(&((*data)->window), &windowInfo);
    if(arc_errno){
        free(data);
        return;
    }

    ARC_Renderer_CreateWithEngineData(&((*data)->renderer), *data);
    if(arc_errno){
        ARC_Window_Destroy((*data)->window);
        free(data);
    }

    ARC_Input_CreateWithEngineData(&((*data)->input), *data);

    (*data)->keyboard = ARC_Input_GetKeyboard((*data)->input);
    (*data)->mouse    = ARC_Input_GetMouse((*data)->input);
}

void ARC_EngineData_Destroy(ARC_EngineData *data){
    ARC_Mouse_Destroy(data->mouse);
    ARC_Keyboard_Destroy(data->keyboard);
    ARC_Renderer_Destroy(data->renderer);
    ARC_Window_Destroy(data->window);
    ARC_Handler_Destroy(data->state);
}

void ARC_Engine_RunUncapped(ARC_EngineData *data){
    if(arc_errno){
        return;
    }

    //double lastTime = 0, currentTime;

    data->running = ARC_True;
    while(data->running){
        //currentTime = SDL_GetTicks();
        //data->dt = currentTime - lastTime;
        //lastTime = currentTime;

        data->running = ARC_Input_Update(data->input);

        ARC_Handler_Clean(data->state);

        ARC_Handler_Iterate(data->state, ARC_State_Update);

        ARC_Renderer_Clear(data->renderer);

        ARC_Handler_Iterate(data->state, ARC_State_Render);

        ARC_Renderer_Render(data->renderer);
    }
}
