//
// Asura_Chunk_ResourceFile_PS3_Shaders.h
//
// Created by DMR - 15 Aug 2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//

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

#include "Core/Asura.h"

#include "ChunkSystem/Asura_Chunk_ResourceFile_PS3_Shaders.h"

// Asura Platform-independent
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Core/Asura_Material_System.h"
#include "SpecialFX/Asura_PS3_DecalSystem.h"
#include "ChunkSystem/Asura_Chunk_ResourceFile_PS3.h"
#include "Rendering/Shaders/Asura_PS3_GCM_Shader.h"
#include "Rendering/Asura_PS3_MaterialResponse_System.h"

#include "Rendering/ShadersDefinition/fp/Water_FP.h"
#include "Rendering/ShadersDefinition/FP/SFX_Skybox_FP.h"

/******************************************************************************/
/* Asura_Chunk_ResourceFile_PS3_Shaders Class Functions              */
/******************************************************************************/

void Asura_Chunk_ResourceFile_PS3_Shaders::Process( const char* szFilename, Asura_Chunk_Stream& xStream )
{
	if( Version != ASURA_PS3_SHADERS_CHUNK_VERSION )
	{
		Asura_Assertf( false, ("Invalid shaders chunk version (%d) encountered. Should be %d. You may need new code, or to re-export the level.", Version, ASURA_PS3_SHADERS_CHUNK_VERSION) );
		return;
	}
	LoadShaderTree( static_cast<Asura_Hash_ID> ( ASURA_SHADER_HASH_BOTANICALS ),		xStream, false );	//Botanicals
	LoadShaderTree( static_cast<Asura_Hash_ID> ( ASURA_SHADER_HASH_ENVIRONMENT ),		xStream, true  );	//Environment
	LoadShaderTree( static_cast<Asura_Hash_ID> ( ASURA_SHADER_HASH_OBJECTS ),			xStream, false );	//Objects
	LoadShaderTree( static_cast<Asura_Hash_ID> ( ASURA_SHADER_HASH_CHARACTER ),			xStream, false );	//SmoothSkin
	LoadOtherShaders( xStream );
}

void Asura_Chunk_ResourceFile_PS3_Shaders::LoadShaderTree( Asura_Hash_ID uTreeHash, Asura_Chunk_Stream& xStream, bool bCanHaveWaterStrip )
{
	int iNumberOfShaders;
	unsigned char xShaderTemp[ ASURA_PS3_SHADER_READBUFFER_SIZE ];

	xStream >> iNumberOfShaders;

	for( int i = 0; i < iNumberOfShaders; ++i )
	{
		u_int uShaderSize;

		xStream >> uShaderSize;
		if( ( uShaderSize > 0 ) && ( uShaderSize < sizeof( xShaderTemp ) ) )
		{
			Asura_Hash_ID uShaderHash;

			xStream >> uShaderHash;
			xStream.Read( uShaderSize, xShaderTemp );
			if( uShaderHash & ASURA_PS3_SHADER_WATER )
			{
				if( bCanHaveWaterStrip )
				{
					Asura_PS3_GCM_ShadersLibrary::AddFP( uTreeHash, uShaderHash, xShaderTemp, uShaderSize, new Asura_PS3_Water_Handles(),
 1, false );
				}
				else
				{
					Asura_Assert( false, "Shader has a wrong Water Flag ID" );
					Asura_PS3_GCM_ShadersLibrary::AddFP( uTreeHash, uShaderHash, xShaderTemp, uShaderSize, new Asura_PS3_MaterialResponse_Handles(), 2, false );
				}
			}
			else
			{
				Asura_PS3_GCM_ShadersLibrary::AddFP( uTreeHash, uShaderHash, xShaderTemp, uShaderSize, new Asura_PS3_MaterialResponse_Handles(), 2, false );
			}
		}
		else
		{
			Asura_Assert( false, "Wrong shader exported. Some strips will not be draw." );
			if( uShaderSize > 0 )
			{
				xStream.Skip( uShaderSize );
			}
		}
	}
}

void Asura_Chunk_ResourceFile_PS3_Shaders::LoadOtherShaders( Asura_Chunk_Stream& xStream )
{
	int iNumberOfShaders;
	unsigned char xShaderTemp[ ASURA_PS3_SHADER_READBUFFER_SIZE ];

	xStream >> iNumberOfShaders;

	for( int i = 0; i < iNumberOfShaders; ++i )
	{
		u_int uShaderSize;

		xStream >> uShaderSize;
		if( ( uShaderSize > 0 ) && ( uShaderSize < sizeof( xShaderTemp ) ) )
		{
			Asura_Hash_ID uShaderHash;

			xStream >> uShaderHash;
			xStream.Read( uShaderSize, xShaderTemp );
			switch( uShaderHash )
			{
			case ASURA_PS3_SHADER_TYPE_HASH_SKYBOX:
				{
					Asura_PS3_GCM_ShadersLibrary::AddFP( ASURA_SHADER_HASH_SKYBOX, uShaderHash, xShaderTemp, uShaderSize, new Asura_PS3_Skybox_Handles(), 1, false );
				}
				break;
			default:
				Asura_Assert( false, "Asura_Chunk_ResourceFile_PS3_Shaders::LoadOtherShaders() - > Unknown shader ID. Did you forgot to update this function?" );
				break;
			}
		}
		else
		{
			Asura_Assert( false, "Wrong shader exported. Some strips will not be draw." );
			if( uShaderSize > 0 )
			{
				xStream.Skip( uShaderSize );
			}
		}
	}
}
