//////////////////////////////////////////////////////////////////////////////
//
// Asura_Chunk_ResourceFile_PS3_Character.cpp
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

// This file's header.
#include "ChunkSystem/Asura_Chunk_ResourceFile_PS3_Character.h"

// Engine independent.
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Core/Asura_Material_System.h"
#include "Core/Asura_MaterialResponse_System.h"
#include "Debugging/Asura_Logfile.h"

// Engine platform-specific.
#include "Rendering/Asura_PS3_CharacterRenderer.h"
#include "Rendering/Asura_PS3_Graphics.h"
#include "Rendering/Shaders/Asura_PS3_GCM_ShadersLibrary.h"
#include "Rendering/Asura_PS3_MaterialResponse_System.h"
#include "ChunkSystem/Asura_Chunk_ResourceFile_PS3.h"

// C L A S S   I M P L E M E N T A T I O N S /////////////////////////////////

void Asura_Chunk_ResourceFile_PS3_Character::Process( const char* szResourceFilename, Asura_Chunk_Stream& xStream )
{
	if( Version != ASURA_PS3_CHARACTER_CHUNK_VERSION )
	{
		Asura_Assertf( false, ("Invalid character chunk version (%d) encountered. Should be %d. You may need new code, or to re-export the level.", Version, ASURA_PS3_CHARACTER_CHUNK_VERSION) );
		return;
	}

	Asura_OutputToDebugger(( "Smooth skin: %s\n", szResourceFilename ));

	Asura_Hash_ID uNameHash;
	xStream >> uNameHash;
    
	u_int uNumStrips;
	u_int uNumVertices, uNumIndices;

	xStream >> uNumStrips;
	xStream >> uNumVertices;
	xStream >> uNumIndices;

	Asura_PS3_CharacterRenderer_Skin* const pxCharacter = Asura_PS3_CharacterRenderer::CreateCharacter( uNameHash, uNumStrips );
	if( !pxCharacter )
	{
		int iSkip = 4 + uNumStrips * ( sizeof( Asura_PS3_CharacterRenderer_Strip ) - 4 );
		iSkip += uNumVertices * Asura_PS3_CharacterRenderer::GetVertexSize();
		iSkip += uNumIndices * 2;
		xStream.Skip( iSkip );
		return;
	}

	xStream >> pxCharacter->m_uNumTriangles;

    // Read material header data and fix up material IDs.
	u_int uIndex			= 0;

	for( u_int uStrip = 0; uStrip < uNumStrips; ++uStrip )
	{
		xStream >> pxCharacter->m_pxStrips[ uStrip ].m_uFPHashID;
		xStream >> pxCharacter->m_pxStrips[ uStrip ].m_auMaterialResponseHashIDs[ 0 ];
		xStream >> pxCharacter->m_pxStrips[ uStrip ].m_auMaterialResponseHashIDs[ 1 ];
		xStream >> pxCharacter->m_pxStrips[ uStrip ].m_uNumIndices;
		xStream >> pxCharacter->m_pxStrips[ uStrip ].m_iElementID;
		pxCharacter->m_pxStrips[ uStrip ].m_uStartIndex = uIndex;
		uIndex += pxCharacter->m_pxStrips[ uStrip ].m_uNumIndices;
	}

    // Vertex data.
    {
        const u_int uVtxSize = Asura_PS3_CharacterRenderer::GetVertexSize();
        Asura_PS3_GCM_VertexBuffer& xVtxBfr = pxCharacter->m_xVertexBuffer;

		xVtxBfr.Initialise( uVtxSize, uNumVertices, CELL_GCM_LOCATION_MAIN, true );
        xStream.Read( uNumVertices * uVtxSize, xVtxBfr.LockForWriting() );
        xVtxBfr.Unlock();
    }

    // Index data.
    {
        Asura_PS3_GCM_IndexBuffer& xIndexBfr = pxCharacter->m_xIndexBuffer;

        xIndexBfr.Initialise( uNumIndices, CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16, CELL_GCM_LOCATION_MAIN, true );
        xStream.Read( xIndexBfr.GetIndexBufferSize(), xIndexBfr.LockForWriting() );
        xIndexBfr.Unlock();
    }
}
