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

Vk::ImageView::ImageView(std::shared_ptr<Vk::Device> device, VkImage image, VkFormat format) : m_device(device)
{
    VkImageViewCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    createInfo.image = image;
    createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
    createInfo.format = format;
    createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
    createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
    createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
    createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
    createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    createInfo.subresourceRange.baseMipLevel = 0;
    createInfo.subresourceRange.levelCount = 1;
    createInfo.subresourceRange.baseArrayLayer = 0;
    createInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;

    if (vkCreateImageView(device->inner(), &createInfo, nullptr, &m_imageView) != VK_SUCCESS)
    {
        crash("Failed to create an image view!");
    }
}

Vk::ImageView::ImageView(
    std::shared_ptr<Vk::Device> device,
    std::shared_ptr<Vk::Image> image,
    VkImageViewType type,
    VkImageAspectFlags aspectFlags
) :
    m_device(device),
    m_image(image)
{
    VkImageViewCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    createInfo.image = image->inner();
    createInfo.viewType = type;
    createInfo.format = image->getFormat();
    createInfo.subresourceRange.aspectMask = aspectFlags;
    createInfo.subresourceRange.baseMipLevel = 0;
    createInfo.subresourceRange.levelCount = 1;
    createInfo.subresourceRange.baseArrayLayer = 0;
    createInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;

    if (vkCreateImageView(device->inner(), &createInfo, nullptr, &m_imageView) != VK_SUCCESS)
    {
        crash("Failed to create an image view!");
    }
}

Vk::ImageView::~ImageView()
{
    vkDestroyImageView(m_device->inner(), m_imageView, nullptr);
}

VkImageView Vk::ImageView::inner()
{
    return m_imageView;
}