//-----------------------------------------------------------------------------
// File		: ToolsAVP_Entity_Human.cpp
// Author	: Gareth Thomas
// Created	: 18 / 12 / 07
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//-----------------------------------------------------------------------------

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

// Header
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/ToolsAVP_Entity_Android.h"

// Asura
#include "Blueprint/Asura_Blueprint_System.h"
#include "Camera/Asura_Camera.h"
#include "Entity/Tools_Entity_Data.h"
#include "Interface/Asura_Dialog.h"
#include "Interface/Asura_Overlay.h"
#include "Load&Save/Tools_SaveAsura.h"
#include "Mesh/Asura_Mesh_System.h"
#include "Objects/Tools_Object_System.h"
#include "Rendering/Asura_Render.h"

// AvP
#include "Entity/AVP_Entity_EventIDs.h"
#include "Entity/AVP_Messages.h"
#include "Blueprint/AVP_Blueprint_HashIDs.h"
#include "Entity/PhysicalObject/Actor/Vertebrates/Human/Android/AVP_ServerActor_Android.h"
#include "Entity/Controller/ToolsAVP_Entity_MarineSquad.h"
#include "Objects/ToolsAVP_Object_Type.h"

// tools
#include "Movement/Tools_Movement.h"
#include "Misc/Tools_Timed_Messages.h"

ToolsAVP_Entity_Android*						ToolsAVP_Entity_Android::s_pxSelectedAndroid		= NULL;	
Asura_Hashed_List<ToolsAVP_Entity_Android>		ToolsAVP_Entity_Android::s_xList;

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: Constructor
//-----------------------------------------------------------------------------
ToolsAVP_Entity_Android::ToolsAVP_Entity_Android(AVP_ServerActor_Android* pxActor)
: Tools_Entity_PhysicalObject(pxActor)
, PARENT(pxActor)
{
	Type = TOT_Entity_Android;

	s_pxSelectedAndroid = this;
	m_pxAndroid = pxActor;

	Mesh = Asura_Mesh_System::GetMesh("ToolsShape_Android");

	s_xList.AddToList(this);
}

void ToolsAVP_Entity_Android::RestoreMesh()
{
	// Restore original mesh
	SetMesh(Asura_Mesh_System::GetMesh("ToolsShape_Android"));
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: Destructor
//-----------------------------------------------------------------------------
ToolsAVP_Entity_Android::~ToolsAVP_Entity_Android()
{
	s_xList.RemoveFromList(this);
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: Project_Create
//-----------------------------------------------------------------------------
void ToolsAVP_Entity_Android::Project_Create()
{
	ToolsAVP_Entity_Android::Create( true );
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: Create
//-----------------------------------------------------------------------------
Tools_Object* ToolsAVP_Entity_Android::Create(Asura_Entity* pxEntity)
{
	return new ToolsAVP_Entity_Android(AVP_ServerActor_Android::FindEntity(pxEntity->GetGuid()));
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: Create
//-----------------------------------------------------------------------------
Tools_Object* ToolsAVP_Entity_Android::Create( const bool bFullInit )
{
	// Get the user to pick a blueprint to initialise from.
	Asura_Hash_ID uBlueprintTypeHashID = uAVP_BLUEPRINT_TYPE_ACTORS;
	Asura_Hash_ID uBlueprintHashID     = 0x05f0612d;
	if ( bFullInit )
	{
		BlueprintSelect_Overlay xBPOverlay( "Choose A Blueprint", &uBlueprintHashID, &uBlueprintTypeHashID );
		if ( !xBPOverlay.DoModal() ) { return NULL; }
	}

	const Asura_Guid uGuid = Asura_Entity_System::GetCreatedByToolsGuid();

	// Set up tools data and auto-create a unique name (prompt for new name if there is a clash).
	Tools_Entity_Data* pxToolsData = CreateToolsDataWithDefaultName("Android", "Android", uGuid);
	if ( !pxToolsData ) { return NULL; }

	AVP_ServerActor_Android* pxServerObject = new AVP_ServerActor_Android(uGuid);
	if ( !pxServerObject )
	{
		delete pxToolsData;
		return NULL;
	}

	// Set the tools data before we create the tools object - otherwise it will have already been created!
	pxServerObject->ToolsData = pxToolsData;
	if ( bFullInit )
	{
		pxServerObject->SetPosition( pxToolsData->Position );
		pxServerObject->SetBlueprintTypeHashID( uBlueprintTypeHashID );
		pxServerObject->SetBlueprintHashID( uBlueprintHashID );
		pxServerObject->MakeAI();
		pxServerObject->CreateAndInitialiseBrain();
		pxServerObject->InitFromBlueprint();
	}

	ToolsAVP_Entity_Android* pxToolsObject = new ToolsAVP_Entity_Android( pxServerObject );
	if ( !pxToolsObject )
	{
		delete pxToolsObject;
		delete pxServerObject;
		return NULL;
	}
	Tools_Object_System::SelectObject(pxToolsObject);

	Tools_Timed_Message_System::AddMessage( Tools_Timed_Message_System::COLOUR_DEFAULT, "Created new Android." );
	Tools_SaveAsura::SetEntityModified();

	return pxToolsObject;
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: OnSelection
//-----------------------------------------------------------------------------
void ToolsAVP_Entity_Android::OnSelection()
{
	PARENT::OnSelection();

	s_pxSelectedAndroid = this;
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Human :: OnDeselection
//-----------------------------------------------------------------------------
void ToolsAVP_Entity_Android::OnDeselection()
{
	s_pxSelectedAndroid = NULL;

	PARENT::OnDeselection();
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Android :: OnDeselection
//-----------------------------------------------------------------------------
void ToolsAVP_Entity_Android::AddOverlayControls(Asura_Overlay* pxOverlay, Asura_Vector_2& xOffset)
{
	PARENT::AddOverlayControls(pxOverlay, xOffset);

	Asura_Dialog* pxDialog;

	pxDialog = new Asura_Function_Dialog( "Edit And Focus Androids Squad", xOffset, SelectSquad);
	pxOverlay->AddDialog(pxDialog);
	xOffset.y += Asura_Dialog::DefaultSpacing();
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Android :: SelectSquad
//-----------------------------------------------------------------------------
void ToolsAVP_Entity_Android::SelectSquad(void)
{
	if (s_pxSelectedAndroid)
	{
		ToolsAVP_Entity_Android* pxAndroid = s_pxSelectedAndroid;
		AVP_ServerActor_Android* pxGameAndroid = pxAndroid->m_pxAndroid;

		if (pxGameAndroid)
		{
			if (pxGameAndroid->GetInitialSquadGuid() != ASURA_GUID_UNREGISTERED)
			{
				ToolsAVP_Entity_MarineSquad* pxSquad = (ToolsAVP_Entity_MarineSquad*)ToolsAVP_Entity_MarineSquad::FindEntity(pxGameAndroid->GetInitialSquadGuid());

				if (pxSquad)
				{
					Asura_Vector_3		xNewCameraPos	= pxSquad->Position;
					Asura_Matrix_3x3	xNewCameraOri	= *Asura_Camera::GetOrientation();
					Asura_Vector_3		xFwdVec;

					Asura_Camera::GetForwardVector(xFwdVec);
					xNewCameraPos -= xFwdVec * 8.0f;

					Tools_Movement::TeleportCameraToPosition(&xNewCameraPos, &xNewCameraOri);

					Tools_Object_System::SelectObject(pxSquad);

					return;
				}
			}
		}
	}

	Tools_Timed_Message_System::AddMessage(0xff0000, "Android Has No Squad");
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Marine :: HandlesThisMessage
//-----------------------------------------------------------------------------
bool ToolsAVP_Entity_Android::HandlesThisMessage( int iMessageID )
{
	switch(iMessageID)
	{
		case AVP_MSGID_ADD_AI_OBJECTIVE:
		case AVP_MSGID_PROMOTE_TO_SQUAD_LEADER:
		case AVP_MSGID_ATTACK_SCRIPTED_TARGET:
		case AVP_MSGID_STOP_ATTACKING_SCRIPTED_TARGET:
		case AVP_MSGID_CHANGE_HUMANOID_SQUAD_MOVEMENT_MODE:
		case AVP_MSGID_FORCE_AIM:
		case AVP_MSGID_STOP_FORCE_AIM:
		{
			return true;
		}

		default:
		{
			return ( PARENT::HandlesThisMessage( iMessageID ) );
		}
	}
}

//-----------------------------------------------------------------------------
// ToolsAVP_Entity_Marine :: HandlesThisMessage
//-----------------------------------------------------------------------------
bool ToolsAVP_Entity_Android::HandlesThisEvent( int iEventID ) const
{
	switch(iEventID)
	{
		case AVP_ENTITY_EVENT_MARINE_ALERTED:
		case AVP_ENTITY_EVENT_MARINE_THREAT_SPOTTED:
		{
			return true;
		}

		default:
		{
			return ( PARENT::HandlesThisEvent( iEventID ) );
		}
	}
}

/// End of file. ///

