#include "MW4Headers.hpp"

#include "DeathEntity.hpp"
#include "MWApplication.hpp"

#include <Adept\Application.hpp>
#include <Compost\CompostHeaders.hpp>

#include <Adept\Tool.hpp>

//#############################################################################
//###############################    DeathEntity    ###########################
//#############################################################################

DeathEntity::ClassData*
	DeathEntity::DefaultData = NULL;

SortedChainOf<DeathEntity*, Time>*
	DeathEntity::DeathEntities = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DeathEntity::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			DeathEntityClassID,
			"MechWarrior4::DeathEntity",
			Entity::DefaultData,
			0, NULL,
			(Entity::Factory)Make,
			(Entity::CreateMessage::Factory)CreateMessage::ConstructCreateMessage,
			ExecutionStateEngine::DefaultData,
			(Entity::GameModel::Factory)GameModel::ConstructGameModel,
			(Entity::GameModel::Factory)GameModel::ConstructOBBStream,
			(Entity::GameModel::ReadAndVerifier)GameModel::ReadAndVerify,
			(Entity::GameModel::ModelWrite)GameModel::WriteToText,
			(Entity::GameModel::ModelSave)GameModel::SaveGameModel
		);
	Register_Object(DefaultData);

	DeathEntities = 
			new SortedChainOf<DeathEntity *, Time>(NULL, false);
	Check_Pointer(DeathEntities);
	Register_Object(DeathEntities);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DeathEntity::TerminateClass()
{
	Check_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;

	DeathEntities->DeletePlugs();

	Check_Object(DeathEntities);
	delete DeathEntities;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DeathEntity*
	DeathEntity::Make(
		CreateMessage *message,
		ReplicatorID *base_id
	)
{
	Check_Object(message);
	gos_PushCurrentHeap(Heap);
	DeathEntity *new_entity = 
		new DeathEntity(DefaultData, message, base_id, NULL);
	gos_PopCurrentHeap();
	Check_Object(new_entity);
	return new_entity;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DeathEntity::DeathEntity(
	ClassData *class_data,
	CreateMessage *message,
	ReplicatorID *base_id,
	ElementRenderer::Element *element
):
	Entity(class_data, message, base_id, element)
{
	Check_Pointer(this);
	Check_Object(message);

	SortedChainIteratorOf<DeathEntity *, Time> iterator(DeathEntities);
	if(iterator.GetSize() > 5)
	{
		iterator.First();
		DeathEntity *entity = iterator.GetCurrent();
		entity->SentenceToDeathRow();
	}
	DeathEntities->AddValue(this, gos_GetElapsedTime());
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DeathEntity::~DeathEntity()
{
	Check_Pointer(this);
/* Dave said its obsolete, so be it !
	if(Compost::TerrainTextureLogistic::Instance)
	{
		const GameModel *model = GetGameModel();
		Check_Object(model);
		if(model->m_craterID >= 0)
		{
			Point3D local_to_world;
			local_to_world = GetLocalToWorld();
			Compost::TerrainTextureLogistic::Instance->AddFeature(
				model->m_craterID, local_to_world.x, local_to_world.z);
		}
	}
*/

	Check_Object(Application::GetInstance());
	if(MWApplication::GetInstance()->replicatedHermits.IsPlugMember(this))
	{
		MWApplication::GetInstance()->replicatedHermits.Remove(this);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	DeathEntity::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}