#ifndef __HlslShader__
#define __HlslShader__

#include "../Core/SceneGraph/Shader.h"
#include "DeviceResources.h"

class HlslShader : public Shader {
public:
    class ScalarVariable : public Shader::ScalarVariable {
        friend class HlslShader;
	public:
		void setValue(int value);
		void setValue(float value);
		void setValue(bool value);
		
		void setValue(int* value, size_t count);
		void setValue(float* value, size_t count);
		void setValue(bool* value, size_t count);

    protected:
        ScalarVariable(ID3D10EffectScalarVariable* variable);

        ID3D10EffectScalarVariable* _variable;
	};
	
	class VectorVariable : public Shader::VectorVariable  {
        friend class HlslShader;
	public:
		void setValue(int* value);
		void setValue(float* value);
		void setValue(bool* value);
		
		void setValue(int* value, size_t count);
		void setValue(float* value, size_t count);
		void setValue(bool* value, size_t count);

    protected:
        VectorVariable(ID3D10EffectVectorVariable* variable);

        ID3D10EffectVectorVariable* _variable;
	};
	
	class MatrixVariable : public Shader::MatrixVariable {
        friend class HlslShader;
	public:
		void setValue(float* value);
		void setValue(float* value, size_t count);

    protected:
        MatrixVariable(ID3D10EffectMatrixVariable* variable);

        ID3D10EffectMatrixVariable* _variable;
	};
	
	class ShaderResourceVariable : public Shader::ShaderResourceVariable {
        friend class HlslShader;
	public:
		void setValue(RenderTarget* renderTarget);
        void setValue(Texture* texture);
        void setValue(void* resourceHandle);

    protected:
        ShaderResourceVariable(ID3D10EffectShaderResourceVariable* variable);

        ID3D10EffectShaderResourceVariable* _variable;
	};

    HlslShader(ID3D10Effect* effect, ID3D10EffectTechnique* technique, ID3D10InputLayout* layout);

    ScalarVariable* createScalarVariable(const char* variableName);
    VectorVariable* createVectorVariable(const char* variableName);
    MatrixVariable* createMatrixVariable(const char* variableName);
    ShaderResourceVariable* createShaderResourceVariable(const char* variableName);

    ID3D10Effect* getEffect();
    ID3D10EffectTechnique* getTechnique();
    ID3D10InputLayout* getLayout();

protected:
    ID3D10Effect*           _effect;
    ID3D10EffectTechnique*  _technique;
    ID3D10InputLayout*      _layout;
};

#endif