#include <Vk/Image/Image.hpp>
#include <Utilities/Utilities.hpp>

Vk::Image::Image(
    std::shared_ptr<Vk::Device> device,
    VkImageType imageType,
    uint32_t width, uint32_t height,
    VkFormat format,
    VkImageUsageFlags usage,
    VkMemoryPropertyFlags memoryProps,
    uint32_t arrayLayers,
    VkImageCreateFlags flags,
    VkImageTiling tiling,
    VkSharingMode sharingMode
) :
    m_device(device),
    m_format(format),
    dims(width, height)
{
    VkImageCreateInfo imageInfo{};
    imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    imageInfo.imageType = imageType;
    imageInfo.extent.width = width;
    imageInfo.extent.height = height;
    imageInfo.extent.depth = 1;
    imageInfo.mipLevels = 1;
    imageInfo.arrayLayers = arrayLayers;
    imageInfo.format = format;
    imageInfo.tiling = tiling;
    imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    imageInfo.usage = usage;
    imageInfo.sharingMode = sharingMode;
    imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
    imageInfo.flags = flags;

    VmaAllocationCreateInfo allocInfo = {};
    allocInfo.usage = VMA_MEMORY_USAGE_UNKNOWN;
    allocInfo.requiredFlags = memoryProps;

    if (vmaCreateImage(device->getAllocator(), &imageInfo, &allocInfo, &m_image, &m_allocation, nullptr) != VK_SUCCESS)
    {
        crash("Failed to create image!");
    }
}

Vk::Image::~Image()
{
    vmaDestroyImage(m_device->getAllocator(), m_image, m_allocation);
}

VkImage Vk::Image::inner()
{
    return m_image;
}

VkFormat Vk::Image::getFormat()
{
    return m_format;
}

glm::uvec2 Vk::Image::getDims()
{
    return dims;
}