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


#ifndef	__TINYC_SHADER_TREE_COMPILER__
#define	__TINYC_SHADER_TREE_COMPILER__


		#include "core/shader_tree_compiler.h"


namespace GS {
	namespace Core {
		struct ResourceFactory;
		struct Material;

/*!
	@short	TinyC Shader tree compiler.
	@author	Scorpheus (Scorpheus@hotmail.com)
*/
class		TinyCShaderTreeCompiler : public ShaderTreeCompiler
{
	/*!
		@name	Specialized interface.
		@{
	*/
protected:

	virtual	CShaderBlock	*CompileConstantShaderBlock(const ConstantShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileColorShaderBlock(const ColorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileMaterialParamShaderBlock(const MaterialParamShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileMaterialTextureShaderBlock(const MaterialTextureShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileGeometryVertexShaderBlock(const GeometryVertexShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileGeometryUVShaderBlock(const GeometryUVShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileGeometryNormalShaderBlock(const GeometryNormalShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileGeometrySkinningShaderBlock(const GeometrySkinningShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileGeometryVertexColorShaderBlock(const GeometryVertexColorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileGeometryTangentFrameShaderBlock(const GeometryTangentFrameShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileRenderBufferShaderBlock(const RenderBufferShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileTextureShaderBlock(const TextureShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileTextureSamplerShaderBlock(const TextureSamplerShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileMixShaderBlock(const MixOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileAddShaderBlock(const AddOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileSubShaderBlock(const SubOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileMulShaderBlock(const MulOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileDivShaderBlock(const DivOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileDotShaderBlock(const DotOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileCrossShaderBlock(const CrossOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileClampShaderBlock(const ClampShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileNormalizeBlock(const NormalizeOperatorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileSwizzleShaderBlock(const SwizzleShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileBuildShaderBlock(const BuildShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileCosinusShaderBlock(const CosinusShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileSinusShaderBlock(const SinusShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompilePowShaderBlock(const PowShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileAbsShaderBlock(const AbsShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileUnpackColorToVector(const UnpackColorToVectorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompilePackVectorToColor(const PackVectorToColorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileClockShaderBlock(const ClockShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileScreenUVShaderBlock(const ScreenUVShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileViewVectorShaderBlock(const ViewVectorShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileViewportShaderBlock(const ViewportShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	virtual	CShaderBlock	*CompileNormalViewMatrixShaderBlock(const NormalViewMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileNormalMatrixShaderBlock(const NormalMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileModelViewMatrixShaderBlock(const ModelViewMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);
	virtual	CShaderBlock	*CompileModelMatrixShaderBlock(const ModelMatrixShaderBlock *, ShaderInput::Scope = ShaderInput::Pixel);

	/// @}
	

public:

	ResourceFactory	&graphic_factory;

	/// Get code to the fragment shader declaration.
	String			GetFragmentDeclaration()	{	return pixel_declaration;	}
	/// Get code to the fragment shader.
	String			GetFragmentShader()			{	return pixel_source;	}

	/// Declare a varying.
	virtual	bool	DeclareVarying(const char *name, ShaderInput::DataType data_type) {return true;};

	/// Helper.
	bool			GetTypeDeclaration(ShaderInput::DataType, String &declaration);

	void			SetShaderInputs( const Material &m);

	/// Complete a compilation, retrieve the shader.
	virtual	Shader		*Finish();

	TinyCShaderTreeCompiler(ResourceFactory &gf) : graphic_factory(gf) {}
};

	} // Core
} // GS


#endif	// __TINYC_SHADER_TREE_COMPILER__
