//	Darkstar Engine  (c) UnderWorld Interactive Studio (all coding by Svarog    2007-2008)
//
//      Данный файл является частью Darkstar Engine. Любое использование кода файла
//      без согласия компании, является нарушением закона об авторском праве (в слу-
//      чае если не оговорено обратное).
//
//      Имя файла: shader_reflection_common.cpp
//      Краткое описание: cross platform data for shader reflection
//

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

using namespace gs;
using ker::Log;

bool ShaderInputParameter::operator ==(const ShaderInputParameter& parameter) const
{
	if(parameter.name == name && parameter.rc_type == rc_type && parameter.register_index == register_index &&
		parameter.semantic_index == semantic_index && parameter.sv_type == sv_type)
		return true;
	return false;
};

bool ShaderConstantBuffer::operator ==(const ShaderConstantBuffer& cb) const
{
	return cb.name == name;
};

bool ShaderConstantBuffer::operator ==(const std::string& cb_name) const
{
	return cb_name == name;
};

// common functins to shader reflection class

unsigned int ShaderReflection::getConstantBuffersNum() const
{
	return static_cast<unsigned int>(constant_buffers.size());
};

unsigned int ShaderReflection::getVariablesNum() const
{
	unsigned int var_num = 0;
	for(unsigned int i = 0; i < getConstantBuffersNum(); ++i)
		var_num += static_cast<unsigned int>(constant_buffers[i].variables.size());
	return var_num;
};

unsigned int ShaderReflection::getBoundResourcesNum() const
{
	return static_cast<unsigned int>(bound_resources.size());
};

unsigned int ShaderReflection::getInputParametersNum() const
{
	return static_cast<unsigned int>(input_parameters.size());
};

std::vector<ShaderVariable> ShaderReflection::getAllVariables() const
{
	std::vector<ShaderVariable> variables(getVariablesNum());
	std::vector<ShaderVariable>::iterator var_iter = variables.begin();
	for(unsigned int i = 0; i < getConstantBuffersNum(); ++i)
	{
		std::copy(constant_buffers[i].variables.begin(), constant_buffers[i].variables.end(), var_iter);
		var_iter += static_cast<unsigned int>(constant_buffers[i].variables.size());
	};
	return variables;
};

const std::vector<ShaderConstantBuffer>& ShaderReflection::getAllConstantBuffers() const
{
	return constant_buffers;
};

const std::vector<ShaderBoundResource>& ShaderReflection::getAllBoundResources() const
{
	return bound_resources;
};

const std::vector<ShaderInputParameter>& ShaderReflection::getAllInputParameters() const
{
	return input_parameters;
};

const ShaderConstantBuffer& ShaderReflection::getConstantBufferByIndex(const unsigned int index) const
{
	if(index >= constant_buffers.size())
	{
		lwar << "Try to get constant buffer with non correct index";
		return constant_buffers[constant_buffers.size()-1];
	};
	return constant_buffers[index];
};

const ShaderConstantBuffer& ShaderReflection::getConstantBufferByName(const std::string& name) const
{
	std::vector<ShaderConstantBuffer>::const_iterator it = std::find(constant_buffers.begin(), constant_buffers.end(), name);
	if(it == constant_buffers.end())
	{
		lwar << "Try to get constant buffer with non correct name: " << name;
		// return default buffer
		return constant_buffers[0];
	};
	return *it;
};

const ShaderBoundResource& ShaderReflection::getBoundResource(const unsigned int index) const
{
	if(index >= bound_resources.size())
	{
		lwar << "Try to get bound resource with non correct index: " << index;
		return bound_resources[bound_resources.size()-1];
	};
	return bound_resources[index];
};

const ShaderInputParameter& ShaderReflection::getInputParameter(const unsigned index) const
{
	if(index >= input_parameters.size())
	{
		lwar << "Try to get input parameter with non correct index: " << index;
		return input_parameters[input_parameters.size()-1];
	};
	return input_parameters[index];
};

void* ShaderReflection::getInputSignatureData() const
{
	return input_signature_data;
};

const unsigned int ShaderReflection::getInputSignatureSize() const
{
	return input_signature_size;
};