//////////////////////////////////////////////////////////////////////////////
//
// File: AVP_ClientEntity_Pickup.cpp
//
//(AJK - 29.08.2008) Created
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header.
#include "Entity/PhysicalObject/Pickup/AVP_ClientEntity_Pickup.h"

// ASURA
#include "Animation/Asura_AnimationController_Animation.h"
#include "Blueprint/Asura_Blueprint.h"
#include "Blueprint/Asura_Blueprint_System.h"
#include "Network/Asura_Message.h"

// AVP
#include "Blueprint/AVP_Blueprint_HashIDs.h"
#include "Entity/AVP_Entity_Classification.h"
#include "Entity/AVP_Messages.h"
#ifdef ASURA_USE_CONTAINER_SYSTEM
#include "Entity/Container/Asura_ContainerState.h"
#endif //ASURA_USE_CONTAINER_SYSTEM
#include "Entity/PhysicalObject/Pickup/AVP_Pickup_Messages.h"
#include "Entity/PhysicalObject/Pickup/AVP_Pickup.h"

// Statics defintions
Asura_Hashed_List<AVP_ClientEntity_Pickup> AVP_ClientEntity_Pickup::s_xList(2);
Asura_Hashed_List<AVP_ClientEntity_Pickup> AVP_ClientEntity_Pickup::s_xAutoPickList(2);
Asura_Hashed_List<AVP_ClientEntity_Pickup> AVP_ClientEntity_Pickup::s_xPromptedPickList(2);

AVP_ClientEntity_Pickup::AVP_ClientEntity_Pickup()
: m_pxContainerAttachment( NULL )
, m_uPickupBlueprintHash(ASURA_HASH_ID_UNSET)
, m_uDialogueBlueprintHash(ASURA_HASH_ID_UNSET)
, m_pxPickupObject(NULL)
, m_uFlags(0)
{
	Classification = AVP_ENTITYCLASS_PICKUP;  
	s_xList.AddToList(this);
}

AVP_ClientEntity_Pickup::~AVP_ClientEntity_Pickup( void ) 
{
	if(m_pxPickupObject)
	{
		if(m_pxPickupObject->IsAutoPickup())
		{
			s_xAutoPickList.RemoveFromList(this);
		}
		else
		{
			s_xPromptedPickList.RemoveFromList(this);
		}
		delete m_pxPickupObject;
	}
	else
	{
		Asura_Assert(false, "Where is pickup object?");
	}

	DestroyContainer();

	s_xList.RemoveFromList(this);
}

void AVP_ClientEntity_Pickup::Create(const Asura_Message* pxMessage)
{
	if (pxMessage)
	{
		Asura_Assert(pxMessage->GetMsgID()                == ASURA_MSG_CLIENTCREATE, "Invalid message ID.");
		Asura_Assert(pxMessage->GetEntityClassification() == AVP_ENTITYCLASS_PICKUP, "");

		AVP_ClientEntity_Pickup* pxObject = new AVP_ClientEntity_Pickup;
		pxObject->HandleMessage(pxMessage);
	}
}

bool AVP_ClientEntity_Pickup::HandleMessage(const Asura_Message* pxMessage)
{
	if (pxMessage)
	{
		switch(pxMessage->GetMsgID())
		{
			case ASURA_MSG_CLIENTUPDATE:
			{
				const AVP_Message_Pickup_ClientUpdate* const  pxData = static_cast<const AVP_Message_Pickup_ClientUpdate* const>(pxMessage->GetData());
				if (pxData)
				{
					pxData->ExtractPickup(this);
					UpdateContainerState();
					ProcessClientUpdate(static_cast<const AVP_Message_Pickup_ClientUpdate*>(pxMessage->GetData()), pxMessage->GetSentTime());
				}	
				return true;
			}

			case ASURA_MSG_CLIENTCREATE:
			{
				const AVP_Message_Pickup_ClientCreate* const  pxData = static_cast<const AVP_Message_Pickup_ClientCreate* const>(pxMessage->GetData());
				if (pxData)
				{
					pxData->ExtractPickup(this);
					CreatePickupObject();
					UpdateContainerState();
					ProcessClientUpdate(static_cast<const AVP_Message_Pickup_ClientCreate*>(pxMessage->GetData()), pxMessage->GetSentTime());
				}	
				return true;
			}
			case AVP_MSGID_DISABLE_PICKUP:
			{
				SetEnabed(false); 
				return true; 
			}
			case AVP_MSGID_ENABLE_PICKUP:
			{
				SetEnabed(true); 
				return true; 
			}

			case AVP_MSGID_PLAY_REST_ANIM_PICKUP:
			{
				PlayRestAnim( );
				return true; 
			}
		}
	}
	return PARENT::HandleMessage(pxMessage);
}

void AVP_ClientEntity_Pickup::CreatePickupObject()
{
// The pickup object is changed only in tools;
#ifdef ASURA_TOOLS
	if(m_pxPickupObject)
	{
		if(m_pxPickupObject->IsAutoPickup())
		{
			s_xAutoPickList.RemoveFromList(this);
		}
		else
		{
			s_xPromptedPickList.RemoveFromList(this);
		}
		delete m_pxPickupObject;
	}
#endif //ASURA_TOOLS

    // Normally; the m_pxPickupObject must be NULL here, but
	// because sometimes, the CREATE MESSAGE is received more than one time per client when in multiplayer; this results
	// in memory leaks. So i added a check here to find if the pickup object is already there
	if(!m_pxPickupObject)
	{
		m_pxPickupObject = AVP_Pickup::Create(m_uPickupBlueprintHash);

		if(m_pxPickupObject)
		{
			m_pxPickupObject->InitFromBlueprint();

			if(m_pxPickupObject->IsAutoPickup())
			{
				s_xAutoPickList.AddToList(this);
			}
			else
			{
				s_xPromptedPickList.AddToList(this);
			}
		}
		else
		{
			Asura_Assert(false, "Could not create pickup object!");
		}
	}
}

void AVP_ClientEntity_Pickup::UpdateContainerState( )
{
	//if ( ! m_pxContainerAttachment )
	//{
	//	CreateContainer();
	//}

	//if( m_pxContainerAttachment )
	//{
	//	if( !IsInvisible() && ( m_pxContainerAttachment->GetInputState() == Asura_Container_InputState::Off() ) )
	//	{
	//		m_pxContainerAttachment->ChangeState( Asura_Container_InputState::On() );
	//	}

	//	if( IsInvisible() && ( m_pxContainerAttachment->GetInputState() == Asura_Container_InputState::On() ) )
	//	{
	//		m_pxContainerAttachment->ChangeState( Asura_Container_InputState::Off() );
	//	}
	//}
}

void AVP_ClientEntity_Pickup::CreateContainer()
{
	//Asura_Value xValue;
	//Asura_Blueprint* pxBlueprint = Asura_Blueprint_System::GetBlueprintByHashID( uAVP_BLUEPRINT_TYPE_PICKUPS, m_uPickupBlueprintHash);

	//// Get Container
	//if(pxBlueprint->GetParameterValueByHashID(uAVP_BLUEPRINT_PARAM_PICKUP_CONTAINER, xValue))
	//{
	//	Asura_Hash_ID uContainerHash = xValue.GetHashIDValue();

	//	if ( uContainerHash != ASURA_HASH_ID_UNSET )
	//	{
	//		//m_pxContainerAttachment = new Asura_AnimationAttachment_ClientContainerInstance(uContainerHash, Asura_Container_InputState::Off());
	//		//m_pxContainerAttachment->LinkAttachment( NULL, 0x06233516 /* "light" */, false );	
	//	}
	//	else
	//	{
	//		Asura_Assertf(false, ("Failed to find container to use for the pickup (GUID %d).", GetGuid()));
	//	}
	//}
}

void AVP_ClientEntity_Pickup::DestroyContainer()
{
	//if ( m_pxContainerAttachment )
	//{
	//	delete m_pxContainerAttachment;
	//	m_pxContainerAttachment = NULL;
	//}
}

void AVP_ClientEntity_Pickup::PlayRestAnim( )
{
	if ( m_pxPickupObject && m_pxPickupObject->GetRestAnim() != ASURA_HASH_ID_UNSET )
	{
		// Play animation
		Asura_Animation* pxAnimation = GetShapeInstance().GetAnimation();
		if ( pxAnimation )
		{
			Asura_AnimationController_Animation* pxAACA = pxAnimation->CreateControllerAnimation( AAC_FLAG_ACTIVE | AAC_FLAG_ALLOW_DESTROY_FROM_MESSAGE, 0, m_pxPickupObject->GetRestAnim(), NULL );
			if ( pxAACA )
			{
				pxAACA->Play();
			}
		}
	}
}