//===========================================================================//
// File:	Armor_Tool.cpp														 //
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 12/19/01  MSL  Added StandardArmor                                        //
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive										 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//

#include "MW4Headers.hpp"

#include "Armor.hpp"
#include "MWTool.hpp"

#include <Adept\DamageObject.hpp>
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Armor__CreateMessage::ConstructCreateMessage(Script *script)
{
	Check_Object(script);

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

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

	const char *type_string;
	page->GetEntry("ArmorType", &type_string, true);
	message->m_armorType = Armor::ArmorTypeTextToAscii(type_string);

	Resource model_resource;
	Entity::GetGameModelResourceFromDataListID(&model_resource, message->dataListID);

	Armor::GameModel *model = Cast_Pointer(Armor::GameModel *, model_resource.GetPointer());

	int multiplier = 1;
	switch(message->m_armorType)
	{
// MSL 5.00 Armor
	case Armor::StandardArmor: 
		multiplier = model->m_pointsPerStandardTon;
		break;
	case Armor::FerroFiberusArmor: 
		multiplier = model->m_pointsPerFerroTon;
		break;
	case Armor::ReactiveArmor:
		multiplier = model->m_pointsPerReactiveTon;
		break;
	case Armor::ReflectiveArmor:
		multiplier = model->m_pointsPerReflectiveTon;
		break;
	case Armor::SolarianArmor:
		multiplier = model->m_pointsPerSolarianTon;
		break;
	}

	Scalar armor_value = 0.0f;
	page->GetEntry("LeftLeg", &armor_value);
	message->m_leftLegArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("RightLeg", &armor_value);
	message->m_rightLegArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("LeftArm", &armor_value);
	message->m_leftArmArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("RightArm", &armor_value);
	message->m_rightArmArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("LeftFrontTorso", &armor_value);
	message->m_leftFrontTorsoArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("RightFrontTorso", &armor_value);
	message->m_rightFrontTorsoArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("CenterFrontTorso", &armor_value);
	message->m_centerFrontTorsoArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("CenterRearTorso", &armor_value);
	message->m_centerRearTorsoArmor = armor_value * multiplier;

	armor_value = 0.0f;
	page->GetEntry("Head", &armor_value);
	message->m_headArmor = armor_value * multiplier;

	page->GetEntry("InternalType", &type_string, true);
	message->m_internalType = Armor::InternalTypeTextToAscii(type_string);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Armor::SaveInstanceText(Page *instance_page)
{
	Check_Object(this);

	BaseClass::SaveInstanceText(instance_page);

	instance_page->SetEntry("ArmorType", Armor::ArmorTypeAsciiToText(m_armorType));
	instance_page->SetEntry("InternalType", Armor::InternalTypeAsciiToText(m_internalType));

	instance_page->SetEntry("LeftLeg", m_armorZoneValues[DamageObject::LeftLegArmorZone]);
	instance_page->SetEntry("RightLeg", m_armorZoneValues[DamageObject::RightLegArmorZone]);
	instance_page->SetEntry("LeftArm", m_armorZoneValues[DamageObject::LeftArmArmorZone]);
	instance_page->SetEntry("RightArm", m_armorZoneValues[DamageObject::RightArmArmorZone]);
	instance_page->SetEntry("LeftFrontTorso", m_armorZoneValues[DamageObject::LeftTorsoArmorZone]);
	instance_page->SetEntry("RightFrontTorso", m_armorZoneValues[DamageObject::RightTorsoArmorZone]);
	instance_page->SetEntry("CenterFrontTorso", m_armorZoneValues[DamageObject::CenterTorsoArmorZone]);
	instance_page->SetEntry("CenterRearTorso", m_armorZoneValues[DamageObject::CenterRearTorsoArmorZone]);
	instance_page->SetEntry("Head", m_armorZoneValues[DamageObject::HeadArmorZone]);

}

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	Armor__GameModel::ReadAndVerify(
		Armor__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
	//----------------------------------------
	//
	result = 
		Subsystem__GameModel::ReadAndVerify(
			model, 
			attribute_entry, 
			data,
			error,
			error_buffer
		);
	//
	//---------------------------
	//Verify all the model values
	//---------------------------
	//
	 
	switch(attribute_entry->attributeID)
	{
	case ArmDistributiveAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			model->m_totalArmorDistribution += model->m_armDistributive;
			if(model->m_armDistributive < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]ArmDistributive=%f}: value must be >= 0!",
					model->m_armDistributive
				);
				result = false;
			}
			if(model->m_totalArmorDistribution > 1.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{Your Armor distributions have gone over 1.0}"
				);
				result = false;
			}
			break;
		}
	case LegDistributiveAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			model->m_totalArmorDistribution += model->m_legDistributive;
			if(model->m_legDistributive < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]LegDistributive=%f}: value must be >= 0!",
					model->m_legDistributive
				);
				result = false;
			}
			if(model->m_totalArmorDistribution > 1.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{Your Armor distributions have gone over 1.0}"
				);
				result = false;
			}
			break;
		}
	case SideFrontDistributiveAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			model->m_totalArmorDistribution += model->m_sideFrontDistributive;
			if(model->m_sideFrontDistributive < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]SideFrontDistributive=%f}: value must be >= 0!",
					model->m_sideFrontDistributive
				);
				result = false;
			}
			if(model->m_totalArmorDistribution > 1.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{Your Armor distributions have gone over 1.0}"
				);
				result = false;
			}
			break;
		}
	case CenterFrontDistributiveAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			model->m_totalArmorDistribution += model->m_centerFrontDistributive;
			if(model->m_centerFrontDistributive < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]CenterFrontDistributive=%f}: value must be >= 0!",
					model->m_centerFrontDistributive
				);
				result = false;
			}
			if(model->m_totalArmorDistribution > 1.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{Your Armor distributions have gone over 1.0}"
				);
				result = false;
			}
			break;
		}
	case CenterRearDistributiveAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			model->m_totalArmorDistribution += model->m_centerRearDistributive;
			if(model->m_centerRearDistributive < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]CenterRearDistributive=%f}: value must be >= 0!",
					model->m_centerRearDistributive
				);
				result = false;
			}
			if(model->m_totalArmorDistribution > 1.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{Your Armor distributions have gone over 1.0}"
				);
				result = false;
			}
			break;
		}
// MSL 5.00 Armor
	case PointsPerStandardTonAttributeID:
		{
			if(!valid_data)
			{
				int value = 1;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->m_pointsPerStandardTon <= 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PointsPerStandardTon=%f}: value must be > 0!",
					model->m_pointsPerStandardTon
				);
				result = false;
			}
			break;
		}
	case PointsPerFerroTonAttributeID:
		{
			if(!valid_data)
			{
				int value = 1;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->m_pointsPerFerroTon <= 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PointsPerFerroTon=%f}: value must be > 0!",
					model->m_pointsPerFerroTon
				);
				result = false;
			}
			break;
		}
	case PointsPerReflectiveTonAttributeID:
		{
			if(!valid_data)
			{
				int value = 1;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->m_pointsPerReflectiveTon <= 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PointsPerReflectiveTon=%f}: value must be > 0!",
					model->m_pointsPerReflectiveTon
				);
				result = false;
			}
			break;
		}
	case PointsPerReactiveTonAttributeID:
		{
			if(!valid_data)
			{
				int value = 1;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->m_pointsPerReactiveTon <= 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PointsPerReactiveTon=%f}: value must be > 0!",
					model->m_pointsPerReactiveTon
				);
				result = false;
			}
			break;
		}
	case PointsPerSolarianTonAttributeID:
		{
			if(!valid_data)
			{
				int value = 1;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->m_pointsPerSolarianTon <= 0)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PointsPerSolarianTon=%f}: value must be > 0!",
					model->m_pointsPerSolarianTon
				);
				result = false;
			}
			break;
		}
	}
	return result;
}
