//===========================================================================//
// File:	Mech_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 "Airplane.hpp"
#include "MWTool.hpp"

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

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

	//
	//---------------------------------------------------------------
	// Point at the notation file and make other files relative to it
	//---------------------------------------------------------------
	//
	Page *page = script->instancePage;
	Check_Object(page);
	message->altitude = 0.0f;
	page->GetEntry("FlyingAltitude", &message->altitude);
}


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

	//
	//--------------
	// Set up stream
	//--------------
	//
	MemoryStream *model_stream = script->modelStream;
	Check_Object(model_stream);
	model_stream->AllocateBytes(sizeof(Airplane__GameModel));
	Vehicle__GameModel::ConstructGameModel(script);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	Airplane__GameModel::ReadAndVerify(
		Airplane__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 =
		Vehicle__GameModel::ReadAndVerify(
			model,
			attribute_entry,
			data,
			error,
			error_buffer
		);
	//
	//---------------------------
	//Verify all the model values
	//---------------------------
	//
	switch(attribute_entry->attributeID)
	{
		case TiltSpeedAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->tiltSpeed.angle < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]TiltSpeed=%f}: value must be >= 0!",
					model->tiltSpeed.angle*Degrees_Per_Radian
				);
				result = false;
			}
			break;
		}
		case TiltDegreeAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->tiltDegree.angle < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]TiltDegree=%f}: value must be >= 0!",
					model->tiltDegree.angle*Degrees_Per_Radian
				);
				result = false;
			}
			break;
		}
		
		case PercentageOfTurnToStartTiltAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->percentageOfTurnToStartTilt < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PercentageOfTurnToStartTilt=%f}: value must be >= 0!",
					model->percentageOfTurnToStartTilt
				);
				result = false;
			}
			break;
		}
		case PercentageOfSpeedToStartTiltAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->percentageOfSpeedToStartTilt < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PercentageOfSpeedToStartTilt=%f}: value must be >= 0!",
					model->percentageOfSpeedToStartTilt
				);
				result = false;
			}
			break;
		}
		case FlyingAltitudeAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->flyingAltitude <= 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]FlyingAltitude=%f}: value must be > 0!",
					model->flyingAltitude
				);
				result = false;
			}
			break;
		}
		case MaxTurnAngleAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.25f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			else
			{
				model->maxTurnAngle *= Degrees_Per_Radian;
			}
			if(model->maxTurnAngle <= 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]MaxTurnAngle=%f}: value must be > 0!",
					model->maxTurnAngle
				);
				result = false;
			}
			break;
		}
		case ThrusterAccelerationAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 35.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->thrusterAcceleration <= 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]ThrusterAcceleration=%f}: value must be > 0!",
					model->thrusterAcceleration
				);
				result = false;
			}
			break;
		}
		case PitchSpeedAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->pitchSpeed.angle < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PitchSpeed=%f}: value must be >= 0!",
					model->pitchSpeed.angle*Degrees_Per_Radian
				);
				result = false;
			}
			break;
		}
		case PitchDegreeAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->pitchDegree.angle < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PitchDegree=%f}: value must be >= 0!",
					model->pitchDegree.angle*Degrees_Per_Radian
				);
				result = false;
			}
			break;
		}
		
		case PercentageOfSpeedToStartPitchAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->percentageOfSpeedToStartPitch < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]PercentageOfSpeedToStartPitch=%f}: value must be >= 0!",
					model->percentageOfSpeedToStartPitch
				);
				result = false;
			}
			break;
		}
		case TakeOffSpeedAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 10.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->takeOffSpeed < 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]TakeOffSpeed=%f}: value must be >= 0!",
					model->takeOffSpeed
				);
				result = false;
			}
			break;
		}
		case MaxClimbAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->maxClimb <= 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]MaxClimb=%f}: value must be > 0!",
					model->maxClimb
				);
				result = false;
			}
			break;
		}
		case MaxDescentAttributeID:
		{
			if(!valid_data)
			{
				Scalar value = 0.0f;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			if(model->maxDescent <= 0.0f)
			{
				_snprintf(
					*error,
					error_buffer,
					"{[GameData]MaxDescent=%f}: value must be > 0!",
					model->maxDescent
				);
				result = false;
			}
			break;
		}
		case TakeOffResourceAttributeID:
		{
			if(!valid_data)
			{
				ResourceID value = ResourceID::Null;
				attribute_entry->SetValue(model, (void *)&value);
				result = true;
			}
			break;
		}
		case TakeOffGroundResourceAttributeID:
		{
			if(!valid_data)
			{
				ResourceID value = ResourceID::Null;
				attribute_entry->SetValue(model, (void *)&value);
				result = true;
			}
			break;
		}
		case LandingResourceAttributeID:
		{
			if(!valid_data)
			{
				ResourceID value = ResourceID::Null;
				attribute_entry->SetValue(model, (void *)&value);
				result = true;
			}
			break;
		}
		case LandingGroundResourceAttributeID:
		{
			if(!valid_data)
			{
				ResourceID value = ResourceID::Null;
				attribute_entry->SetValue(model, (void *)&value);
				result = true;
			}
			break;
		}
	}
	return result;
}

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

	BaseClass::SaveInstanceText(page);

	//
	//-------------------------
	// Save the Execution State
	//-------------------------
	//
	int execution_state = executionState->GetState();
	MString execution_state_text;
	switch(execution_state)
	{
	case ExecutionStateEngine::TakingOffMotionState:
		{
			execution_state_text = "TakingOffMotionState";
			break;
		}
	case ExecutionStateEngine::LandingMotionState:
		{
			execution_state_text = "LandingMotionState";
			break;
		}
	case ExecutionStateEngine::CrashingDeathState:
		{
			execution_state_text = "CrashingDeathState";
			break;
		}
		case ExecutionStateEngine::TaxiState:
		{
			execution_state_text = "TaxiState";
			break;
		}
		case ExecutionStateEngine::PopupState:
		{
			execution_state_text = "PopupState";
			break;
		}
		case ExecutionStateEngine::PopdownState:
		{
			execution_state_text = "PopdownState";
			break;
		}
		case ExecutionStateEngine::FloatState:
		{
			execution_state_text = "FloatState";
			break;
		}
	}
	if (execution_state_text)
	{
		page->SetEntry("ExecutionState", execution_state_text);
	}
	page->SetEntry("FlyingAltitude", flyingAltitude);
}