//////////////////////////////////////////////////////////////////////////////
//
// AVP_Sense_Hearing_Predator.cpp
//
// Created by NJD - 06 December 2006
//
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

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

// This files header
#include "Knowledge/SenseTypes/AVP_Sense_Hearing_Predator.h"

// Asura
#include "Blueprint/Asura_Blueprint.h"
#include "Blueprint/Asura_Blueprint_System.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"

// Axon
#include "Core/BrainTypes/Axon_Project_Brain.h"
#include "Knowledge/Axon_Knowledge.h"

// AVP
#include "Entity/PhysicalObject/Actor/Vertebrates/Predator/AVP_ServerActor_Predator.h"
#include "Entity/AVP_Entity_Classification.h"
#include "Core/BrainTypes/AVP_Brain_Actor.h"
#include "Knowledge/AVP_Knowledge_System_predator.h"
#include "Tactical/AVP_Tactical_System.h"

//////////////////////////////////////////////////////////////////////////////
//
// AVP_Sense_Hearing_Predator
//
//////////////////////////////////////////////////////////////////////////////

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: Constructor
//---------------------------------------------------------------------------
AVP_Sense_Hearing_Predator::AVP_Sense_Hearing_Predator( AVP_Knowledge_System_Predator* pxAVPKnowledgeSystem ) 
: PARENT( pxAVPKnowledgeSystem )
, m_pxActor( AVP_ServerEntity_Actor::FindEntity( GetAVPKnowledgeSystem()->GetActorBrain()->GetOwnerGuid() ) )
{
    m_fSensitivity = 10.0f;
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: Destructor
//---------------------------------------------------------------------------
AVP_Sense_Hearing_Predator::~AVP_Sense_Hearing_Predator() 
{
	DestroyAllKnowledge();
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: InitialiseFromBlueprint
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::InitialiseFromBlueprint( const Asura_Blueprint& xBlueprint )
{
	PARENT::InitialiseFromBlueprint( xBlueprint );

	// We also need to initialise from our AI settings blueprint currently.
	InitFromSettingsBlueprint();
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: ReadFromChunkStream
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::ReadFromChunkStream( Asura_Chunk_Stream& xStream ) 
{
    int iVersion;
    xStream >> iVersion;

    PARENT::ReadFromChunkStream( xStream );

    Asura_Assertf(iVersion == CURRENT_CHUNK_VERSION, ("AVP_Sense_Hearing_Predator::ReadFromChunkStream - unhandled chunk version (%d)", iVersion));
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: WriteToChunkStream
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::WriteToChunkStream(Asura_Chunk_Stream& xStream) const
{
    xStream << CURRENT_CHUNK_VERSION;

    PARENT::WriteToChunkStream(xStream);
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: Update
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::Update(const float fTimeslice)
{
	m_xPosition    = m_pxActor->GetPosition();
	m_xDirection.x = m_pxActor->GetOrientation().e13;
	m_xDirection.y = m_pxActor->GetOrientation().e23;
	m_xDirection.z = m_pxActor->GetOrientation().e33;

	PARENT::Update(fTimeslice);

	// Go through and only keep the most important sound from each guid
	Asura_List_It<Axon_Knowledge> xHearingIter(&m_xSoundList);
	while (!xHearingIter.Done())
	{
		Axon_Knowledge* pxKnowledge = xHearingIter.GetCurrent();
		const AVP_ServerEntity_Actor* pxHeardActor = AVP_ServerEntity_Actor::FindEntity(pxKnowledge->GetGuid());

		if (!pxHeardActor)
		{
			xHearingIter.DeleteCurrent();
			m_pxKnowledgeSystem->DestroyKnowledge(pxKnowledge);
			continue;
		}

		if (pxHeardActor->IsDead() || !pxHeardActor->IsEntityActive() || AVP_Tactical_System::GetAllegiance(*m_pxActor, *pxHeardActor) == AVP_ALLEGIANCE_FRIEND)
		{
			xHearingIter.DeleteCurrent();
			m_pxKnowledgeSystem->DestroyKnowledge(pxKnowledge);
			continue;
		}		

		GetAVPKnowledgeSystem()->ResetAlertTimer();

		xHearingIter.Next();
	}
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: AddToHearingList
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::AddToHearingList(Axon_Knowledge* pxNewKnowledge)
{
	if (pxNewKnowledge)
	{
		m_xSoundList.AddToList(pxNewKnowledge);
	}
}

//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: AddToVisionList
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::DeleteFromHearingList(const Axon_Knowledge* pxKnowledgeToRemove)
{
	Asura_List_It<Axon_Knowledge> xHearingIter(&m_xSoundList);
	while (!xHearingIter.Done())
	{
		Axon_Knowledge* pxKnowledge = xHearingIter.GetCurrent();
		
		if (pxKnowledge->GetGuid() == pxKnowledgeToRemove->GetGuid())
		{
			m_xSoundList.RemoveFromList(pxKnowledge);
			m_pxKnowledgeSystem->DestroyKnowledge(pxKnowledge);
			break;
		}

		xHearingIter.Next();
	}
}


//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: GetAVPKnowledgeSystem
//---------------------------------------------------------------------------
AVP_Knowledge_System_Predator* AVP_Sense_Hearing_Predator::GetAVPKnowledgeSystem()
{
    return static_cast<AVP_Knowledge_System_Predator*>(m_pxKnowledgeSystem);
}


//---------------------------------------------------------------------------
// AVP_Sense_Hearing_Predator :: RefreshBlueprintData
//---------------------------------------------------------------------------
void AVP_Sense_Hearing_Predator::InitFromSettingsBlueprint()
{
	AVP_ServerEntity_Actor*	pxOurActor				= AVP_ServerEntity_Actor::FindEntity(GetAVPKnowledgeSystem()->GetActorBrain()->GetOwnerGuid());
	Asura_Hash_ID			uBlueprintTypeHashID	= 0x7AD7BD1B; // Asura_GetHashID("AI Settings")
	Asura_Hash_ID			uBlueprintHashID		= 0xfbdd4b67; // Asura_GetHashID("PredatorKnowledge")

	Asura_Assert(pxOurActor->GetClassification() == AVP_ENTITYCLASS_PREDATOR, "Actor not a predator");

	if (pxOurActor->GetClassification() == AVP_ENTITYCLASS_PREDATOR)
	{
		Asura_Blueprint* pxBlueprint = Asura_Blueprint_System::GetBlueprintByHashID(uBlueprintTypeHashID, uBlueprintHashID);
		if (pxBlueprint)
		{
			Asura_Value xValue;

			if (pxBlueprint->GetParameterValueByHashID(0x1daea193, xValue))	// "HearingKnowledgeLifeTime"
				m_fKowledgeLifeTime = (xValue.GetFloatValue());
		}

	}
	else
	{
		m_fKowledgeLifeTime = 20.0f;
	}

	m_fSensitivity = 10.0f;

}
