//----------------------------------------------------------------------------
// File		:	AVP_ServerNode_CoverpointNode.h
// Created	:	28 / 02 / 08
// Author	:	Gareth Thomas
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//----------------------------------------------------------------------------

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

// This Files Header
#include "Entity/Locations/OrientedNode/CoverpointNode/AVP_ServerNode_CoverpointNode.h"

// asura
#include "AI/Asura_AI_Navigation.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Dynamics/Asura_Collision_Object.h"
#ifdef ASURA_TOOLS
#include "EntityTemplate/Tools_EntityTemplate_System.h"
#endif
#include "Mesh/Asura_Mesh_PolygonFlags.h"
#include "Physics/Asura_Physics_Object.h"

// AVP
#include "Entity/AVP_Entity_Classification.h"


#ifdef ASURA_TOOLS
#include "Waypointing/Tools_Mode_Waypointing.h"
#endif

//----------------------------------------------------------------------------
// Function		AVP_ServerNode_CoverpointNode :: Constructor
//----------------------------------------------------------------------------
AVP_ServerNode_CoverpointNode::AVP_ServerNode_CoverpointNode(Asura_Guid uGuid)
: PARENT(uGuid)
, m_uNumLinkedCoverPoints(0)
, m_iLowCoverType(0)
{
	Classification = AVP_ENTITYCLASS_COVERPOINT;

	for (u_int u = 0; u < MAX_LINKED_COVERPOINTS; ++u)
	{
		m_auLinkedCoverPointGuids[u] = ASURA_GUID_UNREGISTERED;
	}

	SetNeverUpdateClient();
	SetNeverUpdates(true);
}

void AVP_ServerNode_CoverpointNode::CreateFromChunkStream( Asura_Guid uGuid, Asura_Chunk_Stream& xStream )
{
	PARENT::CreateFromChunkStream(uGuid, xStream);
}

void AVP_ServerNode_CoverpointNode::ReadFromChunkStream( Asura_Chunk_Stream& xStream )
{
	//Version
	u_int uVersion;
	xStream	>> uVersion;

	//Parent
	PARENT::ReadFromChunkStream(xStream);

	if (uVersion == 2)
	{
		xStream >> m_uNumLinkedCoverPoints;

		for ( u_int u = 0; u < MAX_LINKED_COVERPOINTS; ++u )
		{
			xStream >> m_auLinkedCoverPointGuids[ u ];
		}

		m_iLowCoverType = 0;
	}
	else if ( uVersion == 3 )
	{
		xStream >> m_uNumLinkedCoverPoints;

		for ( u_int u = 0; u < 3; ++u )
		{
			xStream >> m_auLinkedCoverPointGuids[ u ];
		}

		m_auLinkedCoverPointGuids[ 3 ] = ASURA_GUID_UNREGISTERED;

		xStream >> m_iLowCoverType;
	}
	else if ( uVersion == AVP_ServerNode_CoverpointNode::CURRENT_CHUNK_VERSION )
	{
		xStream >> m_uNumLinkedCoverPoints;

		for ( u_int u = 0; u < MAX_LINKED_COVERPOINTS; ++u )
		{
			xStream >> m_auLinkedCoverPointGuids[ u ];
		}

		xStream >> m_iLowCoverType;
	}
}

void AVP_ServerNode_CoverpointNode::WriteToChunkStream( Asura_Chunk_Stream& xStream ) const
{
	//Version
	xStream << CURRENT_CHUNK_VERSION;

	//Parent
	PARENT::WriteToChunkStream(xStream);

	xStream << m_uNumLinkedCoverPoints;

	for (u_int u = 0; u < MAX_LINKED_COVERPOINTS; ++u)
	{
		xStream << m_auLinkedCoverPointGuids[u];
	}

	xStream << m_iLowCoverType;
}

bool AVP_ServerNode_CoverpointNode::IsBaseOrDerivativeOf(u_short usClassification) const
{
	return PARENT::IsBaseOrDerivativeOf(usClassification);
}

void AVP_ServerNode_CoverpointNode::SetIsOccupied(const bool bIsOccupied)
{
	if (IsOccupied() != bIsOccupied)
	{
		m_bIsOccupied = bIsOccupied;
	}

	// now we have to do the linked coverpoints.
	for (u_int u = 0; u < MAX_LINKED_COVERPOINTS; ++u)
	{
		if (GetLinkedCoverPointGuid(u) != ASURA_GUID_UNREGISTERED)
		{
			Asura_ServerNode_Coverpoint* pxCoverPoint = Asura_ServerNode_Coverpoint::FindEntity(GetLinkedCoverPointGuid(u));
			if (pxCoverPoint)
			{
				if (pxCoverPoint->IsOccupied() != bIsOccupied)
				{
					pxCoverPoint->SetIsOccupied(bIsOccupied);
				}
			}
		}
	}
}

//----------------------------------------------------------------------------
// Function		AVP_ServerNode_CoverpointNode :: Create
//----------------------------------------------------------------------------
AVP_ServerNode_CoverpointNode* AVP_ServerNode_CoverpointNode::Create(Asura_Guid uGuid)
{
	AVP_ServerNode_CoverpointNode* pxCoverPoint = new AVP_ServerNode_CoverpointNode(uGuid);

	return pxCoverPoint;
}

#ifdef ASURA_TOOLS
bool AVP_ServerNode_CoverpointNode::CanBeIncludedInTemplate() const
{
	return (Classification == AVP_ENTITYCLASS_COVERPOINT);
}

void AVP_ServerNode_CoverpointNode::ApplyChangesForTemplateInstance(Tools_EntityTemplateInstance* pxInstance)
{
	PARENT::ApplyChangesForTemplateInstance(pxInstance);

	for (u_int u = 0; u < MAX_LINKED_COVERPOINTS; ++u)
	{
		m_auLinkedCoverPointGuids[u] = pxInstance->ConvertGuid(m_auLinkedCoverPointGuids[u]);
	}
}
#endif
