///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Predator_InteractionHandler.cpp
// Author : Ali Jakamy
// Date   : 23-10-2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header...
#include "Actor/Vertebrates/Predator/AVP_Predator_InteractionHandler.h"

// Asura
#include "Interface/Asura_CommandConsole.h"

// AVP
#include "Actor/AVP_Actor_InputHandler.h"
#include "Entity/PhysicalObject/Actor/AVP_Actor_Messages.h"
#include "Entity/PhysicalObject/Interact/AVP_ClientEntity_InteractObject.h"
#include "Moves/AVP_Move_Interaction.h"
#include "Moves/Vertebrates/Predator/AVP_Predator_MovesInteraction.h"

bool	AVP_Predator_InteractionHandler::s_bPredatorEngagedInPuzzle = false;

AVP_Predator_InteractionHandler::AVP_Predator_InteractionHandler(AVP_ClientEntity_Actor& xOwner)
: PARENT(xOwner)
, m_bDisengage(false)
, m_uPuzzleToDisengageGuid(ASURA_GUID_UNREGISTERED)
{

}

#if defined(ASURA_SUPPORT_COMMAND_CONSOLE)
void AVP_Predator_InteractionHandler::CreateConsoleVars()
{
	Asura_CommandConsole::AddVar(L"AVP.PredatorPlayer.UsingPuzzle", &s_bPredatorEngagedInPuzzle, Asura_CommandConsole::REMOVE_AT_SHUTDOWN );
}
#endif	//defined(ASURA_SUPPORT_COMMAND_CONSOLE)

bool AVP_Predator_InteractionHandler::HandleInteraction(AVP_INTERACTION_TYPES eType, int iKeyType, float fKeyValue) const
{
	const Asura_Guid uGuidForInteraction = GetGuidForInteraction( eType );
	if ( uGuidForInteraction != ASURA_GUID_UNREGISTERED )
	{
		AVP_ClientEntity_InteractObject* pxInteractObject = AVP_ClientEntity_InteractObject::FindEntity( uGuidForInteraction );
		if ( pxInteractObject )
		{
			// Is it a predator lock?
			if (pxInteractObject->GetInteractionObjectType() == AVP_ClientEntity_InteractObject::INTERACTION_TYPE_PREDATOR_LOCK)
			{
				if (iKeyType == AVP_Actor_InputHandler::STRAFE_LEFT_RIGHT)
				{
					if(fKeyValue < 0.0f) // Left
					{
						return SendInteractMessage(eType, AVP_Predator_Move_Interaction_TurnLeft::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_LEFT);
					}
					else
					{
						return SendInteractMessage(eType, AVP_Predator_Move_Interaction_TurnRight::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_RIGHT);
					}
				}
				else if (iKeyType == AVP_Actor_InputHandler::INTERACT)
				{
					if(IsInIdleInteraction())
					{
						return SendInteractMessage(eType, AVP_Predator_Move_Interaction_UnPlugKey::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_INTIATED);

					}
					else
					{					
						return SendInteractMessage(eType, AVP_Predator_Move_Interaction_PlugKey::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_INTIATED);
					}
				}
			}
			else if (pxInteractObject->GetInteractionObjectType() == AVP_ClientEntity_InteractObject::INTERACTION_TYPE_BATTERYRECEPTACLE)
			{
				if (iKeyType == AVP_Actor_InputHandler::INTERACT  && !IsInteracting())
				{
					return SendInteractMessage(eType, AVP_Predator_Move_Interaction_UseBattery::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_INTIATED);
				}
			}
			else if (pxInteractObject->GetInteractionObjectType() == AVP_ClientEntity_InteractObject::INTERACTION_TYPE_RETINALSCANNER)
			{
				if (iKeyType == AVP_Actor_InputHandler::INTERACT  && !IsInteracting())
				{
					return SendInteractMessage(eType, AVP_Predator_Move_Interaction_UseHead::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_INTIATED);
				}
			}
			else
			{
				if(!IsInteracting())
				{
					// Fall back to old interaction handle to not break up things already there
					return PARENT::HandleInteraction(eType, iKeyType, fKeyValue);
				}
			}
		}
	}
	return false;
}

void AVP_Predator_InteractionHandler::Update()
{
	UpdateDisengage();

	PARENT::Update();

	s_bPredatorEngagedInPuzzle = IsEngagedWithPuzzle();

	// Handle Disengage
	HandleDisengage();
}

void AVP_Predator_InteractionHandler::HandleDisengage()
{
	if(m_bDisengage)
	{
		if(m_uPuzzleToDisengageGuid != ASURA_GUID_UNREGISTERED )
		{
			AVP_ClientEntity_InteractObject* pxInteractObject = AVP_ClientEntity_InteractObject::FindEntity( m_uPuzzleToDisengageGuid );
			if ( pxInteractObject)
			{
				// Is it a predator lock?
				if (pxInteractObject->GetInteractionObjectType() == AVP_ClientEntity_InteractObject::INTERACTION_TYPE_PREDATOR_LOCK)
				{
					if(IsInIdleInteraction())
					{
						SendInteractMessage(AVP_INTERACTION_TYPE_DEFAULT, AVP_Predator_Move_Interaction_UnPlugKey::GetStaticHash(), pxInteractObject, AVP_Message_Actor_RequestInteraction::INTERACTION_NONE);
						m_bDisengage			 = false;
						m_uPuzzleToDisengageGuid = ASURA_HASH_ID_UNSET;
					}
				}
			}
		}
	}
}

void AVP_Predator_InteractionHandler::UpdateDisengage()
{
	const Asura_Guid uGuidForInteraction = GetGuidForInteraction( AVP_INTERACTION_TYPE_DEFAULT );
	if(uGuidForInteraction != ASURA_GUID_UNREGISTERED )
	{
		AVP_ClientEntity_InteractObject* pxInteractObject = AVP_ClientEntity_InteractObject::FindEntity( uGuidForInteraction );
		if ( pxInteractObject && !pxInteractObject->IsEnabled())
		{
			// Is it a predator lock?
			if (pxInteractObject->GetInteractionObjectType() == AVP_ClientEntity_InteractObject::INTERACTION_TYPE_PREDATOR_LOCK)
			{
				m_bDisengage			 = true;
				m_uPuzzleToDisengageGuid = uGuidForInteraction;
			}
		}
	}
}

bool AVP_Predator_InteractionHandler::IsEngagedWithPuzzle() const
{
	const Asura_Guid uGuidForInteraction = GetGuidForInteraction( AVP_INTERACTION_TYPE_DEFAULT );
	if(uGuidForInteraction != ASURA_GUID_UNREGISTERED )
	{
		AVP_ClientEntity_InteractObject* pxInteractObject = AVP_ClientEntity_InteractObject::FindEntity( uGuidForInteraction );
		if ( pxInteractObject )
		{
			// Is it a predator lock?
			if (pxInteractObject->GetInteractionObjectType() == AVP_ClientEntity_InteractObject::INTERACTION_TYPE_PREDATOR_LOCK)
			{
				//See if he is playing any of predator lock moves
				const Asura_Move* pxMove = NULL; 
				if ( m_xOwner.GetMovementSystem() && (( pxMove = m_xOwner.GetMovementSystem()->GetCurrentMove()) != NULL) )
				{
					if (   pxMove->GetHash() == AVP_Predator_Move_Interaction_TurnLeft::GetStaticHash() 
						|| pxMove->GetHash() == AVP_Predator_Move_Interaction_TurnRight::GetStaticHash()
						|| pxMove->GetHash() == AVP_Predator_Move_Interaction_UnPlugKey::GetStaticHash()
						|| pxMove->GetHash() == AVP_Predator_Move_Interaction_PlugKey::GetStaticHash()
						|| pxMove->GetHash() == AVP_Predator_Move_Interaction_StandStill::GetStaticHash() )
					{
						return true;
					}
				}
			}
		}
	}
	return false;
}

bool AVP_Predator_InteractionHandler::IsInteracting() const
{
	const Asura_Move* pxMove = NULL; 
	if ( m_xOwner.GetMovementSystem() && (( pxMove = m_xOwner.GetMovementSystem()->GetCurrentMove()) != NULL) )
	{
		//First see if he is doing a weapon away interaction move
		return GetIsPredatorInteractionMove(pxMove->GetHash());
	}

	// Engaged in puzzle ?
	return false;
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ClientActor_Predator::IsInIdleInteraction
// Author       : AJK
// Date         : 27-Nov-2008
////////////////////////////////////////////////////////////////////////////////

bool AVP_Predator_InteractionHandler::IsInIdleInteraction() const
{
	const Asura_Move* pxMove = m_xOwner.GetMovementSystem() ? m_xOwner.GetMovementSystem()->GetCurrentMove() : NULL; 
	if (pxMove)
	{
		if ( pxMove->GetHash() == AVP_Predator_Move_Interaction_StandStill::GetStaticHash() )
		{
			AVP_Predator_Move_Interaction_StandStill* pxStillMove = static_cast< AVP_Predator_Move_Interaction_StandStill*>(m_xOwner.GetMovementSystem()->GetMove(AVP_Predator_Move_Interaction_StandStill::GetStaticHash()));
			pxStillMove->AdvanceTweenHack();
			if(pxStillMove->GetTweenHack() > DEFAULT_TWEEN_TIME)
			{
				return true;
			}
		}
	}
	return false;
}


bool AVP_Predator_InteractionHandler::GetIsPredatorInteractionMove(const Asura_Hash_ID uMoveHash)
{
	if ((uMoveHash == AVP_Move_Interaction_BeginWeaponAway::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_TurnLeft::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_TurnRight::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_UnPlugKey::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_PlugKey::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_StandStill::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_UseBattery::GetStaticHash())
		|| (uMoveHash == AVP_Predator_Move_Interaction_UseHead::GetStaticHash())
		|| (uMoveHash == AVP_Move_Interaction::GetStaticHash()))
	{
		return true;
	}
	else
	{
		return false;
	}
}
