#include "stdafx.h"
#include <MW4\MW4.hpp>
#include <MW4\MW4.hpp>
#include <MFCPlatform\MFCPlatform.hpp>
#include <GameOS\ToolOS.hpp>
#include <Stuff\Stuff.hpp>
#include <MLR\MLR.hpp>
#include <GosFx\GosFx.hpp>
#include <GosFx\EffectLibrary.hpp>
#include <ElementRenderer\ElementRenderer.hpp>
#include <Adept\Adeptheaders.hpp>
#include <Adept\EntityManager.hpp>
#include <Adept\CollisionGrid.hpp>
#include <ElementRenderer\GridElement.hpp>
#include <Adept\Tile.hpp>
#include <MW4\MWMission.hpp>
#include <MW4\MWMap.hpp>
#include <Adept\Zone.hpp>
#include <MW4\Turret.hpp>
#include <MW4\Path.hpp>
#include <MW4\MWTable.hpp>
#include <MW4\WaterCultural.hpp>
#include <Compost\Compost.hpp>
#include <MW4\CameraShip.hpp>
#include <MW4\Objective.hpp>
#include <MW4\EffectGenerator.hpp>
#include <MW4\Flag.hpp>
#include <MW4\Team.hpp>
#include <Adept\ResourceEffectLibrary.hpp>
#include <Adept\CollisionVolume.hpp>
#include "GlobalDefines.h"
#include "UndoManager.h"
#include "NameManager.h"
#include "EdObjective.h"
#include <Adept\LightManager.hpp>
#include <MLR\MLRLight.hpp>
#include "GUILight.h"
#include "GUIFXGenerator.h"
#include "resource.h"
#include <Adept\VideoHeaders.hpp>
#include <ElementRenderer\ElementRenderer.hpp>
#include <ElementRenderer\StateChange.hpp>

#include <direct.h>
char *LocalIPAddress;
// This block may not be needed
using namespace MechWarrior4;
#include <MW4\Vehicle.hpp>
#include <MW4\Building.hpp>
#include <MW4\NonCom.hpp>
#include <MW4\Navpoint.hpp>
#include <MW4\Cultural.hpp>
#include <Adept\Dropzone.hpp>
#include <MW4\MWTool.hpp>
#include <MW4\SearchLight.hpp>
#include <MW4DedicatedUI\DedicatedUI.hpp>

#include <MW4\AI.hpp>
using namespace Stuff;
using namespace MW4AI;
using namespace Adept;
using namespace MidLevelRenderer;
#include <Buildnum\BuildNum.h>
#include <Adept\Map.hpp>
#include <MW4\MWTool.hpp>
#include <Adept\Tool.hpp>
#include <MW4\MWPlayer.hpp>
#include <mw4\mwapplication.hpp>

#include "EditorApplication.h"
#include "ObjectManager.h"
#include "OverviewWindow.h"
#include "NVGameObject.h"
#include "GUIDropZone.h"
#include "GUILattice.h"
#include "GUICamera.h"
#include "MissionReport.h"
#include "BldResDlg.h"
extern bool Immediate_Draw;
bool NeedResourceBuild=true;
bool AllowBuild=true;
bool AllowBldSkies=false; // jcem
bool NoBldMissions=false; // jcem
bool MissionLoaded=false;
extern bool gNoDialogs;
extern bool AllowFail;

#define USEEXTERNALLY

#ifdef USEEXTERNALLY
#define BUILDFILENAME "Content\\MW4Editor.Build"
#else
#define BUILDFILENAME "Content\\MechWarrior4.Build"
#endif

bool GameInitilized=false;

#include "GameInterface.h"

void	SetMissionName(CString old_mission_name,CString new_mission_name);


void GameInit(HINSTANCE inst,HWND win,char *Comline)
{
	InitGameOS(inst,win,Comline);
}

void InitClasses()
{	
	Stuff::InitializeClasses();
	MidLevelRenderer::InitializeClasses(NULL, 2048*8);
	Compost::InitializeClasses();
	gosFX::InitializeClasses();
	ElementRenderer::InitializeClasses();
	Adept::InitializeClasses();
	Map::LoadRadius = 8;
	MechWarrior4::InitializeClasses();
	
	EditorApplication::InitializeClass();
	Immediate_Draw=false;
	
	
	
	
	Adept::Tool::Instance = new MechWarrior4::MWTool();
	
	Check_Object(Tool::Instance);
	EditorApplication *MW4GameEd_Application = new EditorApplication;
	Check_Object(MW4GameEd_Application);
	GlobalPointers::AddGlobalPointer(MW4GameEd_Application, ApplicationGlobalPointerIndex);
	MW4GameEd_Application->Initialize();
	CollisionGrid::s_ignoreOBBCollisions=true;
	
	
	Verify(!Network::GetInstance());
	GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
	Check_Object(Network::GetInstance());
	
	gos_EnableSetting(gos_Set_NumLockMode,2);
	
	GameInitilized = true;
}

void TermClasses()
{
	gNoDialogs=true;
	AllowFail=true;
	
	GameInitilized = false;
	
	
	
	Check_Object(Adept::Application::GetInstance());
	delete Adept::Application::GetInstance();
	GlobalPointers::ClearPointer(ApplicationGlobalPointerIndex);
	
	
	if (Tool::Instance)
	{
		Check_Object(Tool::Instance);
		delete Tool::Instance;
	}
	
	
	EditorApplication::TerminateClass();
	MechWarrior4::TerminateClasses();
	
	Adept::TerminateClasses();
	ElementRenderer::TerminateClasses();
	gosFX::TerminateClasses();
	Compost::TerminateClasses();
	MidLevelRenderer::TerminateClasses();
	Stuff::TerminateClasses();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void _stdcall TerminateGameEngine()
{
	Check_Object(ResourceManager::Instance);
	delete ResourceManager::Instance;
	ResourceManager::Instance=NULL;	
	
	Check_Object(Adept::Application::GetInstance());
	Adept::Application::GetInstance()->Terminate();
	
	TermClasses();
	ExitGameOS();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void _stdcall InitializeGameEngine()
{
	//	Stuff::ArmorLevel = 1;
	InitClasses();
}

void LoadResourceForBuild(const char *resource_file_name,int level)
{
	
	FileDependencies deps;
	
	
	//			PushFilePath(&parse_file);
	ResourceFile *res_file =
		ResourceManager::Instance->OpenResourceFile(
		resource_file_name,
		//					dep_filename,
		NULL,
		level,
		VER_CONTENTVERSION,
		true,
		false
		);
		/*
		//
		//-------------------------------------------------------
		// If we have dependencies, write them into resource zero
		//-------------------------------------------------------
		//
		{
		Resource build_dependencies(resource_file_name);
		if (!build_dependencies.DoesResourceExist())
		{
		unsigned length = dependencies->m_fileNameStream.GetBytesUsed();
		if (length>0)
		{
		MemoryStream chain(
		static_cast<BYTE*>(dependencies->m_fileNameStream.GetPointer()) - length,
		length,
		length
		);
		build_dependencies.Save(&chain, dependencies);
		}
		else
		{
		MemoryStream chain("", 1, 1);
		build_dependencies.Save(&chain, NULL);
		}
		}
		Verify(build_dependencies.GetResourceID().GetRecordID() == ResourceID::BuildDependenciesRecordID);
		}
	*/
	//			PopFilePath();
	
}

extern HGOSHEAP CurrentHeap;


void __stdcall
EdGetFileForGOS(
				const char* file_name,
				BYTE** memory,
				DWORD* size
				)
{
	if(Tool::FindFileForGOS(file_name))
	{
		Tool::GetFileForGOS(file_name,memory,size);
	}
	else if(Application::FindFileForGOS(file_name))
	{
		Application::GetFileForGOS(file_name,memory,size);
		BYTE *oldbuf=*memory;
		*memory=(BYTE *)gos_Malloc(*size>0?*size:4,CurrentHeap);
		CopyMemory(*memory,oldbuf,*size);
	}
	else STOP(("%s File Not found",file_name));
	
}

bool __stdcall EdFindFileForGOS(const char* filename)
{
	return Application::FindFileForGOS(filename) || Tool::FindFileForGOS(filename);
}


void ObjectManager::BuildResources()
{
	CBldResDlg dlg;
	
	Environment.HookGetFile = Adept::Tool::GetFileForGOS;
	Environment.HookDoesFileExist = Adept::Tool::FindFileForGOS;
	

		gos_PushCurrentHeap(gosFX::Heap);
	if(gosFX::EffectLibrary::Instance!=NULL)
	{
		delete gosFX::EffectLibrary::Instance;
		gosFX::EffectLibrary::Instance=NULL;
	}
	
		gosFX::EffectLibrary::Instance = new ResourceEffectLibrary;
		gos_PopCurrentHeap();
	
	
	ResourceManager::Instance = new ResourceManager;
	Check_Object(ResourceManager::Instance);
	
	
	
	//
	//--------------------------------------------------------
	// We have disabled building, so load up the required data
	//--------------------------------------------------------
	//
	
	LoadResourceForBuild("Resource\\textures.mw4",TexturesResourceFileID);
	LoadResourceForBuild("Resource\\core.mw4",CoreResourceFileID);
	LoadResourceForBuild("Resource\\props.mw4",PropsResourceFileID);
	//LoadResourceForBuild("Resource\\skies.mw4",MissionResourceFileID+1);
	
	
	//
	//-------------------------
	// Load up the core effects
	//-------------------------
	//
	Resource libraries("{effects}");
	Verify(libraries.DoesResourceExist());
	libraries.LoadData();
	ResourceID *lib = Cast_Pointer(ResourceID*, libraries.GetPointer());
	for (unsigned i=0; i<libraries.GetSize()/sizeof(ResourceID); ++i, ++lib)
	{
		Resource library(*lib);
		gosFX::EffectLibrary::Instance->Load(&library);
	}
	
	
	
	if(AllowBuild || AllowBldSkies) // jcem
	{
		
		FileDependencies deps;
		Stuff::NotationFile build_script;
		Stuff::NotationFile blank_nfile;
		blank_nfile.SetPage("");
		Page *bpage=build_script.SetPage("");
		Check_Object(bpage);
		bpage->SetEntry("skies.build",&blank_nfile);	


		if (AllowBuild) { // jcem
			WIN32_FIND_DATA file_data;
	HANDLE file_find;
	file_find=FindFirstFile("Content\\Maps\\*.*",&file_data);
	
	if(file_find != INVALID_HANDLE_VALUE)
	{
		CString map_name;
		do
		{
			map_name=file_data.cFileName;
			if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && 
				map_name!="."  && map_name!=".." )
			{
				CString buildfname="Maps\\"+map_name+"\\"+map_name+".build";
				bpage->SetEntry(buildfname,&blank_nfile);	
			}
		}
		while (FindNextFile(file_find,&file_data));
	}
		}

	
		Application::BuildOK=true;
		Tool::Instance->BuildResources(&build_script, VER_CONTENTVERSION, &deps,2);
		build_script.IgnoreChanges();
	}
	Application::BuildOK=false;
	

	gos_CreateDirectory("Resource\\UserMissions");
	
	
	if (!NoBldMissions) { // jcem
	bool maploaded=false;
	
	WIN32_FIND_DATA file_data;
	HANDLE file_find;
	file_find=FindFirstFile("Content\\Missions\\*.*",&file_data);
	
	if(file_find != INVALID_HANDLE_VALUE)
	{
		CString mis_name;
		do
		{
			mis_name=file_data.cFileName;
			if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY && 
				mis_name!="."  && mis_name!=".." )
			{
				CString instfname="Content\\Missions\\"+mis_name+"\\"+mis_name+".instance";
				
				Stuff::NotationFile instfile(instfname);
				Page *mis_page=instfile.GetPage(mis_name);
				Check_Object(mis_page);
				const char *mapentry;
				mis_page->GetEntry("Map",&mapentry);
				CString mapname=mapentry;
				mapname=mapname.Mid(mapname.ReverseFind('\\')+1);
				mapname=mapname.Left(mapname.ReverseFind('.'));
				
				if(maploaded)
				{
					delete ResourceManager::Instance->GetResourceFile(MapResourceFileID);
					maploaded=false;
				}
				
				
				LoadResourceForBuild("Resource\\Maps\\"+mapname+".mw4",MapResourceFileID);
				maploaded=true;
				
//				gos_CreateDirectory("Resource\\UserMissions");

				
				if(AllowBuild)
				{
					CString mispath="Content\\Missions\\"+mis_name;
					CString buildfname=mispath+"\\"+mis_name+".build";
					//Stuff::NotationFile build_script(buildfname);
					
					
					Stuff::NotationFile build_script(buildfname);
					Stuff::NotationFile blank_nfile;
					blank_nfile.SetPage("");
					Page *bpage=build_script.SetPage("");
					Check_Object(bpage);
					bpage->SetEntry(buildfname,&blank_nfile);	
					
					
					Application::BuildOK=true;
					
					
					Environment.HookGetFile = EdGetFileForGOS;
					Environment.HookDoesFileExist = EdFindFileForGOS;
					
					FileDependencies deps;
					deps.AddDependency("Resource\\Maps\\"+mapname+".mw4");
					
					//					Tool::Instance->PushFilePath(&build_script);					
					Tool::Instance->BuildResources(&build_script, VER_CONTENTVERSION, &deps,3);			
					//					Tool::Instance->PopFilePath();

					Environment.HookGetFile = Adept::Tool::GetFileForGOS;
					Environment.HookDoesFileExist = Adept::Tool::FindFileForGOS;
					
					build_script.IgnoreChanges();
				}
				Application::BuildOK=false;
				
				
			}
		}
		while (FindNextFile(file_find,&file_data));
	}
	
	delete ResourceManager::Instance->GetResourceFile(MapResourceFileID);
  }
	
	NeedResourceBuild=false;
	
	
	ResourceManager::Instance->OpenResourceFile(
		"Resource\\skies.mw4",
		NULL,
		MissionResourceFileID+1,
		VER_CONTENTVERSION,
		true,
		false
		);
	
	delete gosFX::EffectLibrary::Instance;
	gosFX::EffectLibrary::Instance=NULL;
	
	MWApplication::GetInstance()->LoadLookupTables();
	Environment.HookGetFile = Application::GetFileForGOS;
	Environment.HookDoesFileExist = Application::FindFileForGOS;
	
}



void __stdcall GetGameOSEnvironment(char* CommandLine)
{
	
	Environment.applicationName			= "MW4GameEd2";
	Environment.directoryPath			= "code\\MW4GameEd2;Binaries\\MW4";
	Environment.screenWidth				= 640;
	Environment.screenHeight			= 480;
	Environment.fullScreen				= FALSE;
	Environment.bitDepth				= 16;
	Environment.debugLog				= "DebugLog.txt";
	Environment.spew					= "GameOS_Memory"; //GROUP_ADEPT_RESOURCE;
	Environment.memoryTraceLevel		= 10;
	Environment.TimeStampSpew			= false;
	Environment.DoGameLogic				= &MWApplication::DoGameLogic;
	Environment.UpdateRenderers			= &Application::UpdateDisplay;
	Environment.InitializeGameEngine	= InitializeGameEngine;
	Environment.TerminateGameEngine		= TerminateGameEngine;
	
	Environment.Key_FullScreen			= 0;
	Environment.Key_SwitchMonitors		= 0; //KEY_F5;
	Environment.Key_Exit				= 0;
	
	Environment.Renderer				= 0;
	Environment.FullScreenDevice		= 0;
	
	Environment.AntiAlias				= 0;			// true/false - Enable full screen antialiasing
	Environment.NetworkGame				= false;
	Environment.NetworkMaxPlayers		= 2;
	
	Environment.Texture_S_256			= 13;
	Environment.Texture_S_128			= 12;
	Environment.Texture_S_64			= 1;
	Environment.Texture_S_32			= 1;
	Environment.Texture_S_16			= 1;
	
	Environment.Texture_K_256			= 1;
	Environment.Texture_K_128			= 1;
	Environment.Texture_K_64			= 1;
	Environment.Texture_K_32			= 1;
	Environment.Texture_K_16			= 1;
	
	Environment.Texture_A_256			= 1;
	Environment.Texture_A_128			= 1;
	Environment.Texture_A_64			= 1;
	Environment.Texture_A_32			= 1;
	Environment.Texture_A_16			= 1;
	
	Environment.soundChannels			= 32;
	Environment.soundDisable			= true;
	Environment.soundHiFi				= false;
	
	Environment.dontClearRegistry		= true;
	
	Environment.MaxTimeDelta = 0.25f;
}

#define COLSTART 600.0f

float ComputeTerrainElevation(float x,float z,Entity *ignore_entity)
{
	if (!GameInitilized || !MissionLoaded)
		return 0.0f;
	
	if ((Mission::GetInstance() == 0)) return 0.0f;
	
	Entity::CollisionMask collisionType = Entity::CanBeWalkedOnFlag;
	
	Stuff::Line3D line;
	Point3D point;
	
	point.x = x;
	point.z = z;
	point.y = COLSTART;
	
	line.m_length = 1000.0f;
	line.m_direction = Vector3D::Down;
	line.SetOrigin(point);
	
	//
	// Prepare query
	//	
	Stuff::Normal3D inormal;
	Stuff::Line3D iline;
	Stuff::Normal3D normal;
	Entity *entity_hit;
	
	Check_Object(CollisionGrid::Instance);
	Entity::CollisionQuery query(&line, &normal, collisionType,ignore_entity);
	entity_hit = CollisionGrid::Instance->ProjectLine(&query);
	
	if(entity_hit != NULL)
	{
		line.FindEnd(&point);
	}
	return (point.y);
}

Entity *GetTopEntity(float x,float z,float& height)
{
	if (Mission::GetInstance() == 0) return NULL;
	
	Entity::CollisionMask collisionType = Entity::CanBeShotFlag;
	
	Stuff::Line3D line;
	Point3D point;
	
	point.x = x;
	point.z = z;
	point.y = COLSTART;
	
	line.m_length = 1000.0f;
	line.m_direction = Vector3D::Down;
	line.SetOrigin(point);
	
	//
	// Prepare query
	//	
	Stuff::Normal3D inormal;
	Stuff::Line3D iline;
	Stuff::Normal3D normal;
	
	Check_Object(CollisionGrid::Instance);
	Entity::CollisionQuery query(&line, &normal, collisionType,NULL);
	Entity *entity;
	entity=CollisionGrid::Instance->ProjectLine(&query);
	
	if (entity != 0)
	{
		Stuff::Point3D end;
		query.m_line->FindEnd(&end);
		
		height = end.y;
	}
	
	if(entity->IsDerivedFrom(MWMover::DefaultData))
	{
		MWMover *mover;
		mover = Cast_Object(MWMover *, entity);
		if(mover->myParentVehicle)
			return mover->myParentVehicle;
	}
	return entity;
}


CString GetMissionScriptName()
{
	if ((Mission::GetInstance() == 0) ||
		(Mission::GetInstance()->IsDerivedFrom(MWMission::DefaultData) == false))
	{
		return ("");
	}
	
	MWMission* mwmission = Cast_Object(MWMission*,Mission::GetInstance());
	return (mwmission->scriptName);
}

void SetMissionScriptName(const CString& script_name)
{
	if ((Mission::GetInstance() == 0) ||
		(Mission::GetInstance()->IsDerivedFrom(MWMission::DefaultData) == false))
	{
		return;
	}
	MWMission* mwmission = Cast_Object(MWMission*,Mission::GetInstance());
	
	strcpy(mwmission->scriptName,script_name);
}



void ObjectManager::CheckScripts()
{
	Environment.HookGetFile = EdGetFileForGOS;
	Environment.HookDoesFileExist = EdFindFileForGOS;
	
	if (Mission::GetInstance() == 0)	return;
	
	MWMission *mission = Cast_Object(MWMission*,Mission::GetInstance());
	mission->UnloadScript();
	
	MWMap *inst;
	AI *ai;
	inst = Cast_Object(MWMap *,Map::GetInstance());
	ChainIteratorOf<AI *> iterator2(&inst->m_executingAIs);
	iterator2.First();
	while ((ai = iterator2.ReadAndNext()) != NULL)
	{
		Check_Object(ai);
		ai->UnloadScript();
	}
	
	ABL::ABLError error;
	CString errstr;
	CString filename;
	CString cmdline,line;
	char errMessage[500];
	
	if (!mission->ReloadABL (&error))
	{
		sprintf(errMessage, "SYNTAX ERROR %s [line %d] - (type %d) %s\n", error.File (), error.Line (),error.Code (), error.String ());
		
		MessageBox (NULL,errMessage,"ABL Error",MB_OK);
		
		filename = error.File ();
		
		//		cmdline = "c:\\vslick\\win\\vs ";
		cmdline = "vs ";
		cmdline += "\"";
		_getcwd (errMessage,500);
		if (filename[1] != ':')
		{
			cmdline += errMessage;
			cmdline += "\\";
		}
		cmdline += filename;
		cmdline += "\"";
		cmdline += " -#";
		itoa (error.Line (),errMessage,10);
		cmdline += errMessage;	
		
		//		system ((LPCTSTR) cmdline);
		if (WinExec ((LPCTSTR) cmdline,SW_SHOW) <= 31)			// old function but it works
		{
			MessageBox (NULL,"Unable to start SlickEdit, make sure it's in your path","error",MB_OK);
		}
		//		CreateProcess (NULL,cmdline,NULL,NULL,FALSE,0,NULL,NULL,NULL,NULL);
		return;
	}
	
	if (!mission->ReloadScript (&error))
	{
		sprintf(errMessage, "SYNTAX ERROR %s [line %d] - (type %d) %s\n", error.File (), error.Line (),error.Code (), error.String ());
		
		MessageBox(NULL,errMessage,"ABL Error",MB_OK);
		
		filename = error.File ();
		
		//		cmdline = "c:\\vslick\\win\\vs ";
		cmdline = "vs ";
		cmdline += "\"";
		_getcwd(errMessage,500);
		if (filename[1] != ':')
		{
			cmdline += errMessage;
			cmdline += "\\";
		}
		cmdline += filename;
		cmdline += "\"";
		cmdline += " -#";
		itoa (error.Line(),errMessage,10);
		cmdline += errMessage;	
		
		//		system ((LPCTSTR) cmdline);
		if (WinExec((LPCTSTR) cmdline,SW_SHOW) <= 31)			// old function but it works
			MessageBox (NULL,"Unable to start SlickEdit.  Make sure it's in your path","Error",MB_OK);
		//		CreateProcess (NULL,cmdline,NULL,NULL,FALSE,0,NULL,NULL,NULL,NULL);
		return;
	}
	iterator2.First();
	while ((ai = iterator2.ReadAndNext()) != NULL)
	{
		{
			if (!ai->ReloadScript(&error))
			{
				sprintf(errMessage, "SYNTAX ERROR %s [line %d] - (type %d) %s\n", error.File (), error.Line (),error.Code (), error.String ());
				
				MessageBox(NULL,errMessage,"ABL Error",MB_OK);
				
				filename = error.File();
				
				cmdline = "vs ";
				//				cmdline = "c:\\vslick\\win\\vs ";
				cmdline += "\"";
				_getcwd(errMessage,500);
				if (filename[1] != ':')
				{
					cmdline += errMessage;
					cmdline += "\\";
				}
				cmdline += filename;
				cmdline += "\"";
				cmdline += " -#";
				itoa(error.Line(),errMessage,10);
				cmdline += errMessage;	
				
				//		system ((LPCTSTR) cmdline);
				if (WinExec((LPCTSTR) cmdline,SW_SHOW) <= 31)			// old function but it works
				{
					MessageBox(NULL,"Unable to start SlickEdit.  Make sure it's in your path.","Error",MB_OK);
				}
				//		CreateProcess (NULL,cmdline,NULL,NULL,FALSE,0,NULL,NULL,NULL,NULL);
				return;
			}
		}
	}
	
	CheckAlternativeScripts();

	Environment.HookGetFile = Application::GetFileForGOS;
	Environment.HookDoesFileExist = Application::FindFileForGOS;
	
}

// **************************************************************************
//  ObjectManager Game Related Code
// **************************************************************************

EdGUIObject *ObjectManager::AttachGameObject(Entity *entity)
{
	Check_Object(entity);
	
	EdGameObject *obj=NULL;
	
	if(entity->IsDerivedFrom(Vehicle::DefaultData)  ||	// Visual Objects
		entity->IsDerivedFrom(Building::DefaultData) ||
		entity->IsDerivedFrom(Cultural::DefaultData) ||
		entity->IsDerivedFrom(NonCom::DefaultData)
		)
	{
		
		if(!entity->IsPlayerVehicle())
		{
			obj=new EdGameObject;
			obj->AssociateTo(entity);
			AddObject(obj);
			return obj;
		}
	}
	else if(entity->IsDerivedFrom(Path::DefaultData))
	{
		GUIPath *pobj=new GUIPath;
		pobj->AssociateTo(Cast_Object(Path*,entity));
		AddObject(pobj);
		return pobj;
		
	}
	else if(entity->IsDerivedFrom(DropZone::DefaultData))
	{
		GUIDropZone *dzobj=new GUIDropZone;
		dzobj->AssociateTo(Cast_Object(DropZone*,entity));
		AddObject(dzobj);
		return dzobj;
		
	}
	else if(entity->IsDerivedFrom(NavPoint::DefaultData) || 
		entity->IsDerivedFrom(Flag::DefaultData) ||
		entity->IsDerivedFrom(Team::DefaultData) )
	{
		obj=new NVGameObject;
		obj->AssociateTo(entity);
		AddObject(obj);
		return obj;
	} 
	else if(entity->IsDerivedFrom(CameraShip::DefaultData) )
	{
		GUICamera *cam=new GUICamera();
		cam->AssociateTo(entity);
		AddObject(cam);
		return cam;
	}
	else if(entity->IsDerivedFrom(Objective::DefaultData) )
	{
		EdObjective *obj=new EdObjective();
		obj->AssociateTo(entity);
		ObjectiveList.AddObject(obj);
		return obj;
	}
	else if(entity->IsDerivedFrom(EffectGenerator::DefaultData) )
	{
		GUIFXGenerator *obj=new GUIFXGenerator();
		obj->AssociateTo(entity);
		AddObject(obj);
		return obj;
	}
	
	if(HasCollsion(entity))
	{
		
		obj=new EdGameObject;
		obj->AssociateTo(entity);
		AddObject(obj);
		return obj;
	}
	
	return NULL;
}



void ObjectManager::SyncToGame(ViewWindowInfo *vinf)
{
	NameTable::GetInstance()->IsValid();
	Verify(IsLoaded());
	Dissociate();
	DeleteAllObjects();
	
	if(UndoMan) {delete UndoMan; UndoMan=NULL;}
	UndoMan=new UndoManager;
	
	
	// Set Mission Name
	CString misname(MWApplication::GetInstance()->GetMissionName());
	misname=misname.Left(misname.ReverseFind('.'));
	misname=misname.Mid(misname.ReverseFind('\\')+1);
	Name=misname;
	
	MapName=(char *)Map::GetInstance()->GetDataListResource()->GetName();
    MapName=MapName.Left(MapName.ReverseFind('.'));
    MapName=MapName.Mid(MapName.ReverseFind('\\')+1);
	
	
	// Make GUI Objects for Game Objects
	Map::GetInstance()->GetDataListResource()->LoadData();
	ChainIteratorOf<Entity *> iterator(&Map::GetInstance()->childEntityChain);
	Entity *entity;
	
	
	while((entity = iterator.ReadAndNext()) != NULL)
	{
		AttachGameObject(entity);
	}
	
	
	gosFX::Light* gamelight;
	GUILight *edlight;
	
	ChainIteratorOf<gosFX::Light*> lightiterator(&Mission::GetInstance()->m_staticLights);
	
	while((gamelight = lightiterator.ReadAndNext()) != NULL)
	{
		switch (gamelight->m_light->GetLightType())
		{
		case MLRLight::AmbientLight:
			edlight=new GUIAmbientLight("Ambient Light");
			break;
		case MLRLight::InfiniteLight:
			edlight=new GUIInfiniteLight("Infinite Light");
			break;
		case MLRLight::PointLight:
			edlight=new GUIPointLight("Point Light");
			break;
		case MLRLight::SpotLight:
			edlight=new GUISpotLight("Spot Light");
			break;
		case MLRLight::LookUpLight:
			Verify(LLight==NULL);
			LLight=new GUILookUpLight("LookUp Light");
			LLight->AssociateTo(gamelight);
			AddObject(LLight);
		default:
			edlight=NULL;			
		}
		
		if(edlight)
		{
			edlight->AssociateTo(gamelight);
			AddObject(edlight);
		}
	}
	
	
	// Get the Map Size
	
	BYTE rows, cols;
	Map::GetInstance()->GetElement()->GetSize(&rows, &cols);
	
	// Save the MapSize
	MapSize=Point3D(rows*c_ZoneSize,0.0f,cols*c_ZoneSize);
	vinf->SetMapSize(MapSize);
	vinf->SetZoneSize(c_ZoneSize);
	vinf->SetTileSize(c_TileSize);
	
	int i;
	// Load missionBounds
	DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > Bound;
	Mission::GetInstance()->GetMissionPolygon(Bound);
	for (i = 0; i < Bound.GetLength(); i++)
	{
		Bound[i].x /= Map::GetInstance()->GetColumnZoneScale();
		Bound[i].y /= Map::GetInstance()->GetRowZoneScale();
		Bound[i].x -= MapSize.x*0.5f;
		Bound[i].y -= MapSize.z*0.5f;
		
	}
	
	MissionBound->SetBoundData(Bound);
	// Load warningBounds
	Mission::GetInstance()->GetWarningPolygon(Bound);
	for (i = 0; i < Bound.GetLength(); i++)
	{
		Bound[i].x /= Map::GetInstance()->GetColumnZoneScale();
		Bound[i].y /= Map::GetInstance()->GetRowZoneScale();
		Bound[i].x -= MapSize.x*0.5f;
		Bound[i].y -= MapSize.z*0.5f;
	}
	WarningBound->SetBoundData(Bound);
	
	// Load The Terrain Textures
	
	CString MapName(CString(Map::GetInstance()->GetDataListResource()->GetName()));
	MapName=MapName.Left(MapName.ReverseFind('.'));
	MapName=MapName.Mid(MapName.ReverseFind('\\')+1);
	
	
	TerrainTexture.CreateBlank(cols*256,rows*256,ITYPE_RGB,24,RGBMask(0xff0000,0x00ff00,0x0000ff));
	LoadTerrainTexture(&TerrainTexture);
	
	Point3D map_scale;
	HField.CreateBlank(256,256,ITYPE_RGB,24);
	
	map_scale=BuildHFFromMap(&HField);	
	
	SlopeMap=HField;
	
	MakeSlopeMap(&SlopeMap,map_scale);
	MisDat.SyncToGame();
	
	AddObject(Lattice=new GUILattice(MW4AI::g_MissionGraph));
	
	ClearModifyFlags();
}

#define Round(x) floor((x)+.5f)

void ObjectManager::LoadTerrainTexture(Image *img)
{
	BYTE rows, cols;
	Map::GetInstance()->GetElement()->GetSize(&rows, &cols);
	int texturesize=256;
	CString map_texture_path;
	int xblock,yblock;
	xblock=img->GetWidth()/cols;
	yblock=img->GetHeight()/rows;
	
	char rowchar,colchar;
	BYTE currow,curcol;
	Image oimg;
	for(currow=0;currow<rows;currow++)
		for(curcol=0;curcol<cols;curcol++)
		{
			rowchar='A'+currow;
			colchar='A'+curcol;
			int bltlocx,bltlocy;
			bltlocx=((cols-1)-curcol)*xblock;
			bltlocy=((rows-1)-currow)*yblock;
			
			map_texture_path.Format("Content\\Textures\\Maps\\%s\\%c%c\\%s_%c%c_0_0000.png",MapName,rowchar,colchar,MapName,rowchar,colchar);
			if(!gos_DoesFileExist(map_texture_path))
			{
				map_texture_path.Format("Content\\Textures\\Maps\\%s\\%c%c\\%s_%c%c_0_0000.tga",MapName,rowchar,colchar,MapName,rowchar,colchar);
				if(gos_DoesFileExist(map_texture_path))
				{
					oimg.LoadTga((char *)(LPCSTR)map_texture_path);
				}
				else
				{
					PAUSE(("Map Texture %s Missing",(char *)(LPCSTR)map_texture_path));
				}
			}
			else
			{
				oimg.LoadPng((char *)(LPCSTR)map_texture_path);
			}
			img->Blt(oimg,
				CRect(bltlocx,bltlocy,bltlocx+xblock,bltlocy+yblock),
				CRect(0,0,texturesize,texturesize));
		}
		
		img->AutoAdjust();
		
}

Point3D ObjectManager::BuildHFFromMap(Image *img)
{
	Verify(IsLoaded());
	int imgxlen,imgylen;
	imgxlen=img->GetWidth();
	imgylen=img->GetHeight();
	int imgsize=imgxlen*imgylen;
	Scalar *fmap=new Scalar[imgsize];
	int x,y;
	Scalar fx,fz,xinc,zinc,hmin,hmax,val;
	xinc=MapSize.x/img->GetWidth();
	zinc=MapSize.z/img->GetHeight();
	hmin=hmax=ComputeTerrainElevation(0,0,NULL);
	
	for(y=0,fz=MapSize.z*0.5f-zinc*0.5f;y<imgsize;fz-=zinc,y+=imgxlen)
		for(x=0,fx=MapSize.x*0.5f-xinc*0.5f;x<imgxlen;fx-=xinc,x++)
		{
			val=ComputeTerrainElevation(fx,fz,NULL);
			if(val<hmin) hmin=val;
			if(val>hmax) hmax=val;
			fmap[x+y]=val;
			Verify(fmap[x+y]<COLSTART);
		}
		
		BYTE *dtp=img->Lock();
		ImgRGBColor col;
		Scalar mval=255/(hmax-hmin);
		int imgy,imgx;
		BYTE ival;
		
		for(y=imgy=0;y<imgsize;imgy+=imgxlen*3,y+=imgxlen)
			for(imgx=x=0;x<imgxlen;x++,imgx+=3)
			{
				ival=(BYTE)Round((fmap[x+y]-hmin)*mval);
				
				dtp[imgx+imgy+0]=ival;
				dtp[imgx+imgy+1]=ival;
				dtp[imgx+imgy+2]=ival;
				//	col.r=col.g=col.b=(int)Round((fmap[x+y]-hmin)*mval);
				//	((RGBPixel *)(dtp+x+imgy))->Set(col,img->Mask);
			}
			img->UnLock();
			
			delete fmap;
			return Point3D(MapSize.x/imgxlen,(hmax-hmin)/256,MapSize.z/imgylen);
}

void ObjectManager::MakeSlopeMap(Image *img,Point3D map_scale)
{
	
	img->MakeContourMap(map_scale.x,
		map_scale.z,
		map_scale.y,
		10,
		ImgRGBColor(64,64,64),
		ImgRGBColor(200,100,0),ImgRGBColor(0,255,0)
		);
	img->MakeRGB24();
}



void MakeMissionNight(bool night);
bool IsMissionNight();





bool ObjectManager::OpenMission(CString missionFileName,bool night)
{
	
	if(IsLoaded()) 
	{
		if(!CloseMission()) return false;
	}
	Verify(!::MissionLoaded);
	Verify(!IsLoaded());
	Check_Object(ResourceManager::Instance);
	
	
	if(NeedResourceBuild)
	{
		BuildResources();
		
	}
	
	Environment.HookGetFile = Application::GetFileForGOS;
	Environment.HookDoesFileExist = Application::FindFileForGOS;
	
	
	Check_Object(Application::GetInstance());
	CString game_name=missionFileName;
	game_name=game_name.Left(game_name.ReverseFind('.'));
	game_name=game_name.Mid(game_name.ReverseFind('\\')+1);
	
	((MWApplication *)Application::GetInstance())->m_isNight=night;
	
	if( missionFileName.Find("Content") != -1)
	{
		DynamicMemoryStream request_vehicle_stream;
		
		
		bool custom = false;
		request_vehicle_stream.WriteBytes(&custom, 1);
		short file_id = 0;
		short record_id = 0;
		request_vehicle_stream.WriteBytes(&file_id,   4);
		request_vehicle_stream.WriteBytes(&record_id, 4);
		
		
		
		MWApplication::GetInstance()->SetMissionName(missionFileName);
		
		request_vehicle_stream.Rewind();
		
		// request our mech...
		//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), MWApplication::RequestPlayerVehicleMessageID, &request_vehicle_stream, true);
		//Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), MWApplication::ReadyToLaunchMessageID, NULL, true);
		
		MWApplication::GetInstance()->RequestPlayerVehicleMessageHandler(Connection::Server->GetID(), &request_vehicle_stream);
		MWApplication::GetInstance()->ReadyToLaunchMessageHandler(Connection::Server->GetID(), NULL);
		
		MWApplication::GetInstance()->LaunchGame();
		Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), MWApplication::ClientLoadedMessageID, NULL, true);
		
		Check_Object(EntityManager::GetInstance());
		EntityManager::GetInstance()->SuspendExecution();
		
		
		// This is bad since the map isn't guaranteed to be loaded until
		// the application enters into the running state.
		
		// but we can work around this! 
		
		while (Network::GetInstance()->RouteLocalPacket())
		{
		}
		
		
		Check_Object(Map::GetInstance());
		ChainIteratorOf<Entity *> iterator(&Map::GetInstance()->childEntityChain);
		Entity* entity;
		
		CString game_base_path(game_name),contents_path;
		game_base_path=game_base_path.Left(game_base_path.ReverseFind('.'));
		contents_path=game_base_path+".contents";
		Stuff::NotationFile contentsfile((LPCSTR)contents_path);
		
		while((entity = iterator.ReadAndNext()) != NULL)
		{
			if(entity->GetPropType() == Entity::MapPropType)
			{
				EntityManager::GetInstance()->GetNameSocket()->AddValue(entity, entity->instanceName);
			}
		}
	}
	ClearModifyFlags();
	SourceMission="";
	GeneralEventQueue::Instance->ProcessAllEvents();
	RemoveEntityFromNameTable(Player::GetInstance()->vehicle);	
	
	::MissionLoaded=true;	
	MapLoaded=true;
	return true;
}



bool ObjectManager::CloseMission()
{
	if(!::MissionLoaded) return true;
	Check_Object(Application::GetInstance());
	ClipBoard.DeleteAllObjects();
	if(UndoMan) {delete UndoMan; UndoMan=NULL;}
	Dissociate();
	DeleteAllObjects();
	ObjectiveList.Dissociate();
	ObjectiveList.DeleteAllObjects();
	MapName="";
	//	NameManager::GetInstance()->RemoveString(Name);
	Name="";

	for(int i=0;i<GT_TOTALGAMES;i++)
		MPGames[i]=MPGame();

	//	try
	{
		Application::GetInstance()->StopGame();
		Verify(!Network::GetInstance());
		GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
		Check_Object(Network::GetInstance());
		delete gosFX::EffectLibrary::Instance;
		gosFX::EffectLibrary::Instance=NULL;
		ResourceManager::Instance->CloseAllButCore();
		MapLoaded=false;
		::MissionLoaded=false;
		
	}
	//	catch(...)
	{
		//	return false;
	}
	
	return true;
}

void ObjectManager::SaveMission(CString fname,bool textout)
{
	
	
	SetName(fname); 
	SaveMission(textout);
	
	/*
	CString old_name=GetName();
	SetName(fname); 
	CString mis_name=GetName();
	CString mis_res_name;
	mis_res_name.Format("Resource\\UserMissions\\%s.mw4",mis_name);
	ResourceFile *new_mis_file=ResourceManager::Instance->GetResourceFile(MissionResourceFileID);
	new_mis_file->SaveAs(mis_res_name);
	CloseMission();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s\\%s.Instance",mis_name,mis_name);
	OpenMission(mis_path);
	SourceMission=old_name;
	SaveMission(textout);
	*/
}


void ObjectManager::SaveMission(bool textout)
{
	Environment.HookGetFile = Adept::Tool::GetFileForGOS;
	Environment.HookDoesFileExist = Adept::Tool::FindFileForGOS;
	
	if((SourceMission!="" && !gos_DoesFileExist("Content\\Missions\\"+SourceMission))) 
	{
	ClearModifyFlags();
	MessageBox(NULL,"This Mission is based on a mission the does not exist on disk in text format, it cannot be saved","Save Error",MB_OK|MB_ICONHAND);
	return;
	}
	else if(SourceMission=="" && !gos_DoesFileExist("Content\\Missions\\"+GetName()))
	{
	ClearModifyFlags();
	MessageBox(NULL,"A Mission cannot be saved unless it orginated from text","Save Error",MB_OK|MB_ICONHAND);
	return;
	}


	if(!IsLoaded()) return;
	Check_Object(Mission::GetInstance());
	Check_Object(Application::GetInstance());
	Check_Object(Map::GetInstance());
	Check_Object(NameTable::GetInstance());

	CString msg;
	if(AddEssentialObjects(msg))
	{
	MessageBox(NULL,msg,"Mission Modified",MB_OK);
	}

	CString mis_res_name;
	mis_res_name.Format("Resource\\UserMissions\\%s.mw4",GetName());
	
	Stuff::MString missionname = (const char *)mis_res_name;
	if (MWApplication::TranslateMissionNameIfNecessary(missionname))
	{
		mis_res_name = (const char *)missionname;
	}
	
	
	SetMissionScriptName("Content\\Missions\\"+GetName()+"\\Scripts\\"+GetName()+".abl");
	
	ResourceFile *new_mis_file=ResourceManager::Instance->GetResourceFile(MissionResourceFileID);
	new_mis_file->SaveAs(mis_res_name);
	
	if(textout)
	{
		CString mis_name=GetName();
		CString mis_path;
		mis_path.Format("Content\\Missions\\%s",mis_name);
		CreateDirectory(mis_path,NULL);
		CreateDirectory(mis_path+"\\Scripts",NULL);
		CreateDirectory(mis_path+"\\DropZones",NULL);
		CreateDirectory(mis_path+"\\Paths",NULL);
		
		//Copy Default Script
		CString script_name;
		script_name.Format("%s\\scripts\\%s.abl",mis_path,mis_name);
		if(!gos_DoesFileExist(script_name))
		{
			if(SourceMission=="") 
				CopyFile("Content\\Missions\\EditorTemplate\\Scripts\\EditorTemplate.ABL",script_name,NULL);
			else 
				CopyFile("Content\\Missions\\"+SourceMission+"\\Scripts\\"+SourceMission+".ABL",script_name,NULL);
		}
		
		script_name.Format("%s\\scripts\\player.abl",mis_path,mis_name);
		if(!gos_DoesFileExist(script_name))
		{
			if(SourceMission=="") 
				CopyFile("Content\\Missions\\EditorTemplate\\Scripts\\player.ABL",script_name,NULL);
			else 
				CopyFile("Content\\Missions\\"+SourceMission+"\\Scripts\\player.ABL",script_name,NULL);
		}
		
		//Copy Default Audio
		CString audio_name;
		audio_name.Format("%s\\%s.sounds",mis_path,mis_name);
		if(!gos_DoesFileExist(audio_name))
		{
			if(SourceMission=="") 
				CopyFile("Content\\Missions\\EditorTemplate\\EditorTemplate.sounds",audio_name,NULL);
			else 
				CopyFile("Content\\Missions\\"+SourceMission+"\\"+SourceMission+".sounds",audio_name,NULL);
		}
		
		//Copy Default Lights
		CString lights_name;
		
		lights_name.Format("%s\\%s.lights",mis_path,mis_name);
		if(!gos_DoesFileExist(lights_name))
		{
			if(SourceMission=="") 
				CopyFile("Content\\Missions\\EditorTemplate\\EditorTemplate.lights",lights_name,NULL);
			else 
			{
				CopyFile("Content\\Missions\\"+SourceMission+"\\"+SourceMission+".lights",lights_name,NULL);

				NotationFile lights_file(lights_name);
				NotationFile::PageIterator *pages=lights_file.MakePageIterator();
				Page *page;
				
				while(page=pages->ReadAndNext())
				{
				Note *note=page->FindNote("MapName");
				if(note)
				{
				const char *str;
				note->GetEntry(&str);
				CString lnt=str;
				CString new_rname="Content\\Missions\\"+mis_name+"\\"+mis_name+".raw";
				CopyFile(lnt,new_rname,NULL);
				note->SetEntry(new_rname);
				}
				}
				lights_file.Save();
			}
		}
		
		//Copy Night Lights
		lights_name.Format("%s\\%snight.lights",mis_path,mis_name);
		if(!gos_DoesFileExist(lights_name))
		{
			if(SourceMission=="") 
				CopyFile("Content\\Missions\\EditorTemplate\\EditorTemplatenight.lights",lights_name,NULL);
			else 
			{
				CopyFile("Content\\Missions\\"+SourceMission+"\\"+SourceMission+"night.lights",lights_name,NULL);

				NotationFile lights_file(lights_name);
				NotationFile::PageIterator *pages=lights_file.MakePageIterator();
				Page *page;
				
				while(page=pages->ReadAndNext())
				{
				Note *note=page->FindNote("MapName");
				if(note)
				{
				const char *str;
				note->GetEntry(&str);
				CString lnt=str;
				CString new_rname="Content\\Missions\\"+mis_name+"\\"+mis_name+".raw";
				CopyFile(lnt,new_rname,NULL);
				note->SetEntry(new_rname);
				}
				}
				lights_file.Save();

			}
		}
		
		
		SaveOverViewMap("Resource\\UserMissions\\"+GetName()+".tga",CSize(112,112));
		SaveContentsTextFile();
		SaveNameTable();
		SaveRailGraph();
		SaveBounds();
		SaveInstanceTextFile();
		SaveDataTextFile();
		SaveLightsTextFile();
		SaveBuildFile();
		UpdateNFOFile();
		//		if(!InBuildFile()) AddToBuildFile();
		//		Verify(InBuildFile());
		
	}
	else
	{
		STOP(("Unimplemented"));
	}
	
	CString inifilename("Content\\Missions\\"+GetName()+"\\"+GetName()+".ini");
	NotationFile info_file((LPCSTR)(inifilename));
	MakeFileWriteable(inifilename);
	SaveTextInfo(&info_file);
	info_file.Save();
	
	NeedResourceBuild=true;
	SourceMission="";
	ClearModifyFlags();
//	DeleteFile("Resource\\UserMissions\\"+GetName()+".mw4");
	DeleteFile("Resource\\UserMissions\\"+GetName()+".dep");
	Environment.HookGetFile = Application::GetFileForGOS;
	Environment.HookDoesFileExist = Application::FindFileForGOS;
	
	
}

void ObjectManager::SaveBuildFile()
{
	CString mis_name=GetName();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	//Make Build File
	CString bf_name;
	bf_name.Format("%s\\%s.build",mis_path,mis_name);
	MakeFileWriteable(bf_name);
	CString page_name;
	
	NotationFile build_file((LPCSTR)bf_name);
	Page *page;
	
	NotationFile::PageIterator *pages=build_file.MakePageIterator();
	page=pages->ReadAndNext();
	if(page!=NULL)
	{
		page_name=page->GetName();
	}
	else
	{
		page_name="Resource\\UserMissions\\"+mis_name+".mw4";
	}
	
	build_file.DeleteAllPages();
	page=build_file.SetPage(page_name);
	Check_Object(page);
	
	CString hint_path;
	hint_path.Format("%s\\%s.hint",mis_path,mis_name);
	
	page->SetEntry("texturepool",hint_path);
	CString inst_name;
	inst_name.Format("Content\\Missions\\%s\\%s.instance",mis_name,mis_name);
	page->SetEntry("Instance",(char *)(LPCSTR)inst_name);
	
	page->AppendEntry("directory","Content\\Missions\\"+mis_name+"\\scripts");
	page->SetEntry("Soundpool","Content\\Missions\\"+mis_name+"\\"+mis_name+".sounds");
	
	
	build_file.Save();
	
	
	
}


void SetMapTo(const CString& map_name)
{
	CString map_res_name;
	map_res_name.Format("Resource\\Maps\\%s.mw4",map_name);
	Resource deps(ResourceID(MissionResourceFileID, ResourceID::BuildDependenciesRecordID));
	Verify(deps.DoesResourceExist());
	DynamicMemoryStream stream;
	MString map_dep_name_m = (LPCSTR)map_res_name;
	stream << (char*)map_dep_name_m;
	stream << '\0';
	Stuff::FileDependencies build_dependancies;
	build_dependancies.AddDependency("");
	//	deps.Save(&stream,NULL);
	deps.Save(&stream,&build_dependancies);
	
}

void ObjectManager::NewMission(CString mis_name,CString map_name)
{
	if(IsLoaded()) 
		CloseMission();
	
	CString template_mis_name="editortemplate";
	CString mis_res_name;
	CString temp_res_name;
	
	mis_res_name.Format("Resource\\UserMissions\\%s.mw4",mis_name);
	Stuff::MString missionname = (const char *)mis_res_name;
	if (MWApplication::TranslateMissionNameIfNecessary(missionname))
	{
		mis_res_name = (const char *)missionname;
	}
	
	temp_res_name.Format("Resource\\Missions\\%s.mw4",template_mis_name);
	missionname = (const char *)temp_res_name;
	if (MWApplication::TranslateMissionNameIfNecessary(missionname))
	{
		temp_res_name = (const char *)missionname;
	}
	
	
	ResourceFile *new_mis_file=ResourceManager::Instance->OpenResourceFile(
		(LPCSTR)temp_res_name,NULL,MissionResourceFileID,VER_CONTENTVERSION,true,false);
	
	SetMapTo(map_name);
	
	{
		CString old_mission_name=template_mis_name;
		CString new_mission_name=mis_name;
		CString old_name,resource_name;
		
		Resource mission_resource;
		mission_resource.First(new_mis_file);
		//Skip the first one since it is the dependancies structure
		mission_resource.ReadAndNext();
		while(mission_resource.ReadAndNext())
		{
			mission_resource.LoadData();
			resource_name=mission_resource.GetName();
			resource_name.MakeLower();
			resource_name.Replace(old_mission_name,new_mission_name);
			mission_resource.ChangeName(resource_name);
		}
	}
	
	new_mis_file->SaveAs(mis_res_name);
	
	delete ResourceManager::Instance->GetResourceFile(MissionResourceFileID);
	
	
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s\\%s.Instance",mis_name,mis_name);
	OpenMission(mis_path);
	SourceMission="EditorTemplate";
	MPGames[GT_SinglePlayer].Supported=true;
	
}


void SetMissionName(CString old_mission_name,CString new_mission_name)
{
	old_mission_name.MakeLower();
	new_mission_name.MakeLower();
	CString mis_res_name;
	mis_res_name.Format("Resource\\UserMissions\\%s.mw4",old_mission_name);
	Stuff::MString missionname = (const char *)mis_res_name;
	if (MWApplication::TranslateMissionNameIfNecessary(missionname))
	{
		mis_res_name = (const char *)missionname;
	}
	
	
	ResourceFile *new_mis_file=ResourceManager::Instance->GetResourceFile(MissionResourceFileID);
	CString old_name,resource_name;
	ResourceID gmid,dlid,rid;
	Resource *dlres;
	Resource *gmres;
	
	dlres=Mission::GetInstance()->GetDataListResource();
	dlres->LoadData();
	resource_name=dlres->GetName();
	resource_name.MakeLower();
	resource_name.Replace(old_mission_name,new_mission_name);
	dlres->ChangeName(resource_name);
	dlid=dlres->GetResourceID();
	
	gmres=Mission::GetInstance()->GetGameModelResource();
	gmres->LoadData();
	resource_name=gmres->GetName();
	resource_name.MakeLower();
	resource_name.Replace(old_mission_name,new_mission_name);
	gmres->ChangeName(resource_name);
	gmid=gmres->GetResourceID();
	
	Resource mission_resource;
	mission_resource.First(new_mis_file);
	//Skip the first one since it is the dependancies structure
	mission_resource.ReadAndNext();
	while(mission_resource.ReadAndNext())
	{
		rid=mission_resource.GetResourceID();
		if((rid!=gmid) && (rid!=dlid))
		{
			mission_resource.LoadData();
			resource_name=mission_resource.GetName();
			resource_name.MakeLower();
			resource_name.Replace(old_mission_name,new_mission_name);
			mission_resource.ChangeName(resource_name);
		}
	}
	
	
	MWApplication::GetInstance()->SetMissionName(new_mission_name);
}

void ObjectManager::SaveLightsTextFile()
{
	CString mis_name=GetName();
	
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	// Save Contents File
	CString lights_path;
	
	if(IsMissionNight())
		lights_path.Format("%s\\%snight.lights",mis_path,mis_name);
	else
		lights_path.Format("%s\\%s.lights",mis_path,mis_name);
	
	MakeFileWriteable(lights_path);
	NotationFile lights_file(lights_path);
	lights_file.DeleteAllPages();
	
	ChainIteratorOf<gosFX::Light*> lightiterator(&Mission::GetInstance()->m_staticLights);
	
	int lcntr=0;
	CString lname;
	
	gosFX::Light* gamelight;
	
	lightiterator.First();
	while((gamelight = lightiterator.ReadAndNext()) != NULL)
	{
		lname.Format("LookUpLight");
		if(gamelight->m_light->GetLightType()==MLRLight::LookUpLight)
		{
			Page *page=lights_file.SetPage(lname);
			Check_Object(page);
			gamelight->m_light->Write(page);
		}
	}
	
	
	lightiterator.First();
	while((gamelight = lightiterator.ReadAndNext()) != NULL)
	{
		switch (gamelight->m_light->GetLightType())
		{
		case MLRLight::AmbientLight:
			lname.Format("Ambient_Light%04i",lcntr++);
			break;
		case MLRLight::InfiniteLight:
			lname.Format("Infinite_Light%04i",lcntr++);
			break;
		case MLRLight::PointLight:
			lname.Format("Point_Light%04i",lcntr++);
			break;
		case MLRLight::SpotLight:
			lname.Format("Spot_Light%04i",lcntr++);
			break;
		case MLRLight::LookUpLight:
			break;
		default:
			lname.Format("Generic_Light%04i",lcntr++);
		}
		if(gamelight->m_light->GetLightType()!=MLRLight::LookUpLight)
		{
			Page *page=lights_file.SetPage(lname);
			Check_Object(page);
			gamelight->m_light->Write(page);
		}
	}
	
	
	lights_file.Save();
	
}


int EntityCompare(const void *elem1, const void *elem2 )
{
	Entity *obj1,*obj2;
	obj1=*((Entity **)elem1);
	obj2=*((Entity **)elem2);
	Check_Object(obj1);
	Check_Object(obj2);
	
	if(obj1->GetClassID()==obj2->GetClassID())
	{
		if(obj1->IsDerivedFrom(NavPoint::DefaultData)) return 0; //Don't Reorder NavPoints
		
		CString model1,model2;
		int val=strcmpi(obj1->GetModelName(),obj2->GetModelName());
		if(val==0)
		{
			
			if((char *)(obj1->instanceName)==NULL && (char *)(obj2->instanceName)==NULL) return 0;
			if((char *)(obj1->instanceName)==NULL ) return -1;
			if((char *)(obj2->instanceName)==NULL ) return 1;
			return strcmpi(obj1->instanceName,obj2->instanceName);
			
		}	
		else 
			return val;
	}
	else
	{
		return obj1->GetClassID()<obj2->GetClassID()?-1:1;
	}
}

void ObjectManager::SaveContentsTextFile()
{
	CString mis_name=GetName();
	
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	// Save Contents File
	CString contents_path;
	contents_path.Format("%s\\%s.contents",mis_path,mis_name);
	MakeFileWriteable(contents_path);
	NotationFile contents_file(contents_path);
	contents_file.DeleteAllPages();
	Page *inc_page=contents_file.SetPage(NULL);
	Check_Object(inc_page);
	//	inc_page->SetEntry("!Include","Content\\Defines\\MissionLang.defines");
	inc_page->SetEntry("!concatenate",false);
	inc_page->SetEntry("!preservecase",true);
	
	/*
	CString date;
	CTime tme=CTime::GetCurrentTime();
	inc_page->SetEntry("EditorVersion",VER_PRODUCTVERSION_STR);
	inc_page->SetEntry("DateSaved",	tme.Format("%A %B %d, %Y %H:%M:%S"));
	inc_page->SetEntry("TimeStamp",	tme.GetTime());
	*/
	
	CString path_path;
	path_path.Format("%s\\Paths",mis_path);
	gos_CreateDirectory(path_path);
	
	CString dzone_path;
	dzone_path.Format("%s\\DropZones",mis_path);
	gos_CreateDirectory(dzone_path);
	
	
	ChainIteratorOf<Entity *> iterator(&Map::GetInstance()->childEntityChain);
	Entity *entity;
	
	int list_size,cur_pos=0;
	list_size=iterator.GetSize();
	Entity **EntityList= new Entity*[list_size];
	
	iterator.First();
	while((entity = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(entity);
		EntityList[cur_pos++]=entity;
		Verify(cur_pos<=list_size);
	}
	
	Verify(cur_pos==list_size);
	
	qsort(EntityList,list_size,sizeof(Entity *),EntityCompare);
	
	for(cur_pos=0;cur_pos<list_size;cur_pos++)
	{
		entity=EntityList[cur_pos];
		Check_Object(entity);
		SPEW(("tsteinke","I don't like this, save should really happen in the object"));
		
		
		if (entity->IsDerivedFrom(Path::DefaultData))
		{
			CString path_name((char*)entity->instanceName);
			Page *entity_page = contents_file.AddPage(path_name);
			Check_Object(entity_page);
			entity->SaveInstanceText(entity_page);
			
			entity_page->SetEntry("Model","Misc\\Path\\Path.data");
			entity_page->SetEntry("ExecutionState","NeverExecuteState");
			entity_page->SetEntry("CollisionCallback","false");
			entity_page->SetEntry("CollideeType","Zone");
			entity_page->SetEntry("CollisionMask",-1);
			
			CString path_filename,path_shortpath;
			path_shortpath.Format("Paths\\%s.contents",path_name);
			path_filename.Format("%s\\%s.contents",path_path,path_name);
			entity_page->SetEntry("PathPoints",path_shortpath);
			
			MakeFileWriteable(path_filename);
			NotationFile path_notation_file(path_filename);
			path_notation_file.DeleteAllPages();
			Page *path_page = path_notation_file.SetPage("Path");
			
			Path* path;
			path = Cast_Object(Path*,entity);
			
			CString point_name;
			for(int i=0;i<path->pathPoints.size();i++)
			{
				point_name.Format("Point%i",i+1);
				path_page->SetEntry(point_name,path->pathPoints[i]);
			}
			
			path_notation_file.Save();
		}
		else if(entity->IsDerivedFrom(DropZone::DefaultData))
		{	
			CString dzone_name((char*)entity->instanceName);
			Page *entity_page = contents_file.AddPage(dzone_name);
			Check_Object(entity_page);
			
			
			entity_page->SetEntry("Model","Misc\\DropZone\\DropZone.data");
			entity_page->SetEntry("ExecutionState","NeverExecuteState");
			entity_page->SetEntry("TileBound","false");
			Point3D local_translation(entity->GetLocalToParent());
			entity_page->SetEntry("Translation", local_translation);
			YawPitchRoll rotation_value(entity->GetLocalToParent());
			entity_page->SetEntry("Rotation", rotation_value);
			const char *alignment_text;
			alignment_text = Entity::AlignmentAsciiToText(entity->GetAlignment());
			entity_page->SetEntry("Alignment", alignment_text);
			
			CString dzone_filename,dzone_shortpath;
			dzone_shortpath.Format("DropZones\\%s.contents",dzone_name);
			dzone_filename.Format("%s\\%s.contents",dzone_path,dzone_name);
			
			entity_page->SetEntry("DropPoints",dzone_shortpath);
			
			
			MakeFileWriteable(dzone_filename);
			NotationFile drop_notation_file(dzone_filename);
			drop_notation_file.DeleteAllPages();
			
			Page *drop_page = drop_notation_file.SetPage("DropPoints");
			Page *rot_page = drop_notation_file.SetPage("DropRots");
			
			Point3D point;
			YawPitchRoll rot;
			LinearMatrix4D mat;
			DropZone* drop=Cast_Object(DropZone*,entity);
			
			ChainIteratorOf<DropZone::MatrixPlug *> iterator(&drop->origDropMats);
			DropZone::MatrixPlug *drop_point;
			CString entry_name;
			int count = 1;
			while((drop_point = iterator.ReadAndNext()) != NULL)
			{	
				Check_Object(drop_point);
				entry_name.Format("Point%i",count);
				mat = drop_point->GetItem();
				point = (Point3D) mat;
				rot = (YawPitchRoll) mat;
				drop_page->SetEntry(entry_name, point);
				entry_name.Format("Rot%i",count);
				rot_page->SetEntry(entry_name, rot);
				count++;
			}
			drop_notation_file.Save();
			
		}
		else if (entity->GetPropType() == Entity::MissionPropType &&
			!entity->IsDerivedFrom(AI::DefaultData) )
		{
			Page *entity_page = contents_file.AddPage((char*)entity->instanceName);
			Check_Object(entity_page);
			
			entity->SaveInstanceText(entity_page);
		}
		
		}
		
		delete EntityList;
		
		
		// Save AI Drivers And Waypoints
		
		MWMap *mwmap_inst;
		AI *ai;
		mwmap_inst = Cast_Object (MWMap *,Map::GetInstance());
		ChainIteratorOf<AI *> ai_iterator(&mwmap_inst->m_executingAIs);
		ai_iterator.First();
		while((ai = ai_iterator.ReadAndNext()) != NULL)
		{
			Check_Object(ai);
			if (!ai->IsDerivedFrom (PlayerAI::DefaultData))
			{
				Page *page = contents_file.AddPage((char*)ai->instanceName);
				Check_Object(page);
				ai->SaveInstanceText(page);
			}
		}
		
		contents_file.Save();
}


void ObjectManager::SaveInstanceTextFile()
{
	
	CString mis_name=GetName();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	{
		CString instance_path;
		instance_path.Format("%s\\%s.instance",mis_path,mis_name);
		
		MakeFileWriteable(instance_path);
		NotationFile instance_file(instance_path);
		Page *mission_page = instance_file.SetPage(mis_name);
		Mission::GetInstance()->SaveInstanceText(mission_page);
		
		instance_file.Save();
	}	
	CString hint_path;
	hint_path.Format("%s\\%s.hint",mis_path,mis_name);
	
	MakeFileWriteable(hint_path);
	NotationFile hint_file(hint_path);
	CString hint_page_name;
	hint_file.DeleteAllPages();
	
	hint_page_name.Format("Resource\\UserMissions\\%s.mw4",mis_name);
	Page *hint_page;
	
	// put texture pages here
	
	CString sky_name,str;
	CString texture_name;
	char c[6]="fblru";
	int miplevel,clev;
	
	sky_name=DaySkyName();
	bool isnight;
	
	sky_name=sky_name.Mid(sky_name.Find('\\')+1);
	str=sky_name.Mid(sky_name.ReverseFind('_')+1);
	isnight=(!str.CompareNoCase("night") || !str.CompareNoCase("storm"));
	
	for(clev=0;clev<5;clev++)
		for(miplevel=1;miplevel<=5;miplevel++)
		{
			if(isnight)
				texture_name.Format("Skyn%c%c%c%i",sky_name[0],sky_name[sky_name.Find('0')+1],c[clev],miplevel);
			else
				texture_name.Format("Sky%c%c%c%i",sky_name[0],sky_name[sky_name.Find('0')+1],c[clev],miplevel);
			hint_page=hint_file.SetPage(texture_name);
			hint_page->SetEntry("mipmap","explicit");
			hint_page->SetEntry("nogamma",false);
			hint_page->SetEntry("memory","default");
			hint_page->SetEntry("blueisalpha",false);
			hint_page->SetEntry("format","Solid");
			hint_page->SetEntry("pinkisalpha",false);
			hint_page->SetEntry("mipfilter","box");
			hint_page->SetEntry("reloadfromdisk",true);
			hint_page->SetEntry("pageout","default");
			hint_page->SetEntry("readonly",true);
			hint_page->SetEntry("resourcify",true);
		}	
		
		if(DaySkyName().CompareNoCase(NightSkyName()))
		{
			sky_name=NightSkyName();
			if(sky_name!="")
			{
			sky_name=sky_name.Mid(sky_name.Find('\\')+1);
			str=sky_name.Mid(sky_name.ReverseFind('_')+1);
			isnight=(!str.CompareNoCase("night") || !str.CompareNoCase("storm"));
			
			sky_name=sky_name.Mid(sky_name.Find('\\')+1);
			for(clev=0;clev<5;clev++)
				for(miplevel=1;miplevel<=5;miplevel++)
				{
					if(isnight)
						texture_name.Format("Skyn%c%c%c%i",sky_name[0],sky_name[sky_name.Find('0')+1],c[clev],miplevel);
					else
						texture_name.Format("Sky%c%c%c%i",sky_name[0],sky_name[sky_name.Find('0')+1],c[clev],miplevel);
					hint_page=hint_file.SetPage(texture_name);
					hint_page->SetEntry("mipmap","explicit");
					hint_page->SetEntry("nogamma",false);
					hint_page->SetEntry("memory","default");
					hint_page->SetEntry("blueisalpha",false);
					hint_page->SetEntry("format","Solid");
					hint_page->SetEntry("pinkisalpha",false);
					hint_page->SetEntry("mipfilter","box");
					hint_page->SetEntry("reloadfromdisk",true);
					hint_page->SetEntry("pageout","default");
					hint_page->SetEntry("readonly",true);
					hint_page->SetEntry("resourcify",true);
				}	
			}	
		}	
		
		hint_file.Save();
		//	mission_page->SetEntry("!Include",hint_path);
}

void ObjectManager::SaveBounds()
{
	CString mis_name=GetName();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	
	int i;
	//Save Mission Bounds
	FileStream mbound_file;	
	DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > mission_bound;
	Check_Pointer(MissionBound);
	MissionBound->GetBoundData(&mission_bound);
	for (i=0;i<mission_bound.GetLength();i++)
	{
		mission_bound[i].x += MapSize.x*0.5f;
		mission_bound[i].y += MapSize.z*0.5f;
		mission_bound[i].x *= Map::GetInstance()->GetColumnZoneScale();
		mission_bound[i].y *= Map::GetInstance()->GetRowZoneScale();
	}
	
	Mission::GetInstance()->SetMissionPolygon(mission_bound);
	CString mbound_filename=mis_path+"\\Mission.bounds";
	MakeFileWriteable(mbound_filename);	
	mbound_file.Open((LPCSTR)mbound_filename,FileStream::WriteOnly);
	MemoryStreamIO_Write(&mbound_file, &mission_bound);
	mbound_file.Close();
	
	//Save Warning Bounds
	FileStream wbound_file;	
	DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > warning_bound;
	Check_Pointer(WarningBound);
	WarningBound->GetBoundData(&warning_bound);
	for (i=0;i<warning_bound.GetLength();i++)
	{
		warning_bound[i].x += MapSize.x*0.5f;
		warning_bound[i].y += MapSize.z*0.5f;
		warning_bound[i].x *= Map::GetInstance()->GetColumnZoneScale();
		warning_bound[i].y *= Map::GetInstance()->GetRowZoneScale();
	}
	
	Mission::GetInstance()->SetWarningPolygon(warning_bound);
	CString wbound_filename=mis_path+"\\Warning.bounds";
	MakeFileWriteable(wbound_filename);	
	wbound_file.Open((LPCSTR)wbound_filename,FileStream::WriteOnly);
	MemoryStreamIO_Write(&wbound_file, &warning_bound);
	wbound_file.Close();
	
}

void ObjectManager::SaveNameTable()
{
	CString mis_name=GetName();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	//Save the NameTable
	CString table_path;
	table_path.Format("%s\\%s.table",mis_path,mis_name);
	MakeFileWriteable(table_path);	
	NotationFile table_file(table_path,NotationFile::Standard,true);
	table_file.DeleteAllPages();
	Page *page=table_file.SetPage(NULL);
	page->SetEntry("!preservecase",true);
	NameTable::GetInstance()->IsValid();
	NameTable::GetInstance()->SaveTable(&table_file);
	table_file.Save();
	
}

void ObjectManager::SaveRailGraph()
{
	CString mis_name=GetName();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	
	
	//Save the RailGraph
	CString graph_path,move_grid_path,rect_grid_path,air_move_path;
	graph_path.Format("%s\\%sGraph.data",mis_path,mis_name);
	move_grid_path.Format("%s\\%sMoveGrid.data",mis_path,mis_name);
	rect_grid_path.Format("%s\\%sRectGrid.data",mis_path,mis_name);
	air_move_path.Format("%s\\%sAirMoveGrid.data",mis_path,mis_name);
	NotationFile railgraph_file(graph_path);
	MakeFileWriteable(graph_path);	
	MakeFileWriteable(move_grid_path);	
	MakeFileWriteable(rect_grid_path);	
	MakeFileWriteable(air_move_path);	
	MW4AI::g_MissionGraph->DumpNotationFile (&railgraph_file,(LPCTSTR) move_grid_path,(LPCTSTR) rect_grid_path,(LPCTSTR) air_move_path);
	railgraph_file.Save();
	
	
}

void ObjectManager::SaveDataTextFile()
{
	CString mis_name=GetName();
	CString mis_path;
	mis_path.Format("Content\\Missions\\%s",mis_name);
	CString data_path;
	data_path.Format("%s\\%s.data",mis_path,mis_name);
	MakeFileWriteable(data_path);	
	NotationFile data_file(data_path);
	Page *page=data_file.SetPage("GameData");
	MisDat.SaveText(&data_file);
	data_file.Save();
}

bool ObjectManager::InBuildFile()
{
	CString missionName=GetName();
	CString missionPath = "Content\\Missions\\";
	missionPath += missionName;
	
	CString map_buildpath;
	CString map_shortpath;
	CString map_longpath;
	CString mission_instancepath;
	CString mission_buildpath;
	map_shortpath.Format("Maps\\%s\\%s.build",MapName,MapName);	
	mission_buildpath.Format("Missions\\%s\\%s.build",missionName,missionName);	
	mission_instancepath.Format("Missions\\%s\\%s.instance",missionName,missionName);	
	map_longpath="Content\\"+map_shortpath;
	
	////////////////////////////////////////////////////////////
	//	Enter the data in the build file
	
	
	////////////////////////////////////////////////////////////
	//	Enter the data in the build file
	Verify(gos_DoesFileExist(BUILDFILENAME));
	MakeFileWriteable(BUILDFILENAME);	
	
#ifdef USEEXTERNALLY
	
	NotationFile prop_file(BUILDFILENAME);
	Page *prop_page = prop_file.FindPage("");
	Check_Object(prop_page);
	Note *map_note = prop_page->FindNote(map_shortpath);
	
	NotationFile maps_file;
	if(!map_note) return false;
	map_note->GetEntry(&maps_file);
	Page *mission_page = maps_file.FindPage("");
	Check_Object(mission_page);
	if(mission_page->FindNote(mission_buildpath)) return true;
	
	
#else
	
	
	Stuff::NotationFile build_file(BUILDFILENAME);
	Page *texture_page = build_file.FindPage("");
	if (!texture_page) return false;
	Check_Object(texture_page);
	Page::NoteIterator *texture_notes = texture_page->MakeNoteIterator();
	Check_Object(texture_notes);
	Note *texture_note;
	while ((texture_note = texture_notes->ReadAndNext()) != NULL)
	{
		Check_Object(texture_note);
		NotationFile texture_file;
		texture_note->GetEntry(&texture_file);
		Page *core_page = texture_file.FindPage("");
		if (!core_page) return false;
		Check_Object(core_page);
		Page::NoteIterator *core_notes = core_page->MakeNoteIterator();
		Check_Object(core_notes);
		Note *core_note;
		while ((core_note = core_notes->ReadAndNext()) != NULL)
		{
			Check_Object(core_note);
			NotationFile core_file;
			core_note->GetEntry(&core_file);
			Page *props_page = core_file.FindPage("");
			if(!props_page) return false;
			Page::NoteIterator *prop_notes = core_page->MakeNoteIterator();
			Check_Object(prop_notes);
			Note *prop_note;
			while ((prop_note = prop_notes->ReadAndNext()) != NULL)
			{
				Check_Object(prop_note);
				NotationFile prop_file;
				prop_note->GetEntry(&prop_file);
				Page *props_page = prop_file.FindPage("");
				if (props_page)
				{
					Check_Object(props_page);
					Page::NoteIterator *props_notes = props_page->MakeNoteIterator();
					Check_Object(props_notes);
					Note *props_note;
					while ((props_note = props_notes->ReadAndNext()) != NULL)
					{
						Check_Object(props_note);
						NotationFile map_file;
						props_note->GetEntry(&map_file);
						Page *maps_page = map_file.FindPage("");
						Check_Object(maps_page);
						Page::NoteIterator *map_notes = maps_page->MakeNoteIterator();
						Check_Object(map_notes);
						Note *map_note;
						
						NotationFile mission_file;
						map_note=maps_page->FindNote(map_shortpath);
						if(!map_note) return false;
						
						map_note->GetEntry(&mission_file);
						
						Page *mission_page = mission_file.FindPage("");
						if(!mission_page) return false;
						
						if(mission_page->FindNote(mission_buildpath)) return true;
						
					}
				}
			}
		}
				}
	
#endif
	
	
	
	return false;
	
}

void ObjectManager::AddToBuildFile()
{
	CString missionName=GetName();
	CString missionPath = "Content\\Missions\\";
	missionPath += missionName;
	
	CString map_buildpath;
	CString map_shortpath;
	CString map_longpath;
	CString mission_instancepath;
	CString mission_buildpath;
	map_shortpath.Format("Maps\\%s\\%s.build",MapName,MapName);	
	mission_buildpath.Format("Missions\\%s\\%s.build",missionName,missionName);	
	mission_instancepath.Format("Missions\\%s\\%s.instance",missionName,missionName);	
	map_longpath="Content\\"+map_shortpath;
	
	
	
	////////////////////////////////////////////////////////////
	//	Enter the data in the build file
	Verify(gos_DoesFileExist(BUILDFILENAME));
	MakeFileWriteable(BUILDFILENAME);	
	
#ifdef USEEXTERNALLY
	NotationFile prop_file(BUILDFILENAME);
	Page *prop_page = prop_file.FindPage("");
	Check_Object(prop_page);
	Note *map_note = prop_page->FindNote(map_shortpath);
#else
	
	
	NotationFile build_file(BUILDFILENAME);
	Page *build_page = build_file.FindPage("");
	Check_Object(build_page);
	Note *texture_note = build_page->FindNote("textures.build");
	Check_Object(texture_note);
	
	NotationFile texture_file;
	texture_note->GetEntry(&texture_file);
	Page *texture_page = texture_file.FindPage("");
	Check_Object(texture_page);
	Note *core_note = texture_page->FindNote("core.build");
	Check_Object(core_note);
	
	NotationFile core_file;
	core_note->GetEntry(&core_file);
	Page *core_page = core_file.FindPage("");
	Check_Object(core_page);
	Note *prop_note = core_page->FindNote("props.build");
	Check_Object(prop_note);
	
	
	NotationFile prop_file;
	prop_note->GetEntry(&prop_file);
	Page *prop_page = prop_file.FindPage("");
	Check_Object(prop_page);
	Note *map_note = prop_page->FindNote(map_shortpath);
	
#endif
	
	
	NotationFile maps_file;
	if(!map_note)
	{
		map_note=prop_page->AddNote(map_shortpath);
		Check_Object(map_note);
	}
	else
	{
		Check_Object(map_note);
		map_note->GetEntry(&maps_file);
	}
	
	
	
	Page *mission_page;
	mission_page = maps_file.FindPage("");
	if(!mission_page) mission_page = maps_file.SetPage("");
	Check_Object(mission_page);
	
	NotationFile mission_note;
	mission_page->SetEntry(mission_buildpath,&mission_note);
	map_note->SetEntry(&maps_file);
	
#ifdef USEEXTERNALLY
	prop_file.Save();
#else
	prop_note->SetEntry(&prop_file);
	core_note->SetEntry(&core_file);
	texture_note->SetEntry(&texture_file);
	build_file.Save();
#endif
	
	NeedResourceBuild=true;
}

void ObjectManager::SetName( CString &name)
{
	if(GetName()!=name)
	{
		SetMissionName(GetName(),name);
		if(SourceMission=="") SourceMission=GetName();
		Name=name;
	}
	
}
/// Entity Manipulation
bool HasCollsion(Entity *entity)
{
	return (entity->GetSolidVolume()!=NULL || (entity->GetElement() && entity->GetElement()->m_localOBB.sphereRadius>0));
}

void BindEntity(Entity *entity)
{
	Check_Object(entity);
	
	entity->SyncMatrices(true);
	
	Entity::CollisionMask oldmask=entity->GetCollisionMask();
	if (oldmask == Entity::NeverCollidesMask)
		entity->SetCollisionMask(Entity::NeverCollidesMask);
	else
		entity->SetCollisionMask(Entity::EditorIsMovingFlag);
	Map::GetInstance()->UpdateZone(entity);
	entity->SetCollisionMask(oldmask);
	
	if(entity->IsDerivedFrom(Cultural::DefaultData) ) 
	{
		entity->BindToTile();
	}
	else
		if(!entity->IsMultiTile() )
		{
			if (entity->IsDerivedFrom(Building::DefaultData) ||  entity->IsDerivedFrom(Turret::DefaultData) )
			{
				entity->BindToTile();
			}
			else if (entity->IsDerivedFrom(Vehicle::DefaultData)) 
			{
				Vehicle *vech=Cast_Object(Vehicle *,entity);
				if(!vech->GetAI())
				{	
					//
					//------------------------------------------
					// If we are already tile bound, just return
					//------------------------------------------
					//
					if (!vech->IsTileBound())
					{
						//
						//---------------------------------------------------------------------
						// We are tile bound now, so find the tile through our element's parent
						//---------------------------------------------------------------------
						//
						ElementRenderer::Element *element = vech->GetElement();
						Check_Object(element);
						Zone *zone = Cast_Object(Zone*, element->GetParentElement());
						
						//
						//----------------------------------------------------------------
						// Unhook the collision, change the flag and hook it back up again
						//----------------------------------------------------------------
						//
						element->DetachFromParent();
						vech->replicatorFlags |= Entity::TileBoundFlag;
						vech->replicatorFlags &= ~Entity::ColliderFlag;
						element->AttachToParent(zone);
						element->Sync();
					}
				}
			}
			
		}
		
		
}

void UnBindEntity(Entity *entity)
{
	Check_Object(entity);
	if (entity->IsDerivedFrom(Building::DefaultData) || 
		entity->IsDerivedFrom(Turret::DefaultData) ||
		entity->IsDerivedFrom(Cultural::DefaultData) ||
		entity->IsDerivedFrom(Vehicle::DefaultData)
		)			
	{
		entity->BindToZone();
	}
	
	
}

void RemoveEntityFromNameTable(Entity *entity)
{
	Check_Object(entity);
	Check_Object(NameTable::GetInstance());
	
	NameTable::GetInstance()->RemoveEntry(entity->objectID);
	NameTable::GetInstance()->IsValid();
}

void AddEntityToNameTable(Entity *entity)
{
	Check_Object(entity);
	Check_Object(NameTable::GetInstance());
	
	if( entity->IsDerivedFrom(Turret::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::TurretArray);
	else if( entity->IsDerivedFrom(Cultural::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::CulturalArray);
	else if(entity->IsDerivedFrom(Vehicle::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::VehicleArray);
	else if(entity->IsDerivedFrom(Building::DefaultData) )
		NameTable::GetInstance()->AddEntry(entity, NameTable::BuildingArray);
	else if(entity->IsDerivedFrom(NavPoint::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::NavArray);
	else if(entity->IsDerivedFrom(DropZone::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::DropZoneArray);
	else if(entity->IsDerivedFrom(AI::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::AIArray);
	else if(entity->IsDerivedFrom(NonCom::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::BuildingArray);
	else if(entity->IsDerivedFrom(Path::DefaultData))
		NameTable::GetInstance()->AddEntry(entity, NameTable::PathArray);
	else
		NameTable::GetInstance()->AddEntry(entity, NameTable::DefaultArray);
	
	NameTable::GetInstance()->IsValid();
	
}

void MoveEntityTo(Entity *entity,Stuff::LinearMatrix4D &mat)
{
	Check_Object(entity);
	
	UnBindEntity(entity);
	entity->SetNewLocalToParent(mat);
	BindEntity(entity);
}

const char* GetEntityScriptName(Entity *entity)
{
	Check_Object(entity);
	if ((entity != 0) &&
		(entity->IsDerivedFrom(MWObject::DefaultData) == true))
	{
		MWObject* mwobject = Cast_Object(MWObject*,entity);
		
		if (mwobject->GetAI() != 0)
		{
			return (mwobject->GetAI()->GetScriptName());
		}
	}
	
	return (0);
}

void SetEntityScriptName(Entity *entity,char* script_name)
{
	Check_Object(entity);
	if ((entity != 0) &&
		(entity->IsDerivedFrom(MWObject::DefaultData) == true))
	{
		MWObject* mwobject = Cast_Object(MWObject*,entity);
		
		if (mwobject->GetAI() != 0)
		{
			mwobject->GetAI()->LoadScript(script_name);
		}
	}
}

void AddEntityAI(Entity *entity)
{
	Check_Object(entity);
	Check_Object(EntityManager::GetInstance());
	Check_Object(Map::GetInstance());
	
	// Add AIHere
	if (entity->IsDerivedFrom(MWObject::DefaultData) == true)
	{
		MWObject* mwobject = Cast_Object(MWObject*,entity);
		
		if (mwobject->GetAI() != 0)
		{
			Entity* ai_entity = mwobject->GetAI();
			
			EntityManager::GetInstance()->GetNameSocket()->AddValue(ai_entity,ai_entity->instanceName);
			
			AddEntityToNameTable(ai_entity);
			
			Check_Object(Map::GetInstance());
			Map::GetInstance()->AddChild(ai_entity);
			
			ai_entity->SetPropType(Entity::MissionPropType);
			ai_entity->SyncMatrices(true);
		}
	}
}

void RemoveEntityAI(Entity *entity)
{
	Check_Object(entity);
	Check_Object(EntityManager::GetInstance());
	Check_Object(Map::GetInstance());
	
	// Remove AI Here	
	if (entity->IsDerivedFrom(MWObject::DefaultData) == true)
	{
		MWObject* mwobject = Cast_Object(MWObject*,entity);
		
		if (mwobject->GetAI() != 0)
		{
			EntityManager::GetInstance()->GetNameSocket()->Remove(mwobject->GetAI());
			Map::GetInstance()->RemoveChild(mwobject->GetAI());
			RemoveEntityFromNameTable(mwobject->GetAI());
		}
	}
}

void UpdateCameraLights()
{
	ChainIteratorOf<gosFX::Light*> lights(&Mission::GetInstance()->m_staticLights);

	ElementRenderer::StateChange *view_states = 
		VideoRenderer::Instance->GetSceneCamera()->GetElement()->GetViewingStateChange();
	
	gosFX::Light *light;
	int i=0;
	while ((light = lights.ReadAndNext()) != NULL)
	{
		Verify(i < ELEMENTS(view_states->m_lights));
		view_states->m_lights[i++] = light->m_light;
	}
	view_states->m_lights[i] = NULL;

}

void AddLightToMap(gosFX::Light *light)
{
	Mission::GetInstance()->m_staticLights.Add(light);
	UpdateCameraLights();

}

void RemoveLightFromMap(gosFX::Light *light)
{
	Mission::GetInstance()->m_staticLights.Remove(light);
	UpdateCameraLights();
}


void AddEntityToMap(Entity *entity,LinearMatrix4D &mat)
{
	Check_Object(entity);
	Check_Object(Map::GetInstance());
	
	AddEntityToNameTable(entity);
	AddEntityAI(entity);
	Map::GetInstance()->AddChild(entity);
	entity->SetNewLocalToParent(mat);
	
	BindEntity(entity);
}

void RemoveEntityFromMap(Entity *entity)
{
	Check_Object(entity);
	Check_Object(Mission::GetInstance());
	Check_Object(NameTable::GetInstance());
	Check_Object(EntityManager::GetInstance());
	Check_Object(Map::GetInstance());
	
	UnBindEntity(entity);
	
	RemoveEntityAI(entity);
	Map::GetInstance()->RemoveChild(entity);
	RemoveEntityFromNameTable(entity);
}

void SetEntityName(Entity *entity,CString newname)
{
	Check_Object(entity);
	RemoveEntityFromNameTable(entity);
	entity->instanceName=(LPCSTR)newname;
	AddEntityToNameTable(entity);
}

bool HasSkin(Entity *entity)
{
	return entity->IsDerivedFrom(MWMover::DefaultData);
}

char GetEntitySkin(Entity *entity)
{
	Check_Object(entity);
	if(!HasSkin(entity)) return -1;
	
	MWMover *mwmover = Cast_Object(MWMover*,entity);
	return mwmover->GetSkinPrefix();
}

void SetEntitySkin(Entity *entity,char skin)
{
	Check_Object(entity);
	if(!HasSkin(entity)) return;
	
	MWMover *mwmover = Cast_Object(MWMover*,entity);
	mwmover->SetSkinPrefix(skin);
}
void MakeMissionNight(bool night)
{
	if(Mission::GetInstance()!=NULL)
	{
		if(night)
			Mission::GetInstance()->SetToNight();
		else
			Mission::GetInstance()->SetToDay();
	}
}

bool IsMissionNight()
{
	if(Mission::GetInstance()==NULL) return false;
	return Mission::GetInstance()->m_isNightMission;
}

void AdoptFogColors()
{
	const Mission::GameModel *model = Mission::GetInstance()->GetGameModel();
	Check_Object(model);
	
	ElementRenderer::StateChange *view_states = 
		VideoRenderer::Instance->GetSceneCamera()->GetElement()->GetViewingStateChange();
	
	if(IsMissionNight())
		view_states->SetFogColor(model->m_nightFogColor);
	else
		view_states->SetFogColor(model->m_fogColor);
	
}


void MakeFileWriteable(CString str)
{
	if(!gos_DoesFileExist(str)) return;
	if(gos_FileReadOnly(str))
	{
		
		gos_FileSetReadWrite(str);
		MessageBox(NULL,str +" has been made writeable and modified","File Modification",MB_OK);
	}
}

Scalar GetWaterLevel()
{
	return Map::GetInstance()->GetGameModel()->m_waterLevel;
}

void LoadSkys(CComboBox *ctrl)
{
	ctrl->ResetContent();
	
	Adept::Resource curres;
	curres.First(NULL);
	
	CString res_name,base_name,dir_name;
	
	while(curres.ReadAndNext())
	{
		res_name=(char *)curres.GetName();
		res_name.MakeLower();
		int sloc=res_name.Find("skies\\");
		
		if(sloc!=-1)
		{									// This is a Data File
			
			base_name=res_name.Mid(sloc+strlen("skies\\"));
			base_name=base_name.Left(base_name.ReverseFind('.'));
			int itm=ctrl->AddString(base_name);
			ctrl->SetItemDataPtr(itm,new CString(res_name));		
		}
	}
	
	
	
}

CString DaySkyName()
{
	Resource res(Mission::GetInstance()->skyResourceID);
	CString base_name=res.GetName();
	base_name=base_name.Mid(base_name.Find("skies\\")+strlen("skies\\"));
	base_name=base_name.Left(base_name.ReverseFind('.'));
	return base_name;
}

CString NightSkyName()
{
	if(Mission::GetInstance()->nightSkyResourceID!=ResourceID::Null)
	{
		Resource res(Mission::GetInstance()->nightSkyResourceID);
		CString base_name=res.GetName();
		base_name=base_name.Mid(base_name.Find("skies\\")+strlen("skies\\"));
		base_name=base_name.Left(base_name.ReverseFind('.'));
		return base_name;
	}
	else 
		return "";
}

void SetDaySky(CString str)
{
	Resource res(str);
	res.LoadData();
	ResourceID rid=res.GetResourceID();
	Mission::GetInstance()->SetDaySky(rid);
	
	
	
}

void SetNightSky(CString str)
{
	Resource res(str);
	res.LoadData();
	ResourceID rid=res.GetResourceID();
	Mission::GetInstance()->SetNightSky(rid);
	
	
}

float GetFarClip()
{
	return Mission::GetInstance()->GetGameModel()->m_farClip;
}

CZoneReport::BasicTypes CZoneReport::GetType(Entity *entity)
{
	if( entity->IsDerivedFrom(Turret::DefaultData)) return MR_TURRET;
	else if( entity->IsDerivedFrom(Cultural::DefaultData)) return MR_CULTURAL;
	else if( entity->IsDerivedFrom(Mech::DefaultData)) return MR_MECH;
	else if(entity->IsDerivedFrom(Vehicle::DefaultData)) return MR_VEHICLE;
	else if(entity->IsDerivedFrom(Building::DefaultData) ) return MR_BUILDING;
	else if(entity->IsDerivedFrom(NavPoint::DefaultData)) return MR_NAVPOINT;
	else if(entity->IsDerivedFrom(DropZone::DefaultData)) return MR_DROPZONE;
	else if(entity->IsDerivedFrom(AI::DefaultData)) return MR_AI;
	else if(entity->IsDerivedFrom(NonCom::DefaultData)) return MR_NONCOM;
	else if(entity->IsDerivedFrom(Path::DefaultData)) return MR_PATH;
	else if(entity->IsDerivedFrom(CameraShip::DefaultData)) return MR_CAMERASHIP;
	else if(entity->IsDerivedFrom(EffectGenerator::DefaultData)) return MR_EFFECT;
	else if(entity->IsDerivedFrom(Objective::DefaultData)) return MR_OBJECTIVE;
	//	else if(entity->IsDerivedFrom(MechWarrior4::SearchLight::DefaultData)) return MR_SEARCHLIGHT;
	else return MR_UNKNOWN;
	
}

bool CZoneReport::InZone(Adept::Entity *entity)
{
	Point3D trans;
	trans=entity->GetLocalToWorld();
	return (trans.x>=StartX && trans.z>=StartZ && trans.x<(StartX+c_ZoneSize) && trans.z<(StartZ+c_ZoneSize));
}

void CZoneReport::CountTypes(float x,float z)
{
	StartX=x;
	StartZ=z;
	
	ChainIteratorOf<Entity *> iterator(&Map::GetInstance()->childEntityChain);
	Entity *entity;
	
	
	for(int i=0;i<MR_TYPECOUNT;i++) BasicTypeCount[i]=0;
	
	int list_size,cur_pos=0;
	list_size=iterator.GetSize();
	Entity **EntityList= new Entity*[list_size];
	
	iterator.First();
	while((entity = iterator.ReadAndNext()) != NULL)
	{
		Check_Object(entity);
		if(InZone(entity))
			EntityList[cur_pos++]=entity;
		Verify(cur_pos<=list_size);
	}
	
	EntityCount=cur_pos;
	
	
	qsort(EntityList,EntityCount,sizeof(Entity *),EntityCompare);
	
	
	CString LastModel="";
	int model_total=0;
	int vio_total=0;
	model_total=0;
	for(cur_pos=0;cur_pos<EntityCount;cur_pos++)
	{
		entity=EntityList[cur_pos];
		Check_Object(entity);
		BasicTypeCount[GetType(entity)]++;
		
		if(LastModel.CompareNoCase(entity->GetModelName())) 
		{
			LastModel=entity->GetModelName();
			model_total++;
		}
		if(entity->IsMultiTile()) vio_total++;
	}
	
	Models=new ReportModel[model_total];
	Violators=new TileViolator[vio_total];
	
	ViolatorCount=0;
	UniqueModelCount=0;
	if(model_total>0)
		Models[UniqueModelCount].Name="";
	
	for(cur_pos=0;cur_pos<EntityCount;cur_pos++)
	{
		entity=EntityList[cur_pos];
		Check_Object(entity);
		
		if(entity->IsMultiTile()) 
		{
			if((char *)(entity->instanceName)!=NULL )
			{
				Violators[ViolatorCount++].Name=entity->instanceName;
			}	
			else
			{
				Violators[ViolatorCount++].Name="<UnNamed>";
			}
		}
		
		if(model_total>0)
		{
			if(UniqueModelCount<1 || (UniqueModelCount<model_total && Models[UniqueModelCount-1].Name.CompareNoCase(entity->GetModelName()))) 
			{
				Models[UniqueModelCount].Name=entity->GetModelName();
				Models[UniqueModelCount].Count=1;
				Models[UniqueModelCount].Type=GetType(entity);
				UniqueModelCount++;
				Verify(UniqueModelCount<=model_total);
				if(UniqueModelCount<model_total)
					Models[UniqueModelCount].Name="";
			}
			else
			{
				Verify(!Models[UniqueModelCount-1].Name.CompareNoCase(entity->GetModelName()));
				Models[UniqueModelCount-1].Count++;
			}
		}
	}
	
	Verify(UniqueModelCount==model_total);
	
	MWMap *mwmap_inst;
	AI *ai;
	mwmap_inst = Cast_Object (MWMap *,Map::GetInstance());
	ChainIteratorOf<AI *> ai_iterator(&mwmap_inst->m_executingAIs);
	ai_iterator.First();
	while((ai = ai_iterator.ReadAndNext()) != NULL)
	{
		Check_Object(ai);
		if (!ai->IsDerivedFrom (PlayerAI::DefaultData))
		{
			BasicTypeCount[MR_AI]++;
		}
	}
	
	//Count Types
	delete EntityList;
	
	
	
}

CString GetMissionName()
{
	CString	MissionName=MWApplication::GetInstance()->GetMissionName();
	MissionName=MissionName.Left(MissionName.ReverseFind('.'));	
	MissionName=MissionName.Mid(MissionName.ReverseFind('\\')+1);	
	return MissionName;
}

void CMissionReport::CountTypes()
{
	MissionName=MWApplication::GetInstance()->GetMissionName();
	MissionName=MissionName.Left(MissionName.ReverseFind('.'));	
	MissionName=MissionName.Mid(MissionName.ReverseFind('\\')+1);	
	
	BYTE rows, cols;
	Map::GetInstance()->GetElement()->GetSize(&rows, &cols);
	ZoneCount=rows*cols;
	
	ZoneRep=new CZoneReport[ZoneCount];
	
	int rinc,cinc;
	float rpos,cpos;
	
	
	UniqueModelCount=0;
	ViolatorCount=0;
	EntityCount=0;
	
	for(rinc=0,rpos=(-rows*c_ZoneSize*0.5f);rinc<rows;rinc++,rpos+=c_ZoneSize)
		for(cinc=0,cpos=(-cols*c_ZoneSize*0.5f);cinc<rows;cinc++,cpos+=c_ZoneSize)
		{
			ZoneRep[rinc*cols+cinc].RChar='A'+rinc;
			ZoneRep[rinc*cols+cinc].CChar='A'+cinc;
			ZoneRep[rinc*cols+cinc].CountTypes(rpos,cpos);
			ViolatorCount+=ZoneRep[rinc*cols+cinc].GetViolatorCount();
			EntityCount+=ZoneRep[rinc*cols+cinc].GetEntityCount();
		}
		
		Violators=new TileViolator[ViolatorCount];
		int vio_inc=0;
		
		CZoneReport::CountTypes(0.0f,0.0f);
		
		BYTE r,c;
		CollisionGrid::Instance->GetSize(&TileRows,&TileCols);
		TileEntityCount=new int[TileCols*TileRows];
		
		for(r=0;r<TileRows;r++)
			for(c=0;c<TileCols;c++)
			{
				TileEntityCount[r*TileCols+c]=CollisionGrid::Instance->EntitiesInTile(r,c);
			}
}

int EntitiesInTile(int x,int y)
{
	BYTE rows, cols;
	CollisionGrid::Instance->GetSize(&rows,&cols);
	if(x>=cols || x<0 || y>=rows ||y<0) return -1;
	
	return CollisionGrid::Instance->EntitiesInTile(y,x);
}

int GetSkinCount()
{
	return MWApplication::GetInstance()->m_skinsTable->GetTableSize();
}

CString GetNthSkinName(int val)
{
	MWTable::TableIterator *skin_iterator;
	skin_iterator = MWApplication::GetInstance()->m_skinsTable->MakeTableIterator();
	MWTableEntry *skin_entry;
	skin_entry=(MWTableEntry *)skin_iterator->GetNthItem(val);
	Check_Object(skin_entry);
	return ((const char *)skin_entry->GetEntryName());
	
}

char GetNthSkin(int val)
{
	MWTable::TableIterator *skin_iterator;
	skin_iterator = MWApplication::GetInstance()->m_skinsTable->MakeTableIterator();
	MWTableEntry *skin_entry;
	skin_entry=(MWTableEntry *)skin_iterator->GetNthItem(val);
	Check_Object(skin_entry);
	return skin_entry->GetData()[0];
	
}


CString GetSkinName(char skin)
{
	if(skin==-1) return "UnSkinable";
	int current_skin;
	
	current_skin = 0;
	char skin_string[2];
	*skin_string = skin;
	skin_string[1] = 0;
	current_skin = MWApplication::GetInstance()->m_skinsTable->FindIndexFromDataString(skin_string);
	
	if(current_skin==-1) return "UnSkinable";
	return GetNthSkinName(current_skin);
}


void TranslateMissionNameBackIfNecessary(CString &mis_name)
{
	Stuff::MString missionname = (const char *)mis_name;
	if (MWApplication::TranslateMissionNameBackIfNecessary(missionname))
		mis_name=(const char *)missionname;
}

#define GAME_REG_KEY	 	"Software\\Microsoft\\Microsoft Games\\MW4GameED2"

typedef DWORD (*EBUPROC) (LPCTSTR lpRegKeyLocation, LPCTSTR lpEULAFileName, LPCSTR lpWarrantyFileName, BOOL fCheckForFirstRun);

bool FirstRunEula(const char *eula_filename,const char *warranty_filename)
{
	EBUPROC	pfnEBUEula;
	
	HINSTANCE hMod;
	hMod = LoadLibrary("Assets\\binaries\\EBUEula.dll");
	
	if (NULL == hMod)  		
		hMod = LoadLibrary("EBUEula.dll");
	
	if (NULL == hMod)  		// can't attach to DLL
	{
		STOP(("Cannot Load EBUEula.dll"));
	}
	pfnEBUEula = (EBUPROC) GetProcAddress(hMod, "EBUEula");
	
	if (NULL == pfnEBUEula) 	// can't find entry point
	{
		FreeLibrary(hMod);
		STOP(("Cannot Find Entry Point to EBUEula.dll"));
	}
	
	
	//
	//This call enables both EULA and warranty accepting/viewing/printing.  If your
	//game doesn't ship with a WARRANTY file, specifiy NULL instead of szWarranty...

	//The code below, for instance, works with both OEM and retail builds...

	//
	const char *pszWarrantyParam = 0xFFFFFFFF != GetFileAttributes(warranty_filename) ? warranty_filename : NULL;
	BOOL fAllowGameToRun = pfnEBUEula(GAME_REG_KEY, eula_filename, pszWarrantyParam, TRUE);
	
	FreeLibrary(hMod);
	return fAllowGameToRun?true:false;
}


void RunEula()
{
		CString ename,wname;
		
		ename.LoadString(IDS_ED_EULA_FILENAME);
		wname.LoadString(IDS_ED_WARRANTY_FILENAME);
		
		if(!FirstRunEula(ename,wname))
		{
		/*
		CString msg,cap;
		msg.LoadString(IDS_ED_EULA_FAIL_MESSAGE);
		cap.LoadString(IDS_ED_EULA_FAIL_CAPTION);
			if(MessageBox(NULL,msg,cap,MB_YESNO)==IDYES)
			{
				exit(1);
			}
		*/
				exit(1);

		}
}

int __stdcall Mech4ReconnectGame(void) { gosASSERT(FALSE); return 0; }
void __cdecl CDedicatedServerUI::EnterRunningGameState(void) { gosASSERT(FALSE); }
void __cdecl CDedicatedServerUI::EnterStoppingGameState(void) { gosASSERT(FALSE); }
void __cdecl CDedicatedServerUI::EnterRecyclingGameState(void) { gosASSERT(FALSE); }
void __cdecl CDedicatedServerUI::EnterLoadingGameState(void) { gosASSERT(FALSE); }
SCRIPTVAR_INT(ConnectionIndex)			= 0;
void RegisterData(void) { gosASSERT(FALSE); }
void UnRegisterData(void) { gosASSERT(FALSE); }
SCRIPTCALLBACK(PreConnect) { gosASSERT(FALSE); return 0; }
SCRIPTCALLBACK(InitConnectionWizard) { gosASSERT(FALSE); return 0; }
SCRIPTCALLBACK(LoadMPConnectionSettings) { gosASSERT(FALSE); return 0; }
SCRIPTCALLBACK(CancelDialup) { gosASSERT(FALSE); return 0; }
