//===========================================================================//
// File:	Subsystem_Tool.cpp										
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 09/09/98  JSE  Inital base class based off of Shadowrun/Adept      
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "MW4Headers.hpp"

#include "Subsystem.hpp"
#include "MWTool.hpp"
#include "MWDamageObject.hpp"
#include "gameinfo.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Subsystem__CreateMessage::ConstructCreateMessage(Script *script)
{
	Check_Object(script);

	//
	//--------------
	// Set up stream
	//--------------
	//
	MemoryStream *message_stream = script->messageStream;
	Check_Object(message_stream);
	message_stream->AllocateBytes(sizeof(Subsystem__CreateMessage));
	Entity__CreateMessage::ConstructCreateMessage(script);
	Subsystem__CreateMessage *message =
		Cast_Pointer(
			Subsystem__CreateMessage*,
			message_stream->GetPointer()
		);
	message->messageLength = sizeof(*message);

	//
	//---------------------------
	// Point at the notation file
	//---------------------------
	//
	Page *page = script->instancePage;
	Check_Object(page);
	Check_Object(Tool::Instance);

	message->criticalHitsTaken = 0;
	page->GetEntry("CriticalHitsTaken", &message->criticalHitsTaken);

	message->subsystemIndex = 0;
	page->GetEntry("SubsystemIndex", &message->subsystemIndex);

	int location_id = 0;
	const char *location_name;
	page->GetEntry("InternalLocation", &location_name, true);
	location_id = InternalDamageObject::InternalZoneTextToAscii(location_name);
	Verify((unsigned)location_id < 256);
	message->locationID = static_cast<BYTE>(location_id);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Subsystem__GameModel::ConstructGameModel(Script *script)
{
	Check_Object(script);

	//
	//--------------
	// Set up stream
	//--------------
	//
	MemoryStream *model_stream = script->modelStream;
	Check_Object(model_stream);
	model_stream->AllocateBytes(sizeof(Subsystem__GameModel));
	Entity__GameModel::ConstructGameModel(script);
	Subsystem__GameModel *model = 
		Cast_Pointer(Subsystem__GameModel *, model_stream->GetPointer());

	NotationFile *model_file = script->modelFile;
	Check_Object(model_file);
	Page *page = model_file->GetPage("GameData");
	Check_Object(page);

	const char *slot_string;
	model->slotType = -1;
	if(page->GetEntry("SlotType", &slot_string))
		model->slotType = MWInternalDamageObject::SlotTypeTextToAscii(slot_string);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Subsystem::SaveInstanceText(Page *page)
{
	Check_Object(this);
	Check_Object(page);

	Entity::SaveInstanceText(page);

	//
	//-------------------------
	// Save the Execution State
	//-------------------------
	//
	int execution_state = executionState->GetState();
	MString execution_state_text;
	switch(execution_state)
	{
	case ExecutionStateEngine::DamagedState:
		{
			execution_state_text = "DamagedState";
			break;
		}
	case ExecutionStateEngine::DestroyedState:
		{
			execution_state_text = "DestroyedState";
			break;
		}
	}
	page->SetEntry("ExecutionState", execution_state_text);

	page->SetEntry("CriticalHitsTaken", critHitsTaken);
	page->SetEntry("SubsystemIndex", subsystemIndex);
	const char *location = InternalDamageObject::InternalZoneAsciiToText((int)internalLocation);
	page->SetEntry("InternalLocation", location);

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	Subsystem__GameModel::ReadAndVerify(
		Subsystem__GameModel *model,
		ModelAttributeEntry *attribute_entry, 
		const char *data,
		char **error,
		int error_buffer
	)
{
	Check_Object(attribute_entry);
	
	bool result = false;
	bool valid_data = (*data != '\0');

	//
	//----------------------------------------
	//Read in the values from the data entered
	//----------------------------------------
	//
#ifdef LAB_ONLY
//	strcpy(MWGameInfo::g_ResourceFile, (char *)(script->instancePage->GetNotationFile()->GetFileName()));
	strcpy(MWGameInfo::g_ResourceEntry, (char *)((*attribute_entry).attributeName));
#endif

	result = 
		Entity__GameModel::ReadAndVerify(
			model, 
			attribute_entry, 
			data,
			error,
			error_buffer
		);
	//
	//---------------------------
	//Verify all the model values
	//---------------------------
	//
	switch(attribute_entry->attributeID)
	{
	case TotalSlotsTakenAttributeID:
		{
			if(!valid_data)
			{
				int value;
				value = 1;
				attribute_entry->SetValue(model, &value);
				return true;
			}
			if(model->totalSlotsTaken < 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]TotalSlotsTaken=%f} must be >= 0!",
					model->totalSlotsTaken
				);
				result = false;
			}
				
			break;
		}
	case TonageAttributeID:
		{
			if(!valid_data)
			{
				Scalar value;
				value = 0.0f;
				attribute_entry->SetValue(model, &value);
				return true;
			}
			if(model->tonage < 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]Tonage=%f} must be >= 0!",
					model->tonage
				);
				result = false;
			}
				
			break;
		}
	case BattleValueAttributeID:
		{
			if(!valid_data)
			{
				int value;
				value = 0;
				attribute_entry->SetValue(model, &value);
				return true;
			}
			if(model->battleValue < 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]BattleValue=%f} must be >= 0!",
					model->battleValue
				);
				result = false;
			}
				
			break;
		}
	case ItemIDAttributeID:
		{
			if(!valid_data)
			{
				int value;
				value = -1;
				attribute_entry->SetValue(model, &value);
				return true;
			}	
			break;
		}
	}
	return result;
}