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


#ifndef	__NSHADERINPUT__
#define	__NSHADERINPUT__


		#include "math/vector.h"
		#include "nstring/nstring.h"


namespace GS {
	namespace Core {

/// Shader input.
struct	ShaderInput
{
enum	Type
{
	None				=	0,

	Uniform,			///< User programmed shader variable.
	Attribute			///< User bound shader input stream.
};

enum	Semantic		// do not reorder!
{
	// Data attributes.
	Position			=	0,
	Normal,
	UV0,
	UV1,
	UV2,
	VertexColor,
	Tangent,
	Bitangent,
	BoneIndex,
	BoneWeight,

	// Data uniforms.
	Constant,

	Texture2D,
	Texture3D,
	TextureCube,

	Clock,
	TimeOfDay,			///< Environment time of day (eg. skybox)
	ViewVector,
	ViewPosition,
	Viewport,
	ZNear,
	ZFar,
	ZoomFactor,
	FxScale,
	InverseBufferSize,
	InverseViewportSize,
	DisplayBufferRatio,
	ViewportRatio,
	ViewDepthOffset,
	AmbientColor,
	FogColor,
	FogNear,
	FogFar,
	FogInverseRange,
	DepthBuffer,
	FrameBuffer,
	GBuffer0,
	GBuffer1,
	GBuffer2,
	GBuffer3,
	NoiseMap,

	NormalMatrix,
	NormalViewMatrix,
	ModelMatrix,
	ViewMatrix,
	ProjectionMatrix,
	ModelViewMatrix,
	ModelViewProjectionMatrix,
	InverseViewProjectionMatrix,
	InverseViewProjectionMatrixAtOrigin, // precision hack

	PreviousModelViewMatrix,
	PreviousModelViewProjectionMatrix,

	MaterialOpacity,

	MaterialDiffuse,
	MaterialSpecular,
	MaterialSelf,
	MaterialAmbient,
	MaterialGlossiness,
	MaterialReflection,
	MaterialAlphaThreshold,
	MaterialDepthBias,
	MaterialTexture0,
	MaterialTexture1,
	MaterialTexture2,
	MaterialTexture3,
	MaterialTexture4,
	MaterialTexture5,
	MaterialTexture6,
	MaterialTexture7,

	LightRange,
	LightSpotEdge,
	LightSpotCone,
	LightShadowBias,
	LightDiffuseColor,
	LightSpecularColor,
	LightShadowColor,
	LightViewPosition,
	LightViewDirection,
	LightShadowMatrix0,
	LightShadowMatrix1,
	LightShadowMatrix2,
	LightShadowMatrix3,
	LightShadowMatrix4,
	LightShadowMatrix5,
	InverseShadowMapSize,
	LightShadowMap0,
	LightShadowMap1,
	LightShadowMap2,
	LightShadowMap3,
	LightShadowMap4,
	LightShadowMap5,
	LightPSSMSliceDistance0,
	LightPSSMSliceDistance1,
	LightPSSMSliceDistance2,
	LightPSSMSliceDistance3,
	ViewToLightMatrix,
	LightProjectionMap,

	BoneMatrix,
	PreviousBoneMatrix,

	LastSemantic
};

enum	Category
{
	CategoryVertexStream			=	0,	// keep as category 0
	CategoryConstant,
	CategoryTexture,
	CategorySkin,
	CategoryRenderer,
	CategoryMaterialOpacity,
	CategoryMaterial,
	CategoryTransform,
	CategoryPreviousTransform,
	CategoryLight,

	CategoryLast
};

static	const char		*GetCategoryName(Category);

enum	Precision
{
	NoP					=	0,

	LowP,
	MediumP,
	HighP
};

enum	DataType		// do not reorder!
{
	NoData				=	(1 << 0),
	Int					=	(1 << 1),
	Float				=	(1 << 2),
	Vector2				=	(1 << 3),
	Vector3				=	(1 << 4),
	Vector4				=	(1 << 5),
	Matrix3				=	(1 << 6),
	Matrix4				=	(1 << 7),
	DataTexture2D		=	(1 << 8),
	DataTexture3D		=	(1 << 9),
	DataTextureCube		=	(1 << 10),
	DataTextureShadow	=	(1 << 11)
};

struct	SemanticDesc
{
	const char	*name;
	Category	category;
	DataType	data_type;
	Precision	precision;
};

static	SemanticDesc	semantic_desc[LastSemantic + 1];

		bool			ConsumesTextureUnit() const;

enum	Scope
{
		Vertex			=	(1 << 0),
		Pixel			=	(1 << 1),
		Geometry		=	(1 << 2)
};

		String			name;

		int				scope;
		Type			type;
		Semantic		semantic;
		uint			array_size;

		String			parm_t;
		GS::Vector4		parm_v;		///< 16B vector

		ShaderInput::DataType data_type;

		ShaderInput();
};

	} //Core
} // GS


#endif	// __NSHADERINPUT__
