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

#include <Darkstar/Graphic System/Effect/constant_table.hpp>
#include <Darkstar/Graphic System/Direct3D/graphicDriver.hpp>
#include <Darkstar/Kernel/logh.hpp>

using gs::GraphicDriver;
using gs::Constant;
using gs::ConstantTable;
using gs::CONSTANT_TYPE;
using gs::PS_CONST;
using gs::VS_CONST;
using gs::ShaderReflection;
using gs::ShaderBoundResource;
using gs::ShaderVariable;
using ker::Log;

ConstantTable::ConstantTable()
{

};

ConstantTable::ConstantTable(const shared_ptr<ShaderReflection>& vs_refl, const shared_ptr<ShaderReflection>& ps_refl)
{
	std::vector<ShaderVariable> vs_variables = vs_refl->getAllVariables();
	std::vector<ShaderVariable> ps_variables = ps_refl->getAllVariables();
	std::vector<ShaderVariable>::iterator var_it;
	for(var_it = vs_variables.begin(); var_it != vs_variables.end(); ++var_it)
	{
		Constant new_constant;
		new_constant.type = VS_CONST;
		new_constant.register_index = var_it->register_index;
		constants.insert(std::pair<std::string, Constant>(var_it->name, new_constant));
	};
	for(var_it = ps_variables.begin(); var_it != ps_variables.end(); ++var_it)
	{
		Constant new_constant;
		new_constant.type = PS_CONST;
		new_constant.register_index = var_it->register_index;
		constants.insert(std::pair<std::string, Constant>(var_it->name, new_constant));
	};
	std::vector<ShaderBoundResource> vs_bound_res = vs_refl->getAllBoundResources();
	std::vector<ShaderBoundResource> ps_bound_res = ps_refl->getAllBoundResources();
	std::vector<ShaderBoundResource>::iterator br_it;
	for(br_it = vs_bound_res.begin(); br_it != vs_bound_res.end(); ++br_it)
	{
		Constant new_constant;
		new_constant.type = VS_CONST;
		new_constant.register_index = br_it->register_index;
		constants.insert(std::pair<std::string, Constant>(br_it->name, new_constant));
	};
	for(br_it = ps_bound_res.begin(); br_it != ps_bound_res.end(); ++br_it)
	{
		Constant new_constant;
		new_constant.type = PS_CONST;
		new_constant.register_index = br_it->register_index;
		constants.insert(std::pair<std::string, Constant>(br_it->name, new_constant));
	};
};

ConstantTable::~ConstantTable()
{
	constants.clear();
};

bool ConstantTable::getIsConstantExist(const std::string& name)
{
	return constants.find(name) != constants.end();
};

short ConstantTable::getConstantIndex(const std::string& name)
{
	storage::iterator it = constants.find(name);
	if(it == constants.end())
		return -1;
	return (unsigned short)it->second.register_index;
};

CONSTANT_TYPE ConstantTable::getConstantType(const std::string& name)
{
	storage::iterator it = constants.find(name);
	if(it == constants.end())
		return TYPE_UNKNOWN;
	return it->second.type;
};

const ConstantTable::storage& ConstantTable::getStorage() const
{
	return constants;
};

void ConstantTable::setNewStorage(const ConstantTable::storage& new_storage)
{
	constants = new_storage;
};