#ifndef VULKAN_BUFFER_HPP_
#define VULKAN_BUFFER_HPP_

#include <Utilities/Extern.hpp>
#include <Vk/Device/Device.hpp>

namespace Vk
{
    /**
     * @brief Represents a Vulkan buffer.
     */
    class Buffer
    {
    private:
        std::shared_ptr<Vk::Device> m_device;
        VkBuffer m_buffer;
        size_t m_size;
        VmaAllocation m_allocation;
        void *m_hostdata;
    
    public:
        /**
         * @brief Construct and allocate a new buffer.
         * 
         * @param device The device on which to allocate.
         * @param size The buffer size.
         * @param usage The usage of this buffer.
         * @param memoryProps Memory property flags.
         * @param sharingMode The sharing mode (exclusive by default).
         */
        Buffer(
            std::shared_ptr<Vk::Device> device,
            size_t size,
            VkBufferUsageFlags usage,
            VkMemoryPropertyFlags memoryProps,
            VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE
        );
        Buffer(const Buffer &) = delete;
        ~Buffer();

        /**
         * @brief Return the wrapped buffer.
         */
        VkBuffer inner();

        /**
         * @brief Return the host data pointer.
         * 
         * If this buffer was not allocated with the `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`,
         * then calling this method crashes the game.
         */
        void* hostdata();

        /**
         * @brief Make the specified section of this non-coherent buffer visible to the GPU.
         */
        void flush(VkDeviceSize offset, VkDeviceSize size);

        /**
         * @brief Get the size of the buffer.
         */
        size_t getSize();
    };
}

#endif