#include "resources.h"
#include "stdint.h"
#include "utils/dictionary.h"
#include "utils/debug.h"

char const *RESOURCE_DIRECTORY = "resources";

typedef enum ResourceType {
    MODEL_RESOURCE = 0, TEXTURE_RESOURCE
} ResourceType;

typedef struct ResourceContainer {
    uint32_t rid;
    char const *resource_name;
    ResourceType type;
    union {
        Model model;
        Texture texture;
    };
} ResourceContainer;

static Dictionary g_resources = {};

static inline
void Internal_CleanResourceContainer(ResourceContainer *container) {
    switch(container->type) {
    case MODEL_RESOURCE:
        UnloadModel(container->model);
        return;
    case TEXTURE_RESOURCE:
        UnloadTexture(container->texture);
        return;
    }
    UNREACHABLE("CleanResourceContainer: Cleanup function not defined for %u", container->type);
}

static inline
void InitializeResourceDirectory() {
    // if there is a resource directory in the working directory, prioritize that for debugging
    if(DirectoryExists(RESOURCE_DIRECTORY)) {
        ChangeDirectory(TextFormat("%s/%s", GetWorkingDirectory(), RESOURCE_DIRECTORY));
        LOG_WARNING("Using working dir resources, this is possible for debug purposes.");
    }
    // check application installation directory for a resource directory
    // this is the default running environment
    char const *installation_resource_dir = TextFormat(GetApplicationDirectory(), RESOURCE_DIRECTORY);
    if(DirectoryExists(installation_resource_dir)) {
        ChangeDirectory(installation_resource_dir);
        return;
    }
    UNREACHABLE("Failed to find resource directory");
}

void InitializeResourceSubsystem() {
    InitializeResourceDirectory();
    g_resources = dictionary_from_type(ResourceContainer);
}

void CleanResourceSubsystem() {
    list_foreach(ResourceContainer *,container, &g_resources.list)
        Internal_CleanResourceContainer(container);
    dictionary_empty(&g_resources);
}

