//
// Tools_DialogueSpeaker_Object.cpp
//
// Created by Richard Rice - 21/11/2006
// 
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"
#include "Sound/Tools_DialogueSpeaker_Object.h"

#ifdef ASURA_USE_DIALOGUE_SYSTEM

#include "Core/Asura_Timers.h"
#include "Entity/PhysicalObject/Asura_ServerEntity_Actor.h"
#include "Entity/PhysicalObject/Asura_ServerEntity_PhysicalObject.h"
#include "Entity/Asura_StaticMessage_System.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Network/Asura_Guid.h"
#include "Network/Asura_Message.h"

#include "Entity/Tools_Entity_Data.h"
#include "Entity/Tools_Entity_Object.h"


Tools_DialogueSpeaker_Object::Tools_DialogueSpeaker_Object()
:Tools_SpecialGuid_Object(ASURA_GUID_DIALOGUE_SPEAKER,"Dialogue Speaker","ToolsShape_CutsceneActor")
{
	m_pxTargetObject = 0;
	m_uFindTargetFrameStamp = 0xffffffff;
}

Tools_DialogueSpeaker_Object::~Tools_DialogueSpeaker_Object()
{
	if(m_pxTargetObject)
	{
		m_pxTargetObject->RemoveReference(this);
		m_pxTargetObject = 0;
	}
}

bool Tools_DialogueSpeaker_Object::HandlesThisMessage(int iMessageID)
{
	//the speaker doesn't handle this message as such ,but this is as convenient target as any. RAR 22/11/2006
	if(iMessageID == ASURA_MSG_DIALOGUE_FROMINSTANCE) return true;
	
	if(!m_pxTargetObject) FindTargetObject();
	if(m_pxTargetObject) return m_pxTargetObject->HandlesThisMessage(iMessageID);

	
	return false;
//	return iMessageID == ASURA_MSG_CHANGE_ANIMATION;
}


void Tools_DialogueSpeaker_Object::FindTargetObject()
{
	//Don't search if we've already done so this frame
	//This is mainly to prevent multiple searches for each call to HandlesThisMessage() should there
	//not be any suitable target
	u_int uFrame = Asura_Timers::GetFrameNumber();
	if(uFrame == m_uFindTargetFrameStamp) return;
	m_uFindTargetFrameStamp = uFrame;

	if(m_pxTargetObject)
	{
		m_pxTargetObject->RemoveReference(this);
		m_pxTargetObject = 0;
	}


	//Search for any actor/npc entity
	for(Asura_Hashed_List_It<Asura_ServerEntity_Actor> xIt(Asura_ServerEntity_Actor::GetList());!xIt.Done();xIt.Next())
	{
		Asura_ServerEntity_Actor* pxEntity = xIt.GetCurrent();
		if(pxEntity->ToolsData && pxEntity->ToolsData->ToolsObject)
		{
			m_pxTargetObject = pxEntity->ToolsData->ToolsObject;
			m_pxTargetObject->AddReference(this);
			return;
		}		
	}

	//try for a physical object instead
	for(Asura_Hashed_List_It<Asura_ServerEntity_PhysicalObject> xIt(Asura_ServerEntity_PhysicalObject::GetList());!xIt.Done();xIt.Next())
	{
		Asura_ServerEntity_PhysicalObject* pxEntity = xIt.GetCurrent();
		if(pxEntity->ToolsData && pxEntity->ToolsData->ToolsObject)
		{
			m_pxTargetObject = pxEntity->ToolsData->ToolsObject;
			m_pxTargetObject->AddReference(this);
			return;
		}		
	}

}

void Tools_DialogueSpeaker_Object::ReferencedObjectIsBeingDeleted(Tools_Object* pxObject)
{
	Tools_SpecialGuid_Object::ReferencedObjectIsBeingDeleted(pxObject);
	
	if(pxObject == m_pxTargetObject)
	{
		//Target object is no more. We will need to search for another one later.
		m_pxTargetObject = 0;
		m_uFindTargetFrameStamp = 0xffffffff;
	}
}


void Tools_DialogueSpeaker_Object::AddMessageOverlayControls(struct Asura_StaticMessage* pxMessage,class Asura_Overlay* pxOverlay,class Asura_Vector_2& xOffset)
{
	if(pxMessage->m_usMsgID != ASURA_MSG_DIALOGUE_FROMINSTANCE)
	{
		Asura_Assert(0,"Unexpected message type");
	}
	Asura_Assert(pxMessage->m_pData,"");

	//message data just consists of an index
	u_int* puIndex = (u_int*) pxMessage->m_pData;

	Asura_Dialog* pxDialog;
	pxDialog = new Asura_Numerical_Dialog("Message Index",xOffset,puIndex,0,999,1,"%d");
	pxDialog->SetHelpText("Index of message to trigger from the calling dialogue instance.");
	xOffset.y += Asura_Dialog::DefaultSpacing();
	pxOverlay->AddDialog(pxDialog);
	

}



#endif //ASURA_USE_DIALOGUE_SYSTEM
