//
// Asura_PS3_GCM_ShadersLibrary.h
//
// Created by Catalin Arsenescu - 29 March 2007
//
// Copyright (C) 2005 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif

#ifndef __ASURA_PS3_GCM_SHADERS_LIBRARY_H__
#define __ASURA_PS3_GCM_SHADERS_LIBRARY_H__

// I N C L U D E S ///////////////////////////////////////////////////////////

// Engine platform-specific.
#include "Rendering/Shaders/Asura_PS3_GCM_Shader.h"

// C L A S S /////////////////////////////////////////////////////////////

enum
{
	ASURA_SHADER_HASH_ENVIRONMENT	= 0x3CEE8FB8, //Hash for "EnvironmentShader"
	ASURA_SHADER_HASH_CHARACTER		= 0xB547704E, //Hash for "CharacterShader"
	ASURA_SHADER_HASH_OBJECTS		= 0x5A8D1DF9, //Hash for "ObjectsShader"
	ASURA_SHADER_HASH_DEFERRED		= 0x626EDC84, //Hash for "DeferredShader"
	ASURA_SHADER_HASH_PROJECTOR		= 0x481171A1, //Hash for "ProjectorShader"
	ASURA_SHADER_HASH_SHADOW		= 0x3D4818F8, //Hash for "ShadowsShader"
	ASURA_SHADER_HASH_BOTANICALS	= 0x6F2606FF, //Hash for "BotanicalsShader"
	ASURA_SHADER_HASH_FOG			= 0x30ACFE23, //Hash for "FogShader"
	ASURA_SHADER_HASH_SKYBOX		= 0x89FFA96F, //Hash for "SkyboxShader"
	ASURA_SHADER_HASH_FSFX			= 0xE9C90F04, //Hash for "FSFXShader"
	ASURA_SHADER_HASH_HDR			= 0x286D7A5B, //Hash for "HDRShader"
	ASURA_SHADER_HASH_SPECIALFX		= 0x6A4596F0, //Hash for "SpecialFXShader"
	ASURA_SHADER_HASH_DECALS		= 0xC683F1CB, //Hash for "DecalsShader"
	ASURA_SHADER_HASH_PFX			= 0x7842D288, //Hash for "SFX_PFX"
	ASURA_SHADER_HASH_PROJECT		= 0x8D869EF0, //Hash for "ProjectSpecificShader"
	ASURA_SHADER_HASH_GLOBAL		= 0xC447B42B, //Hash for "GlobalShaders"
	ASURA_SHADER_HASH_SSAO			= 0x0036028E, //Hash for "SSAO"
};

enum
{
	ASURA_SPECIALFX_CORONA_HASH		= 0x4F629627, //Hash for "SpecialFXCorona"
	ASURA_SPECIALFX_LINES_HASH		= 0x872CA294, //Hash for "SpecialFXLines"
};

// global shaders, may be used by any system
enum
{
	ASURA_GLOBAL_SHADER_BLANK,		// opaque white
	ASURA_GLOBAL_SHADER_BLANK_MRT,  // opaque white to 4 render targets
	ASURA_GLOBAL_SHADER_ALPHA_TEST,	// opaque white with alpha test
};

class Asura_MemAllocator;
class Asura_PS3_FP_Handles;
class Asura_PS3_FP_List_Tree;
class Asura_PS3_FragmentShaderCopy;

template< typename T >
class Asura_TemplateHashTree;

typedef Asura_TemplateHashTree<Asura_PS3_FP_List_Tree*> FPListTree;

class Asura_PS3_GCM_ShadersLibrary
{
public:

	static void Initialise( void );
	static void Reset( void );
	static void Shutdown( void );
	static void EndFrame( void );

	static void AddFP( Asura_Hash_ID uHashTree, Asura_Hash_ID uHashFP, void* uStartProgram, u_int uProgramSize, Asura_PS3_FP_Handles* pxHandles, u_int uiNumberOfElements, bool bPermanent );
// 	static void AddFP( Asura_Hash_ID uHashTree, Asura_Hash_ID uHashFP, Asura_PS3_FragmentShader* pxFP, bool bPermanent );
	static Asura_PS3_FP_List_Tree*			GetPermanentFPTree( Asura_Hash_ID uHash );
	static Asura_PS3_FP_List_Tree*			GetResettableFPTree( Asura_Hash_ID uHash );
	static Asura_PS3_FragmentShaderCopy*	GetPermanentFP( Asura_Hash_ID uHashTree, Asura_Hash_ID uHashFP );
	static Asura_PS3_FragmentShaderCopy*	GetResettableFP( Asura_Hash_ID uHashTree, Asura_Hash_ID uHashFP );

#if defined(ASURA_PS3_ALLOW_SHADER_RELOAD)
	static void* LoadAndCompileShader( char *szFilename, Asura_Hash_ID uHashTree, Asura_Hash_ID uHashFP, const char ** aszArgs, const char ** aszAdditionalIncludePaths, Asura_PS3_FP_Handles *pHandles );
#endif

protected:

	static FPListTree			m_xFPTreesPermanent;
	static FPListTree			m_xFPTreesResettableOriginal;
	static FPListTree*			m_pxFPTreesResettable;
	
private:
	static void DestroyDevShaders( void );
#if defined(ASURA_PS3_ALLOW_SHADER_RELOAD)
	static char* LoadSourceCode( const char* szFilename, char* pSourceBuffer, size_t uSourceBufferSize, const char ** aszAdditionalIncludePaths );
	static bool LoadDevShaders( u_int uHashType, u_int uAdditionalHash );
	static bool ToggleDevShaders( bool bHelp );
	static bool TestShaderLoad( bool bHelp );
	static bool LoadAllShaders( bool bHelp );
	static bool LoadWaterShaders( bool bHelp );
	static bool LoadEnvShaders( bool bHelp );
#endif
}; //class Asura_PS3_GCM_ShadersLibrary

#endif //#ifndef __ASURA_PS3_GCM_SHADERS_LIBRARY_H__
