/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "Buffer.hpp"
#include "Scene/DataFormat.hpp"
#include "VulkanUtils.hpp"
#include <vulkan/vulkan.hpp>

namespace OpenVulkano::Vulkan
{
	class IImage
	{
	public:
		virtual ~IImage() = default;

		virtual vk::Image GetImage() = 0;
		virtual vk::ImageView GetView() = 0;
	};

	struct Image : public Buffer, public IImage
	{
		vk::Image image;
		vk::Extent3D extent;
		vk::ImageView view;
		vk::Format format = vk::Format::eUndefined;

		/**
		 * \brief
		 * \param device
		 * \param imageCreateInfo
		 * \param imageViewCreateInfo The image will be set automatically after it's creation
		 * \param memoryPropertyFlags
		 */
		void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem = true, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);

		void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);

		void SetLayout(vk::CommandBuffer& cmdBuffer, const vk::ImageSubresourceRange& subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const;

		void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageAspectFlags aspectMask, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const
		{
			SetLayout(cmdBuffer, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1), newLayout, oldLayout);
		}

		void Close() override;

		operator bool() const { return image.operator bool(); }


		vk::Image GetImage() override { return image; }

		vk::ImageView GetView() override { return view; }

		~Image() override { Image::Close(); }
	};
}
