#include "MW4Headers.hpp"

#include "LBXMover.hpp"
#include "MWEntityManager.hpp"

//#############################################################################
//###############################    LBXMover   ###############################
//#############################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LBXMover::ClassData*
	LBXMover::DefaultData = NULL;

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

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	LBXMover::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LBXMover*
	LBXMover::Make(
		CreateMessage *message,
		ReplicatorID *base_id
	)
{
	Check_Object(message);
	gos_PushCurrentHeap(Heap);
	Check_Object(EntityManager::GetInstance());
	LBXMover *new_entity;
	Entity *entity = EntityManager::GetInstance()->RequestFromArmory(message->dataListID);
	if (entity)
	{
		new_entity = Cast_Object(LBXMover*, entity);
		new_entity->Reuse(message, base_id);
	}
	else
		new_entity = new LBXMover(DefaultData, message, base_id, NULL);
	gos_PopCurrentHeap();
	Check_Object(new_entity);
	return new_entity;
}

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

	m_disipationStart = message->disipationStart;
	m_maxDisipation = message->maxDisipation;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
LBXMover::~LBXMover()
{
	Check_Object(this);
	
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void 
	LBXMover::PostCollision(Stuff::DynamicArrayOf<CollisionData> *collisions)
{
	Check_Object(this);

	//First we need to check the damage based upon our distance and falloff
	Vector3D distance;
	Point3D current_position;
	ElementRenderer::Element *element = GetElement();
	current_position = element->GetNewLocalToParent();
	distance.Subtract(current_position, startPoint);

	Scalar length = distance.GetLength();
	if(length > m_disipationStart)
	{
		Verify(m_disipationStart + SMALL < maxDistance);
		length -= m_disipationStart;
		Scalar ratio = 1.0f - length*(1.0f - m_maxDisipation)/(maxDistance - m_disipationStart);
		damageAmount *= ratio;
	}

	BaseClass::PostCollision(collisions);
}

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