#ifndef SHADERCOMPOSER_H
#define SHADERCOMPOSER_H

#include <map>
#include <string>
#include <Cg/Cg.h>
#include <Cg/cgGL.h>
#include <cassert>

using namespace std;


enum paramType
{
	FLOAT1,
	FLOAT2,
	FLOAT3,
	FLOAT4,
	FLOAT4x4,

	ARRAY_FLOAT1,
	ARRAY_FLOAT2,
	ARRAY_FLOAT3,
	ARRAY_FLOAT4,

	MATRIX4X4_FLOAT
};

struct ParamInfo
{
	const float* value;
	paramType type;

	ParamInfo(paramType type);
};

/**
*	Pomocna trida pro praci s shaderama - umoznuje snadnejsi predavani parametru shaderu programum
*/
class ShaderComposer
{
private:
	map<string, ParamInfo> params;
	CGprogram shader;

public:
	CGprogram getShader(void);

	explicit ShaderComposer(CGprogram shader); 
	/*
	aby pri prikazech typu 
	
	CGprogramp p1;
	ShaderComposer s1 = p1

	se omylem nezkopirovalo (je treba zavolat metodu setShader(p1) !!!!
	*/


	ShaderComposer(void);

	void setShader(CGprogram shader);

	~ShaderComposer(void);

	void bindShader(void);	//TODO dopsat
	void unBindShader(void);	//TODO dopsat

	void insertParam(const string& name, paramType type);	/**<  vlozi do databaze informaci o shader parametru ( nazev parametru a typ parametru ) */

	bool setMatrixParam(const string& name, const float* values);	/**<   nastavi shader parametr s danym jmenem na danou hodnotu. POZOR parametr musi byt nejdrive pridan do databaze metodou insertParam !!! */
	bool setMatrixParamColumn(const string& name, const float* values); /**< values points at column dominant matrix */

	bool setArrayParam(const string& name, const float* values);	/**<   nastavi shader parametr s danym jmenem na danou hodnotu. POZOR parametr musi byt nejdrive pridan do databaze metodou insertParam !!! */
	bool setArrayParamOnIndex(const string& name, unsigned int idx, const float* values);	/**<   nastavi shader parametr s danym jmenem na danou hodnotu. POZOR parametr musi byt nejdrive pridan do databaze metodou insertParam !!! */

	bool setParamSmart( const string& name, const float* values);	/**< Set parameter - search type of the given param name and according the type call setArrayParam, setMatrixParam or setParam */

	bool setParam(const string& name, const float* value);	/**<  nastavi shader parametr s danym jmenem na danou hodnotu. POZOR parametr musi byt nejdrive pridan do databaze metodou insertParam !!! */
	bool setParamPtr(const string& name, const float* value);	/**<  TODO zrusit  nastavi shader parametr s danym jmenem na danou hodnotu. POZOR parametr musi byt nejdrive pridan do databaze metodou insertParam !!! */
	void loadParamFromPtr(void);				/**<  TODO zrusit nastavi shader parametr s danym jmenem na danou hodnotu. POZOR parametr musi byt nejdrive pridan do databaze metodou insertParam !!! */
};

#endif