#ifndef __Shader__
#define __Shader__

#ifndef CORE_DLL 
    #ifdef CORE_BUILD
	    #define CORE_DLL __declspec(dllexport)
    #else
	    #define CORE_DLL __declspec(dllimport)
        #pragma comment(lib, "Core.lib")
    #endif
#endif

#include "RenderTarget.h"
#include "Texture.h"
#include "../../Core/Observer.h"


class CORE_DLL Shader : public Observer {
public:
	class ScalarVariable {
	public:
		virtual void setValue(int value) = 0;
		virtual void setValue(float value) = 0;
		virtual void setValue(bool value) = 0;
		
		virtual void setValue(int* value, size_t count) = 0;
		virtual void setValue(float* value, size_t count) = 0;
		virtual void setValue(bool* value, size_t count) = 0;
	};
	
	class VectorVariable {
	public:
		virtual void setValue(int* value) = 0;
		virtual void setValue(float* value) = 0;
		virtual void setValue(bool* value) = 0;
		
		virtual void setValue(int* value, size_t count) = 0;
		virtual void setValue(float* value, size_t count) = 0;
		virtual void setValue(bool* value, size_t count) = 0;
	};
	
	class MatrixVariable {
	public:
		virtual void setValue(float* value) = 0;
		virtual void setValue(float* value, size_t count) = 0;
	};
	
	class ShaderResourceVariable {
	public:
        virtual void setValue(Texture* texture) = 0;
        virtual void setValue(RenderTarget* renderTarget) = 0;
        virtual void setValue(void* resourceHandle) = 0;
	};

    Shader();

    void notify(Observable* observable);

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

    MatrixVariable* g_WorldMatrix;
    MatrixVariable* g_ViewMatrix;
    MatrixVariable* g_ProjectionMatrix;
    MatrixVariable* g_NormalMatrix;

    MatrixVariable* g_WorldMatrixInverse;
    MatrixVariable* g_ViewMatrixInverse;
    MatrixVariable* g_ProjectionMatrixInverse;

    VectorVariable* g_Eye;
    VectorVariable* g_Center;
    VectorVariable* g_Up;

    VectorVariable* g_Viewport;

    ShaderResourceVariable* g_Texture;
    ShaderResourceVariable* g_NormalMap;

    ShaderResourceVariable* g_MRT[16];


    VectorVariable* g_DiffuseMaterial;
    VectorVariable* g_SpecularMaterial;
};

#endif