#ifndef BREEZE_GAME_H
#define BREEZE_GAME_H

#include "core/logger.h"

typedef bool (*BzAppInitFunc)(void *);
typedef void (*BzAppUpdateFunc)(float, void *);
typedef void (*BzAppRenderFunc)(float, void *);
typedef void (*BzAppDeinitFunc)(void *);

typedef struct BzAppDesc {
    int32_t    width;
    int32_t    height;
    const char *title;
    int32_t fps;

    BzAppInitFunc   init;
    BzAppUpdateFunc update;
    BzAppRenderFunc render;
    BzAppDeinitFunc deinit;

    void *userData;
} BzAppDesc;

extern bool bzMain(BzAppDesc *appDesc, int argc, const char **argv);

#ifdef BZ_ENTRYPOINT
#include <raylib.h>


int main(int argc, const char **argv) {
    if (!bzLoggerInit())
        return 1;
    bzLoggerSetLevel(BZ_LOG_INFO);
    bzLogInfo("[Breeze] Logger initialized successfully.");

    BzAppDesc appDesc = {
            1280,
            720,
            "Breeze Engine",
            60
    };

    bool successful = bzMain(&appDesc, argc, argv);
    if (!successful) return 1;

    // Validate
    if (!appDesc.render) {
        bzLogFatal("[Breeze] No render function specifies.");
        return 1;
    }
    bzLogInfo("[Breeze] User initialization (bzMain) successful.");

    InitWindow(appDesc.width, appDesc.height, appDesc.title);
    SetTargetFPS(appDesc.fps);
    // Initialize modules

    // User initialize
    if (appDesc.init && !appDesc.init(appDesc.userData)) {
        return 1;
    }

    while (!WindowShouldClose()) {
        if (appDesc.update)
            appDesc.update(0.0f, appDesc.userData);
        if (appDesc.render)
            appDesc.render(0.0f, appDesc.userData);
    }

    // User deinitialize
    if (appDesc.deinit)
        appDesc.deinit(appDesc.userData);

    // Deinitialize modules

    CloseWindow();
    bzLoggerDeinit();

    return 0;
}
#endif

#endif //BREEZE_GAME_H
