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

#ifdef GD_D3D9

#include <Darkstar/Graphic System/Effect/shader_reflection.hpp>
#include <Darkstar/Kernel/logh.hpp>

using namespace gs;
using ker::Log;

ShaderReflection::ShaderReflection(void* code, const unsigned int code_size)
{
	ID3DXConstantTable* reflector;
	if(FAILED(D3DXGetShaderConstantTable((DWORD*)code, &reflector)))
	{
		lwar << "Cannot get shader constant table";
		return;
	};

	D3DXCONSTANTTABLE_DESC shader_desc;
	if(FAILED(reflector->GetDesc(&shader_desc)))
	{
		lwar << "Cannot get description of shader";
		return;
	};
	ShaderConstantBuffer constant_buffer;
	constant_buffer.buffer_type = DESCBT_CBUFFER;
	constant_buffer.name = "default";
	for(unsigned int i = 0; i < shader_desc.Constants; ++i)
	{
		D3DXCONSTANT_DESC constant_desc;
		D3DXHANDLE constant_handle = reflector->GetConstant(NULL, i);
		shared_array<UINT> count(new UINT[8]);
		if(FAILED(reflector->GetConstantDesc(constant_handle, &constant_desc, count.get())))
		{
			lwar << "Cannot get description of constant";
			return;
		};
		switch(constant_desc.Type)
		{
		case D3DXPT_TEXTURE:
		case D3DXPT_TEXTURE1D:
		case D3DXPT_TEXTURE2D:
		case D3DXPT_TEXTURE3D:
		case D3DXPT_TEXTURECUBE:
			{
				ShaderBoundResource new_bound_resource_texture;
				ShaderBoundResource new_bound_resource_sampler;

				std::string constant_desc_name = std::string(constant_desc.Name);
				std::string sampler_name = constant_desc_name.substr(0, constant_desc_name.find_first_of('+'));
				std::string texture_name = constant_desc_name.substr(constant_desc_name.find_first_of('+')+1);

				new_bound_resource_texture.name = texture_name;
				new_bound_resource_texture.register_index = constant_desc.RegisterIndex;
				new_bound_resource_texture.type = DESBRT_TEXTURE;

				new_bound_resource_sampler.name = sampler_name;
				new_bound_resource_sampler.register_index = constant_desc.RegisterIndex;
				new_bound_resource_sampler.type = DESBRT_SAMPLER;
				bound_resources.push_back(new_bound_resource_texture);
				bound_resources.push_back(new_bound_resource_sampler);
			};break;
		case D3DXPT_SAMPLER:
		case D3DXPT_SAMPLER1D:
		case D3DXPT_SAMPLER2D:
		case D3DXPT_SAMPLER3D:
		case D3DXPT_SAMPLERCUBE:
			{
				ShaderBoundResource new_bound_resource;
				new_bound_resource.name = constant_desc.Name;
				new_bound_resource.register_index = constant_desc.RegisterIndex;
				new_bound_resource.type = DESBRT_SAMPLER;
				bound_resources.push_back(new_bound_resource);
			};break;
		case D3DXPT_BOOL:
		case D3DXPT_INT:
		case D3DXPT_FLOAT:
			{
				ShaderVariable new_variable;
				new_variable.name = constant_desc.Name;
				new_variable.register_index = constant_desc.RegisterIndex;
				constant_buffer.variables.push_back(new_variable);
			};break;
		};
	};
	constant_buffers.push_back(constant_buffer);

	input_signature_data = NULL;
	input_signature_size = 0;
};

ShaderReflection::~ShaderReflection()
{

};

#endif


