
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Chunk_Alien_PlayerAnimStateData.cpp
//
// Copyright (C) 2009 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

#include "ChunkSystem/AVP_Chunk_Alien_PlayerAnimStateData.h"

#include "ChunkSystem/Asura_SaveBlock.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"

#include "Actor/AVP_Actor_AnimStateData.h"
#include "Actor/Vertebrates/Alien/AVP_Alien_PlayerAnimStateData.h"
#include "Blueprint/AVP_Blueprint_HashIDs.h"
#include "ChunkSystem/AVP_Chunk_Loaders.h"

static const u_int g_uChunkVersion = 1;

#if defined (ASURA_TOOLS)

bool AVP_Chunk_Alien_PlayerAnimStateData::WriteToFile( Asura_String& xFileName, const bool bMultiplayer )
{
	Asura_SaveBlock					xSaveBlock;
	Asura_Chunk_SaveBlock_Stream	xStream( &xSaveBlock );

	// Fill-in the save-block...
	WriteToChunkStream( xStream, bMultiplayer );

	// Terminate the Asura-file...
	xStream.WriteAsuraTerminator();

	// ...before saving the file to disc...
	return xSaveBlock.SaveFile( xFileName.GetString(), false );
}

void AVP_Chunk_Alien_PlayerAnimStateData::WriteToChunkStream( Asura_Chunk_Stream& xStream, const bool bMultiplayer )
{
	// Begin writing...
	xStream.WriteChunk_Start( AVP_CHUNKID_ALIEN_PLAYERANIMSTATEDATA, g_uChunkVersion, 0 );

	AVP_Alien_PlayerAnimStateData::GetSingleton().Initialise( uAVP_BLUEPRINT_TYPE_ANIMSTATE_ALIEN, bMultiplayer );
	
	// chunk out all the array sizes and scream blue murder if they've changed.
	xStream << 2;
	xStream << 2;
	xStream << AVP_Vertebrate_PlayerAnimStateHandler::MOVESTATE_END_NOAIM;
	xStream << AVP_Vertebrate_PlayerAnimStateHandler::MOVESPEED_END;

	for ( u_int uHudItr = 0; uHudItr < 2; ++uHudItr )
	{
		for ( u_int uFloorItr = 0; uFloorItr < 2; ++uFloorItr )
		{
			for ( u_int uStateItr = 0; uStateItr < AVP_Vertebrate_PlayerAnimStateHandler::MOVESTATE_END_NOAIM; ++uStateItr )
			{
				for ( u_int uSpeedItr = 0; uSpeedItr < AVP_Vertebrate_PlayerAnimStateHandler::MOVESPEED_END; ++uSpeedItr )
				{
					const AVP_Actor_AnimStateData* pxStateData = AVP_Alien_PlayerAnimStateData::GetSingleton().m_aaaapxAnimStateData[ uHudItr ][ uFloorItr ][ uStateItr ][ uSpeedItr ];
					xStream << ( pxStateData != NULL );
					if ( pxStateData != NULL )
					{
						AVP_Actor_AnimStateData::WriteToChunkStream( xStream, pxStateData );
					}
				}
			}
		}
	}

	AVP_Alien_PlayerAnimStateData::GetSingleton().ResetStorage();

	xStream.WriteChunk_End();
}

#endif

void AVP_Chunk_Alien_PlayerAnimStateData::ReadFromChunkStream( Asura_Chunk_Stream& xStream )
{
	u_int uVersion = static_cast< u_int >( Version );
	Asura_Assertf( uVersion > 0 && uVersion <= g_uChunkVersion, ( "Invalid chunk version (%d)!", uVersion ) );
	if ( uVersion == 1 )
	{
		u_int uNumHud;
		xStream >> uNumHud;
		Asura_Assert( uNumHud == 2, "Chunk data inconsistent with code, does the common or character data need re-exporting?" );

		u_int uNumFloor;
		xStream >> uNumFloor;
		Asura_Assert( uNumFloor == 2, "Chunk data inconsistent with code, does the common or character data need re-exporting?" );

		u_int uNumStates;
		xStream >> uNumStates;
		Asura_Assert( uNumStates == AVP_Vertebrate_PlayerAnimStateHandler::MOVESTATE_END_NOAIM, "Chunk data inconsistent with code, does the common or character data need re-exporting?" );

		u_int uNumSpeeds;
		xStream >> uNumSpeeds;
		Asura_Assert( uNumSpeeds == AVP_Vertebrate_PlayerAnimStateHandler::MOVESPEED_END, "Chunk data inconsistent with code, does the common or character data need re-exporting?" );

		for ( u_int uHudItr = 0; uHudItr < uNumHud; ++uHudItr )
		{
			for ( u_int uFloorItr = 0; uFloorItr < uNumFloor; ++uFloorItr )
			{
				for ( u_int uStateItr = 0; uStateItr < uNumStates; ++uStateItr )
				{
					for ( u_int uSpeedItr = 0; uSpeedItr < uNumSpeeds; ++uSpeedItr )
					{
						bool bHasStateData;
						xStream >> bHasStateData;
						AVP_Actor_AnimStateData* pxStateData = NULL;
						if ( bHasStateData )
						{
							pxStateData = AVP_Actor_AnimStateData::CreateFromChunkStream( xStream );
						}

						if ( uHudItr < 2 && uFloorItr < 2 && uStateItr < AVP_Vertebrate_PlayerAnimStateHandler::MOVESTATE_END_NOAIM && uSpeedItr < AVP_Vertebrate_PlayerAnimStateHandler::MOVESPEED_END )
						{
							AVP_Alien_PlayerAnimStateData::GetSingleton().m_aaaapxAnimStateData[ uHudItr ][ uFloorItr ][ uStateItr ][ uSpeedItr ] = pxStateData;
						}
					}
				}
			}
			AVP_Alien_PlayerAnimStateData::GetSingleton().m_bInitialised = true;
		}
	}
}
