/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NRENDERERSHADER__
#define	__NRENDERERSHADER__


		#include "core/shader_input.h"
		#include "container/nlist.h"
		#include "memory/nshared_ptr.h"


namespace GS {
	namespace Core {

// Shader varying.
struct	ShaderVarying
{
		String			type, name;
};

/*!
	@short	Shader base class.
	@author Emmanuel Julien (ejulien@gsworks.fr)
*/
struct	Shader : public SharedObject
{
		String			name;

		String			vertex_decl, vertex,
						pixel_decl, pixel,
						geometry_decl, geometry;

		AutoList <ShaderInput *> input_list;
		AutoList <ShaderVarying *> varying_list;

		/// Clone this shader to a new object.
		bool			Clone(Shader &clone) const;

		/// Declare a varying.
		ShaderVarying	*DeclareVarying(const char *name, const char *type);
		/// Declare an input.
		ShaderInput		*DeclareInput(const char *name, ShaderInput::DataType data_type, ShaderInput::Semantic semantic, ShaderInput::Type parm_type, ShaderInput::Scope parm_scope, uint array_size = 1);

		/// Get a shader input from its semantic.
		ShaderInput		*GetInput(ShaderInput::Semantic semantic) const;

		/// Set a define.
		void			Define(const char *, ShaderInput::Scope define_scope);

		/// Declare inputs from a meta tag.
		void			ParseInputTag(NML::Tag *);
		/// Declare varyings from a meta tag.
		void			ParseVaryingTag(NML::Tag *);

		/// Add an ISL section to this shader.
		bool			AddISLSection(const char *uri);

		void			Clear();

/*!
	@name	Serialization.
	@{
*/
		bool			FromMetaTag(NML::Tag &);
		NML::Tag		*AsMetaTag() const;
/// @}

		Shader(const char *name = 0, const char *vertex = 0, const char *fragment = 0, const char *geometry = 0);
};

	} // Core
} // GS


#endif	// __NRENDERERSHADER__
