#include "MW4Headers.hpp"

#include "Path.hpp"
#include "MWTool.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	Path__CreateMessage::ConstructCreateMessage(Script *script)
{
	Check_Object(script);
	#if defined(_ARMOR)
		int stack_level = Tool::Instance->GetStackLevel();
	#endif
	//
	//--------------
	// Set up stream
	//--------------
	//
	MemoryStream *message_stream = script->messageStream;
	Check_Object(message_stream);
	message_stream->AllocateBytes(sizeof(Path__CreateMessage));
	Entity__CreateMessage::ConstructCreateMessage(script);
	Path__CreateMessage *message =
		Cast_Pointer(
			Path__CreateMessage*,
			message_stream->GetPointer()
		);
	message->messageLength = sizeof(*message);

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

	message->pathPointsResourceID = ResourceID::Null;
	NotationFile path_file;
	if (page->GetEntry("PathPoints", &path_file))
	{
		const char *path_points_filename = path_file.GetFileName();
		Check_Pointer(path_points_filename);

		//
		//---------------------------------------------------------------
		// Look for the damage stream resource to see if it is up to date
		//---------------------------------------------------------------
		//
		Resource path_resource(path_points_filename);
		if (
			path_resource.DoesResourceExist() &&
			path_resource.IsResourceUpToDate()
		)
		{
			message->pathPointsResourceID = path_resource.GetResourceID();
			if (!path_resource.IsRegistered())
				path_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
		}
			
		else
		{

			//
			//----------------------------------------
			// For each page, an Point3D will be added
			//----------------------------------------
			//
			Tool::Instance->PushFilePath(&path_file);
			DynamicMemoryStream path_stream;
			Page *path_page = path_file.FindPage("Path");
			if (path_page)
			{
				Check_Object(path_page);
				Page::NoteIterator *path_entries = path_page->MakeNoteIterator();
				Check_Object(path_entries);
				path_stream << path_entries->GetSize();

				//
				//---------------------------------------
				// Create the damage Object for this page
				//---------------------------------------
				//
				Note* point_instance;
				while ((point_instance = path_entries->ReadAndNext()) != NULL)
				{
					Point3D point;
					point_instance->GetEntry(&point);
					path_stream << point;
				}

				//
				//-----------------------------------------
				// Only save out the stream if there is one
				//-----------------------------------------
				//
				if (path_stream.GetBytesUsed())
				{
					path_resource.Save(
						&path_stream, 
						path_file.GetFileDependencies()
					);
					if (!path_resource.IsRegistered())
						path_resource.AddFileDependenciesTo(Resource::ParentFileDependencies);
					Check_Object(&path_resource);
					message->pathPointsResourceID = path_resource.GetResourceID();
				}
				else
					message->pathPointsResourceID = ResourceID::Null;
				Check_Object(path_entries);
				delete path_entries;
			}
		
			//------------------------
			// Clean up the tool stack
			//------------------------
			//
			Tool::Instance->PopFilePath();
		}
	}
	Tool::Instance->PopFilePath();
	Verify(stack_level == Tool::Instance->GetStackLevel());
}

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

	Entity::SaveInstanceText(instance_page);

	if(pathPointsResourceID != ResourceID::Null)
	{
		Resource path_resource(pathPointsResourceID);
		Verify(path_resource.DoesResourceExist());
		instance_page->SetEntry("PathPoints", path_resource.GetName());
	}
}