#ifndef RT_VK_PHYSICAL_RESOURCE_MANAGER_H
#define RT_VK_PHYSICAL_RESOURCE_MANAGER_H

#include <stdbool.h>
#include <runtime/runtime.h>
#include <runtime/ds.h>
#include <runtime/threading.h>
#include <renderer/backend_api.h>

#include <volk/volk.h>

#define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMI_VULKAN_FUNCTIONS 0
#include <vk_mem_alloc.h>

struct rt_vk_device;

typedef struct {
    rt_render_resource_type type;
    VmaAllocation allocation;

    union {
        VkBuffer buffer;
        VkImage image;
    };
} rt_vk_physical_resource;

typedef struct {
    struct rt_vk_device *dev;
    VmaAllocator allocator;

    /* Maps handles to slots inside resources */
    rt_hashtable resource_lut;
    rt_vk_physical_resource *resources;
    void *lut_mem;

    uint32_t *free_slots;
    uint32_t free_slot_count;

    rt_rwlock lock;
} rt_vk_physical_resource_manager;

typedef struct {
    rt_result result;
    rt_vk_physical_resource_manager phys_res_mgr;
} rt_create_vk_physical_resource_manager_result;

rt_create_vk_physical_resource_manager_result rtCreateVkPhysicalResourceManager(struct rt_vk_device *dev);

void rtDestroyVkPhysicalResourceManager(rt_vk_physical_resource_manager *phys_res_mgr);

/* rt_physical_resource_manager_i functions */
bool rtVkPhysicalResourceManagerIsPresent(void *o, rt_render_resource_handle handle);
void rtVkPhysicalResourceManagerDestroy(void *o, rt_render_resource_handle handle);
rt_result rtVkPhysicalResourceManagerCreateBuffer(void *o, rt_render_resource_handle h, const rt_render_buffer_desc *desc);
rt_result rtVkPhysicalResourceManagerCreateTexture2D(void *o, rt_render_resource_handle h, const rt_render_texture2d_desc *desc);

#endif
