/*
 * 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 "Device.hpp"
#include <vulkan/vulkan.hpp>

namespace OpenVulkano::Vulkan
{
	class FrameBuffer;

	class RenderPass : public ICloseable
	{ //TODO allow to control the render rect size
	protected:
		vk::Device m_device;
		vk::RenderPassBeginInfo m_beginInfo;
		std::array<vk::ClearValue, 2> m_clearValues;
		FrameBuffer* m_frameBuffer = nullptr;
		bool m_useClearColor = false, m_useClearDepth = true;

	public:
		vk::RenderPass renderPass;

		RenderPass() = default;

		~RenderPass() override
		{
			if (m_frameBuffer) RenderPass::Close();
		}

		void Init(Device* device, FrameBuffer* frameBuffer, bool clearColor = false, bool clearDepth = false);

		void Close() override;

		void SetClearColor(vk::ClearColorValue clearColor = vk::ClearColorValue(std::array<float, 4>{ 0.39f, 0.58f, 0.93f, 1.0f }))
		{
			m_clearValues[0] = clearColor;
			if (!m_useClearColor) m_useClearColor = true;
		}

		void DisableClearColor()
		{
			if (m_useClearColor) m_useClearColor = false;
		}

		void SetClearDepth(vk::ClearDepthStencilValue clearDepth = vk::ClearDepthStencilValue(1, 0))
		{
			m_clearValues[1] = clearDepth;
			if (!m_useClearDepth) m_useClearDepth = true;
		}

		void DisableClearDepth()
		{
			if (m_useClearDepth) m_useClearDepth = false;
		}

		void Resize(vk::Extent3D size)
		{
			m_beginInfo.renderArea.extent.width = size.width;
			m_beginInfo.renderArea.extent.height = size.height;
		}

		virtual void Begin(vk::CommandBuffer& commandBuffer, bool primaryBuffer = false);

		virtual void End(vk::CommandBuffer& commandBuffer);

		[[nodiscard]] FrameBuffer* GetFrameBuffer() const { return m_frameBuffer; }

	protected:
		virtual void CreateRenderPass();

		void CreateRenderPass(const vk::RenderPassCreateInfo& renderPassCreateInfo);
	};
}