//////////////////////////////////////////////////////////////////////////////
//
// AVP_ServerEntity_InteractRetinalScanner.h
//
// Created by AJK 24/11/2008
//
// Copyright (c) 2008 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header.
#include "Entity/PhysicalObject/Interact/ToolReceptacle/RetinalScanner/AVP_ServerEntity_InteractRetinalScanner.h"

// Asura
#include "Entity/Asura_StaticMessage_System.h"

//AVP
#include "Entity/PhysicalObject/Interact/ToolReceptacle/RetinalScanner/AVP_Messages_InteractRetinalScanner.h"
#include "Entity/AVP_Entity_Classification.h"
#include "Entity/AVP_Messages.h"
#include "Entity/PhysicalObject/Actor/AVP_Actor_Messages.h"
#include "Entity/PhysicalObject/Interact/ToolReceptacle/RetinalScanner/AVP_ClientEntity_InteractRetinalScanner.h"

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

Asura_Hashed_List<AVP_ServerEntity_InteractRetinalScanner> AVP_ServerEntity_InteractRetinalScanner::s_xList;

AVP_ServerEntity_InteractRetinalScanner::AVP_ServerEntity_InteractRetinalScanner( Asura_Guid uGuid ) 
: Asura_Entity_Server( uGuid )
, PARENT( uGuid )
, m_usPredatorUseHeadMessageBlock( ASURA_STATICMESSAGE_EMPTYBLOCK )
, m_uVictimBlueprintHashID( ASURA_HASH_ID_UNSET)
, m_uVictimBlueprintType( ASURA_HASH_ID_UNSET)
{
	Classification = AVP_ENTITYCLASS_INTERACT_RETINAL_SCANNER;

	s_xList.AddToList(this);
}

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

void AVP_ServerEntity_InteractRetinalScanner::ReadFromChunkStream(Asura_Chunk_Stream& xStream)
{
	int iCurrentChunkVersion;

	xStream >> iCurrentChunkVersion;

	switch ( iCurrentChunkVersion )
	{
	case CURRENT_CHUNK_VERSION :
		{
			PARENT::ReadFromChunkStream(xStream);
			xStream >> m_usPredatorUseHeadMessageBlock;
			xStream >> m_uVictimBlueprintHashID;
			xStream >> m_uVictimBlueprintType;
			break;
		}
	default :
		{
			Asura_Assertf(false, ("Unknown chunk version (%d) in AVP_ServerEntity_InteractRetinalScanner", iCurrentChunkVersion));
			break;
		}
	}
}

void AVP_ServerEntity_InteractRetinalScanner::WriteToChunkStream(Asura_Chunk_Stream& xStream) const
{
	xStream << CURRENT_CHUNK_VERSION;

	PARENT::WriteToChunkStream( xStream );

	xStream << m_usPredatorUseHeadMessageBlock;

	xStream << m_uVictimBlueprintHashID;
	xStream << m_uVictimBlueprintType;
}

void AVP_ServerEntity_InteractRetinalScanner::MakeCreateMessage( Asura_Guid uRequestingClient, bool bSendGuaranteed /*= false*/ )
{
	Asura_Message* pxMessage = Asura_Network::CreateMessage(ASURA_MSG_CLIENTCREATE, sizeof( AVP_Message_InteractRetinalScanner_ClientCreate ), GetClassification());
	if(pxMessage)
	{
		AVP_Message_InteractRetinalScanner_ClientCreate* pxData = static_cast< AVP_Message_InteractRetinalScanner_ClientCreate* >( pxMessage->GetData() );
		pxData->FillInteractionObject(this);

		pxMessage->SetToGuid( ASURA_GUID_MY_CLIENT_ENTITIES );
		pxMessage->SetFromGuid( GetGuid() );
		if (bSendGuaranteed)
		{
			pxMessage->UseGuaranteedDelivery();
		}
		Asura_Network::SendToSpecificMachine( pxMessage, uRequestingClient );
	}
}

#ifdef ASURA_TOOLS
void AVP_ServerEntity_InteractRetinalScanner::CreateFromTools(Asura_Guid uGuid)
{
	new AVP_ServerEntity_InteractRetinalScanner(uGuid);
}

bool AVP_ServerEntity_InteractRetinalScanner::CanBeIncludedInTemplate() const
{
	return (GetClassification() == AVP_ENTITYCLASS_INTERACT_RETINAL_SCANNER);
}

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

	m_usPredatorUseHeadMessageBlock = pxInstance->ConvertMessageBlock( m_usPredatorUseHeadMessageBlock );
}
#endif // #ifdef ASURA_TOOLS

bool AVP_ServerEntity_InteractRetinalScanner::HandleMessage(const Asura_Message* pxMsg)
{
	switch ( pxMsg->GetMsgID() )
	{
	case AVP_MSGID_REQUEST_INTERACTION:
		{
			const AVP_Message_Actor_RequestInteraction*	pxData = static_cast< const AVP_Message_Actor_RequestInteraction* >( pxMsg->GetData() );
			if ( pxData )
			{
				Asura_Assert( pxData->GetInteractionType() == AVP_INTERACTION_TYPE_DEFAULT, "Interaction objects only handle default interactions" );
				if( pxData->GetInteractionMoveType() ==  AVP_Message_Actor_RequestInteraction::INTERACTION_INTIATED)
				{
					SendPredatorUseHeadMessage();
					Asura_Network::Forward( pxMsg, ASURA_GUID_MY_CLIENT_ENTITIES, GetGuid() );
					return true;
				}
			}
			else
			{
				Asura_Assert( false, "No data" );
				return false;
			}
			return false;
		}

	default:
		return PARENT::HandleMessage(pxMsg);
	}
}

void AVP_ServerEntity_InteractRetinalScanner::SendPredatorUseHeadMessage()
{
	if ( m_usPredatorUseHeadMessageBlock != ASURA_STATICMESSAGE_EMPTYBLOCK )
	{
		Asura_StaticMessage_System::SendMessages( m_usPredatorUseHeadMessageBlock, GetGuid() );
	}
}

#ifdef ASURA_TOOLS
void AVP_ServerEntity_InteractRetinalScanner::GetCustomEventName(int iEventIndex, Asura_String& xEventName)
{
	switch(iEventIndex)
	{
	case MESSAGE_BLOCK_PREDATOR_USE_HEAD:	xEventName = "On Predator use head";		return;
	}

	Asura_Assert(FALSE, "Invalid Retinal scanner object event index");

	xEventName = "";
}

unsigned short* AVP_ServerEntity_InteractRetinalScanner::GetCustomEvent(int iIndex)
{
	switch(iIndex)
	{
	case MESSAGE_BLOCK_PREDATOR_USE_HEAD:	return &m_usPredatorUseHeadMessageBlock;
	}

	Asura_Assert(FALSE, "Invalid Retinal scanner object event index");

	return NULL;
}
#endif // ASURA_TOOLS
