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

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

// core
#include "Core/Asura.h"

// header
#include "ChunkSystem/Asura_Chunk_CurrentStreamingZone.h"

#ifdef ASURA_USE_STREAMING

// asura
#include "ChunkSystem/Asura_Chunk_Loaders.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "ChunkSystem/Asura_SaveBlock.h"
#include "Core/Asura_Core.h"
#include "FileAccess/Asura_FileAccess.h"
#include "Streaming/Asura_Streaming_System.h"
#include "Streaming/Asura_Streaming_Zone.h"
#include "Streaming/Asura_Streaming_ZoneDataState.h"


//////////////////////////////////////////////////////////////////////////////
//
// ChunkData
//
//////////////////////////////////////////////////////////////////////////////

struct ChunkData
{
	// The chunk is the filename of the zone in this version
	enum { CURRENT_VERSION = 0 };
};

//////////////////////////////////////////////////////////////////////////////
//
// 
//
//////////////////////////////////////////////////////////////////////////////

bool Asura_Chunk_CurrentStreamingZone::Create(Asura_SaveBlock_Base& xSaveBlock)
{
	const Asura_Streaming_Zone* pxZone = Asura_Streaming_System::GetCurrentZone();
	if (!pxZone) { return false; }

	bool bSuccess = false;
	Asura_String xZoneFilename = pxZone->GetFilename();
#if 0
	const int iChunkSize = sizeof( Asura_Chunk_CurrentStreamingZone ) + (xZoneFilename.GetSizeInInts()*4);
	
	//Create chunk

	Asura_Chunk_CurrentStreamingZone* pxChunk = reinterpret_cast< Asura_Chunk_CurrentStreamingZone* >( xSaveBlock.GetAccessPointer( iChunkSize ) );
	if ( pxChunk == NULL )
	{
		return false;
	}

	//Fill chunk header
	pxChunk->ID      = static_cast< ASURA_CHUNKID >( ASURA_CHUNK_CURRENTSTREAMINGZONE );
	ASURA_CHUNK_VERIFY(pxChunk->ID, int);
	pxChunk->Size    = iChunkSize;
	ASURA_CHUNK_VERIFY(pxChunk->Size, int);
	pxChunk->Version = ChunkData::CURRENT_VERSION;
	ASURA_CHUNK_VERIFY(pxChunk->Version, int);
	pxChunk->Flags   = 0;
	ASURA_CHUNK_VERIFY(pxChunk->Flags, int);

	char* pcChunkBuffer = reinterpret_cast<char*>(pxChunk+1);
	ASURA_CHUNK_FILL_STRING(pcChunkBuffer, xZoneFilename); 
#else
	Asura_Chunk_SaveBlock_Stream xStream(&xSaveBlock);
	xStream.WriteChunk_Start(ASURA_CHUNK_CURRENTSTREAMINGZONE, ChunkData::CURRENT_VERSION, 0);
	xStream << xZoneFilename;
	xStream.WriteChunk_End();
#endif
	return bSuccess;
}

bool Asura_Chunk_CurrentStreamingZone::Process( Asura_Chunk_Stream& xStream ) const
{
	if ( Version == ChunkData::CURRENT_VERSION )
	{
   		// Set up the required zone from this.
		Asura_String xLevelFilename;
		xStream >> xLevelFilename;
		Asura_String xLevelName;
		xLevelFilename.SplitFilename(NULL, &xLevelName, NULL);
		const Asura_Hash_ID uNameHash = Asura_GetHashID(xLevelName.GetString());

		// First, check if we're going to load a level that's already loaded
		const Asura_Streaming_Zone* pxZone = Asura_Streaming_System::FindZone(uNameHash);
		if (pxZone)
		{
			// Next, make sure it's a high detail zone
			const Asura_Streaming_ZoneDataState* pxDataState = pxZone->GetZoneDataState(Asura_Streaming_Zone::HIGH_DETAIL_DATA);
			if (pxDataState && pxDataState->IsFull())
			{
				// Zone exists fully, don't do anything
				return true;
			}
		}

		// OK, so we have the zone filename and it's not the current zone, let the project figure out how to handle the loading.
		Project_ProcessFilename(xLevelFilename);
	}
	else
	{
		Asura_Assertf( false, ( "Asura_Chunk_CurrentStreamingZone - unsupported chunk version: %i", Version ) );
		return false;
	}
	return true;
}

#endif //#ifdef ASURA_USE_STREAMING
