//////////////////////////////////////////////////////////////////////
// Asura_ClientEntity_VolumeTrigger.cpp								//
// SJL 21/11/07														//
// Copyright (C) 2007 Rebellion, All Rights Reserved.			    //
//																	//
// A volume trigger with trigger and untrigger functionality that   //
// will check entities contained in project-specific lists.			//	
//////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header.
#include "Entity/Triggers/Asura_ClientEntity_VolumeTrigger.h"

// Engine independent.
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Entity/Asura_Entity_Classification.h"
#include "Entity/Triggers/Asura_ServerEntity_VolumeTrigger.h"

// Version numbers are kept separate between client and server so any changes can be detected easily.
static const int iASURA_VOLUME_TRIGGER_CHUNK_VERSION_CLIENT = 1; 

Asura_ClientEntity_VolumeTrigger::Asura_ClientEntity_VolumeTrigger(Asura_Guid uGuid)
:Asura_ClientEntity_Trigger(uGuid)
{
	Classification			= AsuraEntityClass_VolumeTrigger;
	m_uFlags 				= 0;
	m_uSpecificGuid			= ASURA_GUID_UNREGISTERED;
	m_bTriggersOnClient = false;
	m_pxVolumeGroup = new Asura_VolumeGroup();
}



Asura_ClientEntity_VolumeTrigger::~Asura_ClientEntity_VolumeTrigger()
{
	if (m_pxVolumeGroup) delete m_pxVolumeGroup;
}

bool Asura_ClientEntity_VolumeTrigger::IsTriggered(void)
{
	if (m_bHasAlreadyTriggered) 
	{
		return false;
	}
	if (IsVolumeOccupied() != (m_bTriggerOnNotOccupied ? true : false))
	{
		m_bHasAlreadyTriggered = true;
		return true;
	}
	return false;
}

bool Asura_ClientEntity_VolumeTrigger::IsUnTriggered(void)
{
	if (!m_bHasAlreadyTriggered)
	{
		return false;
	}
	if (IsVolumeOccupied() == (m_bTriggerOnNotOccupied ? true : false))
	{
		m_bHasAlreadyTriggered = false;
		return true;
	}
	return false;
}

bool Asura_ClientEntity_VolumeTrigger::IsVolumeOccupied()
{
	// This function needs over-riding by a project-class for any functionality.
	return false;
}

void Asura_ClientEntity_VolumeTrigger::OnUnTrigger()
{
	Asura_ClientEntity_Trigger::OnUnTrigger();
	if(m_bTriggerOnce)
	{
		//deactivate this trigger so it doesn't get triggered again
		OnDeactivation();
	}
}

void Asura_ClientEntity_VolumeTrigger::ReadFromChunkStream(Asura_Chunk_Stream& xStream)
{
	int iVersion;
	Asura_ReadFromStream_Bitfield_Wrapper<u_int>	xBitfield(m_uFlags);

	// The chunk version comes first.
	xStream >> iVersion;
	Asura_Assert( iASURA_VOLUME_TRIGGER_CHUNK_VERSION_CLIENT == iASURA_VOLUME_TRIGGER_CHUNK_VERSION_SERVER, "Client and server chunk versions do not match. Client chunk handling code needs updating." );
	Asura_Assert( iVersion <= iASURA_VOLUME_TRIGGER_CHUNK_VERSION_CLIENT, "Unexpected volume trigger chunk version" );
	if( iVersion > iASURA_VOLUME_TRIGGER_CHUNK_VERSION_CLIENT ) return;

	PARENT::ReadFromChunkStream(xStream);

	xStream >> xBitfield;
	xStream >> m_uSpecificGuid;

	bool bActive;
	xStream >> bActive; // backup, not needed for server entities, dealt with upclass.

	if (iVersion >= 1)
	{
		// m_uParentObjectGuid was added to the server chunk in version 1 but we have no use for it currently
		Asura_Guid uDummyGuid;
		xStream >> uDummyGuid;
	}

	m_pxVolumeGroup->ReadFromChunkStream(xStream);

	SetActive(bActive); // Copy of server active flag as we dont get this from upclass..
}


void Asura_ClientEntity_VolumeTrigger::Update()
{
	Asura_Assert(m_bTriggersOnClient, "Why does this exist if it doesnt trigger on client?");
	if (!m_bTriggersOnClient) return;

	Asura_ClientEntity_Trigger::Update();

	//If volume has become deactivated while triggered , then un-trigger it now.
	//Since these volumes are intended to trigger special effects while within the area covered,
	//it is likely that the effect should be stopped if the volume stops being used.
	if(m_bHasAlreadyTriggered && !IsActive())
	{
		m_bHasAlreadyTriggered = false;
		OnUnTrigger();
	}
}


