#include "AdeptHeaders.hpp"
#include "Effect.hpp"
#include "Tool.hpp"

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

	//
	//--------------
	// Set up stream
	//--------------
	//
	MemoryStream *message_stream = script->messageStream;
	Check_Object(message_stream);
	message_stream->AllocateBytes(sizeof(Effect__CreateMessage));
	Mover__CreateMessage::ConstructCreateMessage(script);
	Effect__CreateMessage *message =
		Cast_Pointer(
			Effect__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);

	//
	//---------------
	// Read the flags
	//---------------
	//
	bool flag = false;
	page->GetEntry("Looped", &flag);
	if (flag)
		message->replicatorFlags |= Effect::LoopFlag;
}

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

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

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

	model->rotationType = NoRotation;
	const char *rotation_string;
	if(page->GetEntry("RotationType", &rotation_string))
		model->rotationType = RotationTypeTextToAscii(rotation_string);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	Effect__GameModel::ReadAndVerify(
		Effect__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 = 
		Mover__GameModel::ReadAndVerify(
			model, 
			attribute_entry, 
			data,
			error,
			error_buffer
		);

	switch(attribute_entry->attributeID)
	{
	case StartsRunningAttributeID:
		{
			if(!valid_data)
			{
				_snprintf(
					*error,
					error_buffer,
					"Effect Must have a startsRunning Entry"
				);
				result = false;
			}
			break;
		}
	case KillOnAttachedEntityDeathAttributeID:
		{
			if(!valid_data)
			{
				bool value = true;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			break;
		}
		
	case TranslationAttributeID:
		{
			if(!valid_data)
			{
				Point3D value;
				value = Point3D::Identity;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
			break;
		}
	case RotationAttributeID:
		{
			if(!valid_data)
			{
				UnitQuaternion value;
				value = UnitQuaternion::Identity;
				attribute_entry->SetValue(model, &value);
				result = true;
			}
		}
	}
	return result;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const char *
	Effect__GameModel::RotationTypeAsciiToText(int rotation_type)
{
	switch(rotation_type)
	{
	case NoRotation:
		return "NoRotation";
	case AgainstMotionRotation:
		return "AgainstMotionRotation";
	case IntoMotionRotation:
		return "IntoMotionRotation";
	}
	return "NoRotation";
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	Effect__GameModel::RotationTypeTextToAscii(const char *rotation_string)
{

	if(rotation_string == NULL)
		return NoRotation;

	if(!_stricmp(rotation_string, "NoRotation"))
		return NoRotation;
	else if(!_stricmp(rotation_string, "AgainstMotionRotation"))
		return AgainstMotionRotation;
	else if(!_stricmp(rotation_string, "IntoMotionRotation"))
		return IntoMotionRotation;
	else if(!_stricmp(rotation_string, "UseRotation"))
		return UseRotation;
		
	return NoRotation;
}