//*******************************************************************
// File: Asura_Chunk_ResourceFile_Xbox360_Carpet.cpp
//
// Created: 26 January 2007 DLH
//
// Description: 
//
//*******************************************************************

// system libraries
#include "Core/Asura.h"

#if defined( ASURA_USE_CARPET)

// main header
#include "Carpet/Asura_XBox360_Carpet.h"
#include "ChunkSystem/Asura_Chunk_ResourceFile_Xbox360_Carpet.h"

// other libraries
#include "ChunkSystem/Asura_SaveBlock.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "ChunkSystem/Asura_Chunk_Loaders.h"

#include "Core/Asura_Hash.h"
#include "Core/Asura_Texturemanagement.h"

// internal dependencies

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


//*******************************************************************
// Local Classes
//*******************************************************************


//*******************************************************************
// Local Datas
//*******************************************************************


//*******************************************************************
// Function Definitions
//*******************************************************************

bool Asura_XBox360_CGR_PolygonStyle::Process( Asura_Chunk_Stream &xStream)
{
	for( uint32 uTableIndex = 0; uTableIndex < ASURA_DIRECT3D_CGR_POLYGONSTYLE_LOOKUP_LENGTH; uTableIndex += 1)
	{
		xStream >> this->m_aucStyleLookup[ uTableIndex];
	}

	return( true);
}

bool Asura_XBox360_CGR_Style::Process( Asura_Chunk_Stream &xStream)
{
	xStream >> this->m_fWidth;
	xStream >> this->m_fHeight;
	xStream >> this->m_afU[0];
	xStream >> this->m_afU[1];
	xStream >> this->m_afV[0];
	xStream >> this->m_afV[1];
	xStream >> this->m_fScaleMin;
	xStream >> this->m_fLodFadeFar;
	xStream >> this->m_fLodFadeNear;
	xStream >> this->m_fLodFadeDelta;
	xStream >> this->m_fMovementScale;
	
	return( true);
}

bool Asura_XBox360_CGR_PolygonBatch::Process( Asura_Chunk_Stream &xStream)
{
	xStream >> this->m_uDataOffset;
	xStream >> this->m_uDataSize;
	
	return( true);
}

bool Asura_XBox360_CGR_Vertex::Process( Asura_Chunk_Stream &xStream)
{
	xStream >> this->m_fDensity;
	xStream >> this->m_xColourRGB;
	xStream >> this->m_xPosition;
	
	return( true);
}

bool Asura_XBox360_CGR_Polygon::Process( Asura_Chunk_Stream &xStream)
{
	xStream >> this->m_fLodFadeFar;
	xStream >> this->m_fDenisty;
	xStream >> this->m_uInstanceCount;
	xStream >> this->m_uRandomSeed;
	xStream >> this->m_uPolygonStyle;
	
	xStream >> this->m_uVertexIndex[0];
	xStream >> this->m_uVertexIndex[1];
	xStream >> this->m_uVertexIndex[2];
	
	return( true);
}

bool Asura_XBox360_CGR_RTreeNode::Process( Asura_Chunk_Stream &xStream, Asura_XBox360_CGR_RTreeNode* pxRTreeNodeBase)
{
	xStream >> this->m_xBoundingBox;
	xStream >> this->m_uData;
	
	uint32 uSiblingIndex;
	uint32 uChildIndex;
	xStream >> uSiblingIndex;
	xStream >> uChildIndex;
	
	this->m_pxSibling = (uint32( -1) != uSiblingIndex) ? (pxRTreeNodeBase + uSiblingIndex) : NULL;
	this->m_pxChild = (uint32( -1) != uChildIndex) ? (pxRTreeNodeBase + uChildIndex) : NULL;
	
	return( true);
}

bool Asura_XBox360_CGR_Mesh::Process( Asura_Chunk_Stream &xStream)
{
	Asura_Hash_ID xTextureHash;
	xStream >> xTextureHash;
	this->m_iTexture = Asura_Texture_Management::GetIndexFromHashID( xTextureHash);
	
	xStream >> this->m_xBoundingBox;
	xStream >> this->m_fLodFadeFar;
	
	{
		uint32 uPolygonCount;
		uint32 uPolygonBatchCount;
		uint32 uPolygonStyleCount;
		uint32 uRTreeCount;
		uint32 uStyleCount;
		uint32 uVertexCount;
		
		xStream >> uPolygonCount;
		xStream >> uPolygonBatchCount;
		xStream >> uPolygonStyleCount;
		xStream >> uRTreeCount;
		xStream >> uStyleCount;
		xStream >> uVertexCount;
		
		this->m_uPolygonCount = uPolygonCount;
		this->m_uPolygonBatchCount = uPolygonBatchCount;
		this->m_uPolygonStyleCount = uPolygonStyleCount;
		this->m_uRTreeCount = uRTreeCount;
		this->m_uStyleCount = uStyleCount;
		this->m_uVertexCount = uVertexCount;
	}
	
	this->m_pxPolygons = new Asura_XBox360_CGR_Polygon[ this->m_uPolygonCount];
	this->m_pxPolygonBatches = new Asura_XBox360_CGR_PolygonBatch[ this->m_uPolygonBatchCount];
	this->m_pxPolygonStyles = new Asura_XBox360_CGR_PolygonStyle[ this->m_uPolygonStyleCount];
	this->m_pxRTree = new Asura_XBox360_CGR_RTreeNode[ this->m_uRTreeCount];
	this->m_pxStyles = new Asura_XBox360_CGR_Style[ this->m_uStyleCount];
	this->m_pxVertices = new Asura_XBox360_CGR_Vertex[ this->m_uVertexCount];
	
	for( uint32 uVertexIndex = 0; uVertexIndex < this->m_uVertexCount; uVertexIndex += 1)
	{
		if( false == this->m_pxVertices[ uVertexIndex].Process( xStream))
		{
			return( false);
		}
	}
	
	for( uint32 uPolygonIndex = 0; uPolygonIndex < this->m_uPolygonCount; uPolygonIndex += 1)
	{
		if( false == this->m_pxPolygons[ uPolygonIndex].Process( xStream))
		{
			return( false);
		}
	}
	
	for( uint32 uPolygonStyleIndex = 0; uPolygonStyleIndex < this->m_uPolygonStyleCount; uPolygonStyleIndex += 1)
	{
		if( false == this->m_pxPolygonStyles[ uPolygonStyleIndex].Process( xStream))
		{
			return( false);
		}
	}
	
	for( uint32 uPolygonBatchIndex = 0; uPolygonBatchIndex < this->m_uPolygonBatchCount; uPolygonBatchIndex += 1)
	{
		if( false == this->m_pxPolygonBatches[ uPolygonBatchIndex].Process( xStream))
		{
			return( false);
		}
	}
	
	for( uint32 uRTreeNodeIndex = 0; uRTreeNodeIndex < this->m_uRTreeCount; uRTreeNodeIndex += 1)
	{
		if( false == this->m_pxRTree[ uRTreeNodeIndex].Process( xStream, this->m_pxRTree))
		{
			return( false);
		}
	}
	
	for( uint32 uStyleIndex = 0; uStyleIndex < this->m_uStyleCount; uStyleIndex += 1)
	{
		if( false == this->m_pxStyles[ uStyleIndex].Process( xStream))
		{
			return( false);
		}
	}
	
	return( true);
}

bool Asura_Chunk_ResourceFile_Xbox360_Carpet::Process( const char* const szFilename, Asura_Chunk_Stream& xStream )
{
//	Asura_Chunk_Stream	xStream( hFile);

	if (Version!=CURRENT_VERSION)
	{
		Asura_Assert(false, "Carpet chunk version has changed, please re-export level");
		return(false);
	}
	
	uint32 uCGRMeshCount;
	xStream >> uCGRMeshCount;
	
	Asura_Assert( NULL == Asura_XBox360_Carpet_Game_Render::s_pxMeshes, "Need to clear the CGR Meshes");
	Asura_Assert( 0 == Asura_XBox360_Carpet_Game_Render::s_uMeshesCount, "Need to clear the CGR Meshes");
	Asura_XBox360_Carpet_Game_Render::s_uMeshesCount = uCGRMeshCount;
	Asura_XBox360_Carpet_Game_Render::s_pxMeshes = new Asura_XBox360_CGR_Mesh[ Asura_XBox360_Carpet_Game_Render::s_uMeshesCount];
	
	for( uint32 uCGRMeshIndex = 0; uCGRMeshIndex < uCGRMeshCount; uCGRMeshIndex += 1)
	{
		Asura_XBox360_CGR_Mesh& xCGRMesh = Asura_XBox360_Carpet_Game_Render::s_pxMeshes[ uCGRMeshIndex];
		
		if( false == xCGRMesh.Process( xStream))
		{
			return(false);
		}
	}

	float fMovementSpeed;
	xStream >> fMovementSpeed;
	Asura_Carpet_MeshManager::SetMovementSpeed(fMovementSpeed);

	Asura_XBox360_Carpet_Game_Render::CreateDirect3DData();
	Asura_XBox360_Carpet_Game_Render::BatchCopyAllToBuffers();
	return(true);
}

//*******************************************************************
//
// (c) 2006 Rebellion
//
// Warning: This computer program is protected by copyright law and 
// international treaties. Unauthorized reproduction or distribution
// of this program, or any portion of it, may result in severe civil and
// criminal penalties, and will be prosecuted to the maximum extent 
// possible under the law.
//
//*******************************************************************

#endif //defined( ASURA_USE_CARPET)
