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

#ifndef DSE_GS_EFFECT_EFFECT_HPP
#define DSE_GS_EFFECT_EFFECT_HPP

#include <Darkstar/common.hpp>

#include <Darkstar/Graphic System/Effect/constant_table.hpp>
#include <Darkstar/Graphic System/Effect/pixel_shader.hpp>
#include <Darkstar/Graphic System/Effect/vertex_shader.hpp>
#include <Darkstar/Graphic System/Render State/common_render_state.hpp>
#include <Darkstar/Resource System/Textures/baseTexture.hpp>
#include <Darkstar/Graphic System/Render State/sampler_render_state.hpp>
#include <Darkstar/math.hpp>

namespace gs
{
	struct ConcreteEffect
	{
		shared_ptr<gs::VertexShader> vs;
		shared_ptr<gs::PixelShader> ps;
	};

	enum MACROTYPE
	{
		MT_VERTEX = 0,
		MT_PIXEL = 1,
		MT_SHARED = 2
	};

	struct Macro
	{
		short min_value;
		short max_value;
		short cur_value;
		MACROTYPE type;

		unsigned int contribution;
		std::string name;
	};

	struct ShaderMacro
	{
		LPCSTR name;
		LPCSTR definition;
	};

	struct Technique
	{
		typedef std::vector<ConcreteEffect> storage;
		storage ce;
		shared_ptr<gs::ConstantTable> const_table;
		std::vector<Macro> macros;
		stdext::hash_map<std::string, unsigned int> macros_num_map;
		stdext::hash_map<std::string, shared_ptr<SamplerRenderState> > samplers;

		Technique();
	};

	struct InputSignature
	{
		shared_array<char> code;
		unsigned int size;
	};

	class Effect
	{
	private:
		stdext::hash_map<std::string, shared_ptr<Technique> > techniques;

		shared_ptr<Technique> cur_technique;	
		unsigned int cur_ce_index;

		bool need_to_get_ce_index;

		void _getCurCeIndex();

		InputSignature input_signature;

		typedef stdext::hash_map<std::string, shared_ptr<Technique> >::iterator hmt_it;
		typedef stdext::hash_map<std::string, shared_ptr<Technique> >::const_iterator const_hmt_it;
	public:
		Effect();
		~Effect();

		void addNewTechnique(const std::string& name, const shared_ptr<Technique>& technique);

		void setMacro(const std::string& name, short new_value);
		bool getIsMacroExist(const std::string& name) const;
		short getMacroMaxValue(const std::string& name) const;
		short getMacroMinValue(const std::string& name) const;
		short getMacroCurValue(const std::string& name) const;
		bool setCurTechnique(const std::string& tname);
		bool getIsTechniqueExist(const std::string& tname) const;

		bool setBool(const std::string& name, const bool* value);
		bool setBoolArray(const std::string& name, const bool* values, const unsigned int count);
		bool setFloat(const std::string& name, const float* value);
		bool setFloatArray(const std::string& name, const float* values, const unsigned int count);
		bool setInt(const std::string& name, const int* value);
		bool setIntArray(const std::string& name, const int* values, const unsigned int count);
		bool setVect2(const std::string& name, const math::Vect2* value);
		bool setVect3(const std::string& name, const math::Vect3* value);
		bool setVect3Array(const std::string& name, const math::Vect3* values, const unsigned int count);
		bool setVect4(const std::string& name, const math::Vect4* value);
		bool setVect4Array(const std::string& name, const math::Vect4* values, const unsigned int count);
		bool setMatrix4x4(const std::string& name, const math::Matr4* value);
		bool setMatrix4x4Array(const std::string& name, const math::Matr4* values, const unsigned int count);
		bool setTexture(const std::string& name, const shared_ptr<rs::BaseTexture>& texture);
		bool setSamplers();

		bool getIsConstantExist(const std::string& name) const;
		short getConstantIndex(const std::string& name) const;

		const InputSignature& getEffectInputSignature() const;
		void setEffectInputSignature(const InputSignature& input_signature);

		void set();
	};
};

#endif




