#ifndef CG_SHADER_MANAGER_H
#define CG_SHADER_MANAGER_H

#include <string>
#include <vector>
#include <map>
#include <Cg/Cg.h>
#include <Cg/cgGL.h>
#include <cassert>
#include "./exception/Exception.h"

using namespace std;

class ShaderException : public BasicException
{
public:
	ShaderException( const string& fileName, string details ="no detail description" );
};

/// CG shader manager manages CG shaders.
/**
*	CG shader manager - it allows load, compile and store shader into database
*/
class ShaderManager
{
private:
	CGcontext   context;	/**<CG context*/
	CGprofile	fragmentProfile;	/**<selected CG fragment profile*/
	CGprofile	vertexProfile;		/**<selected CG vertex profile*/

	ShaderManager(const ShaderManager&);	/**<cannot be copied*/
	map<string, CGprogram>	shaders;	/**<shader database*/

public:
	ShaderManager(void);	/**< Have to be called after OpenGL initialization, NOT before!!! */
	ShaderManager(const CGprofile& vertexProfile, const CGprofile& fragmentProfile); /**< Have to be called after OpenGL initialization, NOT before!!! */

	bool insertVertexShaderDirect(const string& vertexShaderCode, const string& entry , const string &name);	/**< Compile and store given vertex shader into database */
	bool insertFragmentShaderDirect(const string& fragmentShaderCode, const string& entry , const string &name); /**< Compile and store given fragment shader into database */

	bool insertVertexShader(const string& path, const string& entry , const string &name);	/**<  Load, compile and store vertex shader into database */
	bool insertFragmentShader(const string& path,  const string& entry, const string &name);	/**<  Load, compile and store fragment shader into database */

	CGprofile getVertexProfile(void);	/**< Returns selected CG vertex profile */
	CGprofile getFragmentProfile(void);	/**< Returns selected CG fragment profile */
	CGprogram getShader(const string &name);	/**<  Return shader which was stored into database under given name. If name is not found in database then return NULL */

	void bind(void);		/**< Activate CG vertex & fragment profile */
	void unbind(void);		/**< Deactivate CG vertex & fragment profile */
};


#endif