//////////////////////////////////////////////////////////////////////////////
//
// Asura_ClientEntity_StartPoint.cpp
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
// Description:
//
//     Player start point entity (client-side)
//
//////////////////////////////////////////////////////////////////////////////

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

#include "Core/Asura.h"

// This file's header.
#include "Entity/Spawners/Asura_ClientEntity_StartPoint.h"

#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Entity/Asura_Entity_Classification.h"
#include "Entity/Spawners/Asura_ServerEntity_StartPoint.h"
#include "Network/Asura_Message.h"

#ifdef ASURA_TOOLS
#include "EntityTemplate/Tools_EntityTemplate_System.h"
#endif


// static data
Asura_Hashed_List<Asura_ClientEntity_StartPoint> Asura_ClientEntity_StartPoint::s_xList;

//////////////////////////////////////////////////////////////////////////
// Ctor / ~tor
//////////////////////////////////////////////////////////////////////////

Asura_ClientEntity_StartPoint::Asura_ClientEntity_StartPoint(Asura_Guid uGuid)
: Asura_Entity_Client(uGuid)
, m_xPosition( Asura_Maths::ZeroVector3 )
, m_xOrientation( Asura_Maths::IdentityMatrix3x3 )
{
	Classification	= AsuraEntityClass_StartPoint;
	
	s_xList.AddToList(this);
}

Asura_ClientEntity_StartPoint::~Asura_ClientEntity_StartPoint()
{
	s_xList.RemoveFromList(this);
}

//////////////////////////////////////////////////////////////////////////
//	Static create functions
//////////////////////////////////////////////////////////////////////////
void Asura_ClientEntity_StartPoint::Create( Asura_Guid uGuid, Asura_Chunk_Stream& xStream )
{
	Asura_ClientEntity_StartPoint* pxStartPoint = new Asura_ClientEntity_StartPoint(uGuid);
	if(pxStartPoint)
	{
		pxStartPoint->ReadFromChunkStream( xStream );
	}
}

//////////////////////////////////////////////////////////////////////////
//	Chunk handling
//////////////////////////////////////////////////////////////////////////

void Asura_ClientEntity_StartPoint::ReadFromChunkStream( Asura_Chunk_Stream& xStream )
{
	// get version number
	int iChunkVersion = -1;
	xStream >> iChunkVersion;

	if(iChunkVersion >= 1)
	{
		// must skip over the server entity data first
		// Also get the blueprint data if it exists
		Asura_Entity_Server::SkippedServerData xSkippedData;

		Asura_Entity_Server::SkipDataInChunkStream(xStream, &xSkippedData);

		SetBlueprintHashID(xSkippedData.m_uBlueprintHashID);
		SetBlueprintTypeHashID(xSkippedData.m_uBlueprintTypeHashID);
	}

	if (iChunkVersion > Asura_ServerEntity_StartPoint::CURRENT_CHUNK_VERSION || iChunkVersion < 0)
	{
		Asura_Assert( 0, "Unknown chunk buffer version for start point.\n");
		return;
	}

	// Currently in all versions
	xStream >> m_xPosition;
	xStream >> m_xOrientation;

	if (iChunkVersion <= 1)
	{
		u_int uDummyFlags = 0;
		Asura_ReadFromStream_Bitfield_Wrapper< u_int > xFlagsBitfield( uDummyFlags );
		xStream >> xFlagsBitfield;
		if (uDummyFlags) { SetEntityActiveFromLoad( true ); }
	}

#ifdef ASURA_ASSERT
	// check this loading code still works
	if (Asura_Network::IsServer())
	{
		const Asura_ServerEntity_StartPoint* pxServerEntity	= Asura_ServerEntity_StartPoint::FindEntity( GetGuid() );
		Asura_Assert(pxServerEntity, "failed to find corresponding server entity start point");
		if (pxServerEntity)
		{
			Asura_Assert(pxServerEntity->GetPosition() == m_xPosition && 
				pxServerEntity->GetOrientation() == m_xOrientation, "client and server start point entities don't match");
		}
	}
#endif
}

#ifdef ASURA_TOOLS
void Asura_ClientEntity_StartPoint::ApplyChangesForTemplateInstance(Tools_EntityTemplateInstance* pxInstance)
{
	Asura_Entity_Client::ApplyChangesForTemplateInstance(pxInstance);

	//update position and orientation
	m_xPosition = pxInstance->TransformPosition(m_xPosition);
	m_xOrientation = pxInstance->TransformMatrix(m_xOrientation);
}
#endif // ASURA_TOOLS


