//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2007-2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: shader_reflection.hpp
//      Краткое описание: Сборщик информации о шейдере
//

#ifndef DSE_GS_EFFECT_SHADER_REFLECTION_HPP
#define DSE_GS_EFFECT_SHADER_REFLECTION_HPP

#include <Darkstar/common.hpp>
#include <Darkstar/Graphic System/Direct3D/direct3d_include.hpp>

namespace gs
{
	enum ShaderConstantBufferType
	{
		DESCBT_CBUFFER = 0,
		DESCBT_TBUFFER = 1,
	};

	enum ShaderBoundResourceType
	{
		DESBRT_TEXTURE = 2,
		DESBRT_SAMPLER = 3,
	};

	enum ShaderSystemValuesType
	{
		DESSVT_UNDEFINED = 0,
		DESSVT_POSITION = 1,
		DESSVT_CLIP_DISTANCE = 2,
		DESSVT_CULL_DISTANCE = 3,
		DESSVT_RENDER_TARGET_ARRAY_INDEX = 4,
		DESSVT_VIEWPORT_ARRAY_INDEX = 5,
		DESSVT_VERTEX_ID = 6,
		DESSVT_PRIMITIVE_ID = 7,
		DESSVT_INSTANCE_ID = 8,
		DESSVT_IS_FRONT_FACE = 9,
		DESSVT_SAMPLE_INDEX = 10,
		DESSVT_TARGET = 64,
		DESSVT_DEPTH = 65,
	};

	enum ShaderRegisterComponentType
	{
		DSRCT_COMPONENT_UNKNOWN = 0,
		DSRCT_COMPONENT_UINT32 = 1,
		DSRCT_COMPONENT_SINT32 = 2,
		DSRCT_COMPONENT_FLOAT32 = 3,
	};

	struct ShaderVariable
	{
		std::string name;
		unsigned int register_index;
	};

	struct ShaderBoundResource
	{
		std::string name;
		unsigned int register_index;
		ShaderBoundResourceType type;
	};

	struct ShaderConstantBuffer
	{
		std::string name;
		ShaderConstantBufferType buffer_type;
		std::vector<ShaderVariable> variables;

		bool operator ==(const ShaderConstantBuffer& cb) const;
		bool operator ==(const std::string& cb_name) const;
	};

	struct ShaderInputParameter
	{
		std::string name;
		unsigned int semantic_index;
		unsigned int register_index;
		ShaderSystemValuesType sv_type;
		ShaderRegisterComponentType rc_type;

		bool operator ==(const ShaderInputParameter& parameter) const;
	};

	class ShaderReflection
	{
	private:
		std::vector<ShaderConstantBuffer> constant_buffers;
		std::vector<ShaderBoundResource> bound_resources;
		std::vector<ShaderInputParameter> input_parameters;

		void* input_signature_data;
		unsigned int input_signature_size;
	public:
		ShaderReflection(void* code, const unsigned int code_size);
		~ShaderReflection();

		unsigned int getVariablesNum() const;
		unsigned int getBoundResourcesNum() const;
		unsigned int getInputParametersNum() const;
		unsigned int getConstantBuffersNum() const;

		std::vector<ShaderVariable> getAllVariables() const;
		const std::vector<ShaderConstantBuffer>& getAllConstantBuffers() const;
		const std::vector<ShaderBoundResource>& getAllBoundResources() const;
		const std::vector<ShaderInputParameter>& getAllInputParameters() const;

		const ShaderConstantBuffer& getConstantBufferByIndex(const unsigned int index) const;
		const ShaderConstantBuffer& getConstantBufferByName(const std::string& name) const;
		const ShaderBoundResource& getBoundResource(const unsigned int index) const;
		const ShaderInputParameter& getInputParameter(const unsigned int index) const;

		void* getInputSignatureData() const;
		const unsigned int getInputSignatureSize() const;
	};
};

#endif
