#include "MW4Headers.hpp"

#include "AMS.hpp"
#include "SubsystemClassData.hpp"
#include "vehicleinterface.hpp"
#include "mechlabheaders.h"

//#############################################################################
//###############################    AMS    ###################################
//#############################################################################

AMS::ClassData*
	AMS::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	AMS::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			AMSClassID,
			"MechWarrior4::AMS",
			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,
			(Subsystem::StreamCreate) CreateStream
		);
	Register_Object(DefaultData);

	DIRECT_GAME_MODEL_ATTRIBUTE(
		AMS__GameModel,
		AMSEffectResource,
		amsEffectResource,
		ResourceID
	);
}

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AMS::AMS(
	ClassData *class_data,
	CreateMessage *message,
	ReplicatorID *base_id,
	ElementRenderer::Element *element
):
	Subsystem(class_data, message, base_id, element)
{
	Check_Object(message);

	ammoCount = message->ammoCount;

	maxAmmoCount = ammoCount;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Replicator::CreateMessage*
	AMS::SaveMakeMessage(MemoryStream *stream, ResourceFile *res_file)
{
	Check_Object(this);
	Check_Object(stream);

	stream->AllocateBytes(sizeof(CreateMessage));
	Subsystem::SaveMakeMessage(stream, res_file);
	CreateMessage *message =
		Cast_Pointer(CreateMessage*, stream->GetPointer());
	message->messageLength = sizeof(*message);

	message->ammoCount = ammoCount;
	return message;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
AMS::~AMS()
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	AMS::DestroySubsystem()
{
	Check_Object(this);
	
#if 0
	MWObject *mw_object = GetParentVehicle();
	Check_Object(mw_object);
	Verify(mw_object->IsDerivedFrom(Vehicle::DefaultData));
	Vehicle *vehicle = Cast_Object(Vehicle *, mw_object);
	vehicle->DestroyAMS();
#endif
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	AMS::SubtractAmmo(int count)
{
	Check_Object(this);


	if (!Network::GetInstance()->AmIServer())
		return;


	if(ammoCount == -1)
		return;

	if(GetParentVehicle()->vehicleInterface)
	{
		const GameModel *model = GetGameModel();
		switch (model->itemID)
		{
		case Sub_AMS:
			GetParentVehicle()->vehicleInterface->ReactToEvent (VehicleInterface::AMS_ENGAGED);
			break;
		case Sub_LAMS:
			GetParentVehicle()->vehicleInterface->ReactToEvent (VehicleInterface::LAMS_ENGAGED);
			break;
#if defined(LAB_ONLY)
		default:
			PAUSE (("unknown type of ams"));
			break;
#endif
		}
	}

	ammoCount -= count;
	Min_Clamp(ammoCount, 0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	AMS::CreateStream(ResourceID data_list, MemoryStream *stream)
{
	Check_Pointer(stream);

	stream->AllocateBytes(sizeof(AMS__CreateMessage));
	Subsystem::CreateStream(data_list, stream);

	AMS__CreateMessage *create_message = Cast_Pointer(
		AMS__CreateMessage *, stream->GetPointer());

	create_message->ammoCount = -1;
}

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

