#pragma once

#include "Logger.h"
#include "VulkanContext.hpp"

#include <vector>

#include <vulkan/vulkan_core.h>

struct FDepthConfig
{
	VkPhysicalDevice PhysicalDevice;
};

class VulkanDepthPass
{
public:
	void Initialize(FDepthConfig& InConfig) { Config = InConfig; }

	void CreateDepthResources() { VkFormat DepthFormat = FindDepthFormat(); }

	VkFormat FindSupportedFormat(
		const std::vector<VkFormat>& Candidates,
		VkImageTiling				 Tiling,
		VkFormatFeatureFlags		 Features
	)
	{
		for (VkFormat Format : Candidates)
		{
			VkFormatProperties Properties;
			vkGetPhysicalDeviceFormatProperties(Config.PhysicalDevice, Format, &Properties);

			if (Tiling == VK_IMAGE_TILING_LINEAR
				&& (Properties.linearTilingFeatures & Features) == Features)
			{
				return Format;
			}
			else if (Tiling == VK_IMAGE_TILING_OPTIMAL
					 && (Properties.optimalTilingFeatures & Features) == Features)
			{
				return Format;
			}
		}

		Log::Error("Failed to find supported format!");
	}

	VkFormat FindDepthFormat()
	{
		return FindSupportedFormat(
			{ VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },
			VK_IMAGE_TILING_OPTIMAL,
			VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
		);
	}

	bool HasStencilComponent(VkFormat Format)
	{
		return Format == VK_FORMAT_D32_SFLOAT_S8_UINT || Format == VK_FORMAT_D24_UNORM_S8_UINT;
	}

	VkImage&		GetDepthImage() { return DepthImage; }
	VkDeviceMemory& GetDepthImageMemory() { return DepthImageMemory; }
	VkImageView&	GetDepthImageView() { return DepthImageView; }
	void			SetDepthImageView(VkImageView ImageView) { DepthImageView = ImageView; }

private:
	FDepthConfig Config;

	VkImage		   DepthImage;
	VkDeviceMemory DepthImageMemory;
	VkImageView	   DepthImageView;
};
