
#include "MW4Headers.hpp"

#include "Group.hpp"
#include <Adept\NameTable.hpp>
#include <Adept\Entity.hpp>



using namespace MechWarrior4;

Adept::Entity* Group::IDToEntity(Adept::ObjectID id) const
{
	Verify(Adept::NameTable::GetInstance() != 0);
	Adept::Entity* rv = Adept::NameTable::GetInstance()->FindData(id);

	if ((rv != 0) &&
		(rv->IsDestroyed() == false))
	{
		return (rv);
	}

	return (0);
}

Group::Group(identifier id)
	: m_id(id)
	, m_SquadAI(0)
{
	Verify(id < 0x00FFFFFF);
}

Group::identifier Group::GetID() const
{
	return (m_id);
}

void Group::UpdateAI(CombatAI& combat_ai)
{
	if (m_SquadAI.GetPointer() != 0)
	{
		m_SquadAI->Update(*this,combat_ai);
	}
}

void Group::SetSquadAI(Stuff::Auto_Ptr<MW4AI::Squad::AI>& squad_ai)
{
	m_SquadAI = squad_ai;

	if (m_SquadAI.GetPointer() != 0)
	{
		std::vector<MWObject*> members;
		GetMembers(members);

		{for (std::vector<MWObject*>::const_iterator i = members.begin();
			  i != members.end();
			  ++i)
		{
			m_SquadAI->NotifyMemberAdded(*this,**i);
		}}
	}
}

void Group::NotifyShot(Adept::ObjectID id)
{
	if (m_SquadAI.GetPointer() != 0)
	{
		m_SquadAI->NotifyShot(*this,id);
	}
}

void Group::NotifyShotFired(const Stuff::Line3D& line,
										  MWObject& at_who,
										  MWObject& shooter)
{
	if (m_SquadAI.GetPointer() != 0)
	{
		m_SquadAI->NotifyShotFired(*this,line,at_who,shooter);
	}
}

bool Group::HasAI() const
{
	return (m_SquadAI.GetPointer() != 0);
}

bool Group::IgnoresFriendlyFire() const
{
	if (m_SquadAI.GetPointer() != 0)
	{
		return (m_SquadAI->IgnoresFriendlyFire());
	}

	return (false);
}

const MW4AI::Squad::AI* Group::GetAI() const
{
	return (m_SquadAI.GetPointer());
}

MW4AI::Squad::AI* Group::GetAI()
{
	return (m_SquadAI.GetPointer());
}

MWObject* FindMWObject(Adept::ObjectID id)
{
	Adept::Entity* entity = Adept::NameTable::GetInstance()->FindData(id);
	if ((entity != 0) &&
		(entity->IsDestroyed() == false) &&
		(entity->IsDerivedFrom(MWObject::DefaultData) == true))
	{
		return (Cast_Object(MWObject*,entity));
	}

	return (0);
}

void Group::GetMembers(std::vector<MWObject*>& members) const
{
	{for (element_list::const_iterator i = GetElements().begin();
		  i != GetElements().end();
		  ++i)
	{
		if ((*i) >= 0)
		{
			if (FindMWObject(*i) != 0)
			{
				members.push_back(FindMWObject(*i));
			}
		}
	}}
}

const std::vector<Adept::ObjectID>& Group::GetElements() const
{
	return (m_Elements);
}

void Group::AddObject(Adept::ObjectID object)
{
	m_Elements.push_back(object);

	if ((m_SquadAI.GetPointer() != 0) &&
		(FindMWObject(object) != 0))
	{	
		m_SquadAI->NotifyMemberAdded(*this,*(FindMWObject(object)));
	}
}

void Group::RemoveObject(Adept::ObjectID object)
{
	element_list::iterator found = std::find(m_Elements.begin(),m_Elements.end(),object);
	Verify(found != m_Elements.end());

	if ((m_SquadAI.GetPointer() != 0) &&
		(FindMWObject(object) != 0))
	{	
		m_SquadAI->NotifyMemberRemoved(*this,*(FindMWObject(object)));
	}

	m_Elements.erase(found);
}

void Group::NotifyMechDestroyed(const Adept::ReplicatorID& inflicting_id, const Adept::ReplicatorID& victim_id)
{
	if (m_SquadAI.GetPointer() != 0)
	{
		m_SquadAI->NotifyMechDestroyed(*this,inflicting_id,victim_id);
	}
}
