//////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_MaterialResponse_System.h
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

#if defined ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#if !defined __ASURA_PS3_MATERIALRESPONSE_SYSTEM_H__
#define __ASURA_PS3_MATERIALRESPONSE_SYSTEM_H__

/******************************************************************************/
/* Included Files                                                             */
/******************************************************************************/

// Asura
#include "Core/Asura_HashTree.h"

// Asura PS3
#include "Rendering/Asura_PS3_Graphics.h"
#include "Rendering/Asura_PS3_TextureManagement.h"

/******************************************************************************/
/* Constants                                                                  */
/******************************************************************************/

#define ASURA_PS3_MATERIALS_TEXTURE_WIDTH  (256)
#ifndef ASURA_PS3_MATERIALS_TEXTURE_HEIGHT
#define ASURA_PS3_MATERIALS_TEXTURE_HEIGHT (512)
#endif

#include "Rendering/Shaders/Asura_PS3_FP_Handles.h"

/******************************************************************************/
/* Classes                                                                    */
/******************************************************************************/

class Asura_Chunk_Stream;
class Asura_MaterialResponse;
class Asura_PS3_FragmentShaderBase;
class Asura_PS3_FragmentShaderCopy;
class Asura_TextureAnimationController;
class Asura_Animation;

////////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_MaterialResponse_Handles
//
// Class to store parameter handles for an fragment shader which uses the material
// response system
//
////////////////////////////////////////////////////////////////////////////////

enum UNIFORM_ELEMENTS_MATERIAL_RESPONSE_SYSTEM
{
	UE_MR_FogColour,
	UE_MR_FogProperties,

	UE_MR_RedSH,
	UE_MR_GreenSH,
	UE_MR_BlueSH,

	UE_MR_SHLightDirection,
	UE_MR_SHLightColour,
	UE_MR_SHLightBrightness,

	UE_MR_MaterialProperties,
	UE_MR_DetailMapParameters,
	UE_MR_DetailMapParameters2,

	UE_MR_SelfIlluminationParameters,
	UE_MR_AlbedoModifier,

	UE_MR_DepthAdjustment,

	UE_MR_UseAlbedo,
	UE_MR_UseNormalMap,
	UE_MR_UseSpecularMap,
	UE_MR_UseTransparencyMap,
	UE_MR_UseSelfIlluminationMap,
	UE_MR_UseParallaxMap,
	UE_MR_UseEnvironmentMap,
	UE_MR_UseReflectivityMask,
	UE_MR_UseAlbedoDetailMap,
	UE_MR_UseNormalDetailMap,


	UE_MR_ELEMENTS
};

enum TEXTURE_UNITS_MATERIAL_RESPONSE_SYSTEM
{
	TU_MR_Albedo,
	TU_MR_NormalMap,
	TU_MR_SpecularMap,
	TU_MR_TransparencyMap,
	TU_MR_SelfIlluminationMap,
	TU_MR_ParallaxMap,
	TU_MR_Albedo2,
	TU_MR_NormalMap2,
	TU_MR_SpecularMap2,
	TU_MR_TransparencyMap2,
	TU_MR_SelfIlluminationMap2,
	TU_MR_ParallaxMap2,
	TU_MR_EnvironmentMap,
	TU_MR_ReflectivityMask,
	TU_MR_MaterialsTexture,
	TU_MR_FogTexture,
	TU_MR_AlbedoDetailMap,
	TU_MR_AlbedoDetailMap2,
	TU_MR_NormalDetailMap,
	TU_MR_NormalDetailMap2,

	TU_MR_ELEMENTS
};

class Asura_PS3_MaterialResponse_Handles : public Asura_PS3_FP_Handles
{
public:

	Asura_PS3_MaterialResponse_Handles();
	~Asura_PS3_MaterialResponse_Handles();

	void InitialiseFromShader( Asura_PS3_FragmentShaderBase* pxShader );
};

enum ASURA_PS3_MATERIAL_TEXTURE_FORMAT
{
	ASURA_PS3_MATERIAL_A16B16G16R16F,
	ASURA_PS3_MATERIAL_A16B16G16R16,
	ASURA_PS3_MATERIAL_A8R8G8B8,
};


////////////////////////////////////////////////////////////////////////////////
//
// Asura_PS3_MaterialResponse_System
//
// System to manage material response on PS3
//
////////////////////////////////////////////////////////////////////////////////

class Asura_PS3_MaterialResponse_System
{
public:

	static void Initialise();
	static void Reset( const bool bFullReset );
	static void Shutdown();

	static Asura_PS3_Texture* GetDataTexture()	{ return &s_xMaterialsTexture; }
	static void UpdateDataTexture( Asura_Chunk_Stream& xStream, const int iVersion, u_int uNumberOfMaterials );

	static void SetBlendStates( const Asura_MaterialResponse* const pxMaterial );

	static void SetEffectParameters( const Asura_MaterialResponse* const			pxMaterial1,
									 const Asura_MaterialResponse* const			pxMaterial2,
									 const Asura_Animation* const					pxAnim,
									 Asura_PS3_FragmentShaderCopy*					pxShader );

	static void SetSHParameters(	const Asura_MaterialResponse* const				pxMaterial1,
									Asura_PS3_FragmentShaderCopy*					pxShader );
	static void SetProjectContext( const Asura_MaterialResponse* const pxMaterial1, const Asura_MaterialResponse* const pxMaterial2 );

	static Asura_Hash_ID CreateShaderHashID( Asura_Hash_ID uMaterialHash1, Asura_Hash_ID uMaterialHash2 );
	
	static void SetDepthParameters(	Asura_PS3_FragmentShaderCopy* pxShader, u_int uParameter );

	static void ReadPS3Material( Asura_Chunk_Stream& xStream, u_int uNumberOfMaterials );
	
protected:

	static Asura_PS3_Texture					s_xMaterialsTexture;
	static float								s_fMaterialsTextureScale;
	static int									s_iLastMaterial;

};

#endif // !defined __ASURA_XBOX360_MATERIALRESPONSE_SYSTEM_H__
