/*
 * 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 "ShaderProgramType.hpp"
#include <tuple>

namespace OpenVulkano
{
	struct DescriptorSetLayoutBinding
	{
		enum Type : uint32_t {
			TYPE_SAMPLER = 0,
			TYPE_COMBINED_IMAGE_SAMPLER = 1,
			TYPE_SAMPLED_IMAGE = 2,
			TYPE_STORAGE_IMAGE = 3,
			TYPE_UNIFORM_TEXEL_BUFFER = 4,
			TYPE_STORAGE_TEXEL_BUFFER = 5,
			TYPE_UNIFORM_BUFFER = 6,
			TYPE_STORAGE_BUFFER = 7,
			TYPE_UNIFORM_BUFFER_DYNAMIC = 8,
			TYPE_STORAGE_BUFFER_DYNAMIC = 9,
			TYPE_INPUT_ATTACHMENT = 10,
			TYPE_INLINE_UNIFORM_BLOCK = 1000138000,
			TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000,
			TYPE_ACCELERATION_STRUCTURE_NV = 1000165000,
			TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000,
			TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001,
			TYPE_MUTABLE_VALVE = 1000351000
		};

		uint32_t bindingId;
		Type descriptorType;
		uint32_t descriptorCount;
		ShaderProgramType::Type stageFlags;
		void* immutableSamplers;

		constexpr DescriptorSetLayoutBinding()
				: DescriptorSetLayoutBinding(0, Type::TYPE_UNIFORM_BUFFER_DYNAMIC, 1, ShaderProgramType::Type::VERTEX)
		{}

		constexpr DescriptorSetLayoutBinding(uint32_t bindingId, Type descriptorType, uint32_t descriptorCount,
								   ShaderProgramType::Type stageFlags, void* immutableSamplers = nullptr)
								   : bindingId(bindingId), descriptorType(descriptorType)
								   , descriptorCount(descriptorCount), stageFlags(stageFlags)
								   , immutableSamplers(immutableSamplers)
		{}

		constexpr DescriptorSetLayoutBinding(uint32_t id, const DescriptorSetLayoutBinding& layout)
				: bindingId(id), descriptorType(layout.descriptorType), descriptorCount(layout.descriptorCount)
				, stageFlags(layout.stageFlags), immutableSamplers(layout.immutableSamplers)
		{}

		constexpr bool operator <(const DescriptorSetLayoutBinding& rhs) const
		{
			return std::tie(bindingId, descriptorType, descriptorCount, stageFlags, immutableSamplers) <
					std::tie(rhs.bindingId, rhs.descriptorType, rhs.descriptorCount, rhs.stageFlags, rhs.immutableSamplers);
		}
	};
}