// ResourceWindow.cpp : implementation file
//

#include "stdafx.h"
#include "MW4GameEd.h"
#include "ResourceWindow.h"
#include "EditorChildWnd.h"
#include "MW4GameEd.h"
#include <direct.h>
#include <stdlib.h>
#include <stdio.h>
#include <Adept\Map.hpp>
#include "MoveCommand.h"
#include "AddCommand.h"
#include "SprayCommand.h"
#include <Adept\EntityManager.hpp>
#include <Adept\Mission.hpp>
#include <Adept\Connection.hpp>
#include <Adept\Application.hpp>
#include <Adept\NameTable.hpp>
#include <Adept\EntityClassData.hpp>
#include <MW4\Vehicle.hpp>
#include <MW4\Building.hpp>
#include "EditorWaypoint.h"
#include <MW4\rail_move.hpp>
#include "MW4\path.hpp"
#include "DisplayWindow.h"
#include "OverviewWindow.h"
#include "InstanceWindow.h"
#include "Selection.h"
#include <MW4\MWTool.hpp>
#include <NavPoint.hpp>
#include <mw4\Cultural.hpp>
#include <mw4\noncom.hpp>
#include <Adept\navpoint.hpp>
#include "ProgDlg.h"

extern CMW4GameEdApp theApp;
Entity* CreateNewInstanceSimple(char* game_model_name, char* entity_name, char* instance_name); 

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CResourceWindow

IMPLEMENT_DYNCREATE(CResourceWindow, CEditorChildWnd)

CResourceWindow::CResourceWindow() :
mechList(NULL),
buildingList(NULL),
vehicleList(NULL),
miscList(NULL),
tabListIterator(NULL)
{
	CString	title;
	RECT	rect;
	
	TLDlg = NULL;
	
	title.LoadString(IDS_RESOURCEWINDOWTITLE);
	rect.top = 210; rect.left = 650; rect.bottom = 400; rect.right = 900;
	
	Create(NULL,title,WS_CHILD | WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW | WS_VISIBLE,rect);//,theApp.m_pMainWnd,0);
	
	numEntitiesAdded = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CResourceWindow::~CResourceWindow()
{
	objectInformation->IgnoreChanges();
	Unregister_Object(objectInformation);
	delete objectInformation;
	
	TabList* current;
	ChainIteratorOf<TabList*> mechIterator(&mechList);
	while((current = mechIterator.GetCurrent()) != NULL)
	{
		mechIterator.Remove();
		mechIterator.First();
		delete current;
	}
	ChainIteratorOf<TabList*> buildingIterator(&buildingList);
	while((current = buildingIterator.GetCurrent()) != NULL)
	{
		buildingIterator.Remove();
		buildingIterator.First();
		delete current;
	}
	ChainIteratorOf<TabList*> vehicleIterator(&vehicleList);
	while((current = vehicleIterator.GetCurrent()) != NULL)
	{
		vehicleIterator.Remove();
		vehicleIterator.First();
		delete current;
	}
	ChainIteratorOf<TabList*> miscIterator(&miscList);
	while((current = miscIterator.GetCurrent()) != NULL)
	{
		miscIterator.Remove();
		miscIterator.First();
		delete current;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BEGIN_MESSAGE_MAP(CResourceWindow,CEditorChildWnd)
//{{AFX_MSG_MAP(CResourceWindow)
ON_WM_LBUTTONDBLCLK()
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_KEYDOWN()
ON_WM_RBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CResourceWindow message handlers

void CResourceWindow::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	if(Application::Instance->GetApplicationState() 
		== ApplicationStateEngine::RunningGameState)
	{
		theApp.m_editorState = CMW4GameEdApp::WaitingToAddState;
		Entity* entity = CreateNewInstance();
		if (entity != NULL)
		{
			if (theApp.m_editorState == CMW4GameEdApp::WaitingToAddState)
				theApp.m_editorState = CMW4GameEdApp::AddingObjectState;
		}
    else
    {
        theApp.m_editorState = CMW4GameEdApp::IdleState;

    }
	}
	CEditorChildWnd::OnLButtonDblClk(nFlags, point);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Entity* CResourceWindow::CreateNewInstance(char* game_model_name, char* entity_name, char* instance_name) 
{
	Entity* entity = NULL;
	
	Check_Object(theApp.resourceWindow->objectInformation);
	Page *entity_instance = theApp.resourceWindow->objectInformation->FindPage(instance_name);
	if(!entity_instance)
	{
		PAUSE(("That item does not have an instance in editor.contents"));
		return (NULL);
	}
	else
	{
		FileDependencies dummy;
		FileDependencies *parent = Resource::ParentFileDependencies;
		Resource::ParentFileDependencies = &dummy;
		entity_instance->SetEntry("Model", game_model_name);
		DynamicMemoryStream entity_stream;
		ReplicatorID entity_id = ReplicatorID::Null;
		Entity::CreateMessage* create_message = 
			Tool::Instance->ConstructCreateMessage(
			&entity_stream,
			entity_instance,
			&entity_id
			);
		
		// 
		// set the default alignment based on the editor settings
		//
		create_message->alignment = theApp.GetDefaultAlignmentForPlacedObjects();
		
		LinearMatrix4D matrix = LinearMatrix4D::Identity;
		Point3D point;
		point.x = 0.0f;
		point.z = 0.0f;
		point.y = theApp.displayWindow->GetMapPointVertical(point.x,point.z);
		
		matrix.BuildTranslation(point);
		
		create_message->localToParent = matrix;
		
		entity_stream.Rewind();
		Check_Object(Connection::Local);
		entity_id = Connection::Local->GetNextReplicatorID();
		
		entity = Entity::CreateEntity(
			&entity_stream,
			&entity_id,
			false
			);
		//
		//--------------------------------------------
		//Make some initial assignments for the entity
		//--------------------------------------------
		//
		Check_Object(entity);
		Check_Object(EntityManager::Instance);
		EntityManager::Instance->GetNameSocket()->Remove(entity);
		entity->instanceName = theApp.resourceWindow->AssignObjectName(entity_name, &theApp.resourceWindow->numEntitiesAdded);
		if (entity->IsDerivedFrom(Vehicle::DefaultData))
		{
			Vehicle* vehicle = Cast_Object(Vehicle*,entity);
			
			EntityManager::Instance->RemoveMover(vehicle);
			EntityManager::Instance->AddMover(vehicle);
		}
		EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
		
		Check_Object(Map::Instance);
		Map::Instance->AddChild(entity);
		MLRTexturePool::Instance->LoadImages();
		entity->SetPropType(Entity::MissionPropType);
		theApp.displayWindow->SetFocus();
		
		entity->SyncMatrices(true);
		Map::Instance->UpdateZone(entity);
		CSelectionList::Instance->AddSelection(entity);
		CSelectionList::Instance->RemoveCollision();
		Resource::ParentFileDependencies = parent;
	}
	return entity;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Entity* CResourceWindow::CreateNewInstance(Entity* entity)
{
	static  recurseGuard = false;
	
	TLDlg->m_ObjList.EnableWindow(FALSE);
	theApp.instanceWindow->TLDlg->m_ObjList.EnableWindow(FALSE);
	
	CSelectionList::Instance->ClearSelectionList();
	theApp.m_MultiDrop = true;
	
	int item = TLDlg->m_ObjList.GetCurSel();
	
	if(Application::Instance->GetApplicationState() 
		== ApplicationStateEngine::RunningGameState)
	{
		const char *game_model_name = (char *)TLDlg->m_ObjList.GetItemData(item);
		char entity_name[MAX_PATH];
		int length = TLDlg->m_ObjList.GetText(item,entity_name);
		Verify(length < MAX_PATH);
		char instance_name[MAX_PATH];
		TLDlg->m_ObjList.GetText(item,instance_name);
		entity = CreateNewInstance((char*)game_model_name,entity_name,instance_name);
		if (entity == NULL)
		{
			TLDlg->m_ObjList.EnableWindow(TRUE);
			theApp.instanceWindow->TLDlg->m_ObjList.EnableWindow(TRUE);
			theApp.m_MultiDrop = false;
			return (NULL);
		}
		
		if (entity->IsDerivedFrom(EditorLatticeNode::DefaultData))
		{
			Point3D pos;
			pos = entity->GetLocalToWorld();
			MW4AI::CRailNode* railNode;
			SPEW(("scottjan","Hey! set up a default railnode radius"));
			railNode = new MW4AI::CRailNode(pos,50);
			MW4AI::g_MissionGraph->AddNode(railNode);
			
			EditorLatticeNode* latticeNode = Cast_Object(EditorLatticeNode*,entity);
			latticeNode->railNode = railNode;
			theApp.CreateLatticeNodeRadius(latticeNode);
			
			theApp.m_showLattice = false;
			theApp.OnToolsMovementlattice();
			//			theApp.m_showLatticeLinks = false;
			//			theApp.OnToolsMovmentlayerShowlatticelinks();
		}
		else if (entity->IsDerivedFrom(EditorMovementPath::DefaultData))
		{
			if (theApp.m_CurPath == NULL)
			{
				EditorMovementPath* path;
				path = Cast_Object(EditorMovementPath*, entity);
				path->pathSlot.Remove();
				path->pathSlot.Add(CreateMovementPath());
				theApp.m_CurPath = path;
				theApp.m_CurPathNodeCount = 0;
				theApp.m_LastPathNode = NULL;
				
				path->instanceName = path->pathSlot.GetCurrent()->instanceName;
				//	path->GetElement()->SetAlwaysCullMode();
				path->GetElement()->Sync();
				
				theApp.instanceWindow->ResetInstanceLists();
			}
			else	// quick hack, if we are appending to a path we need to destroy the new one we just created
			{
				entity->SentenceToDeathRow();
			}
			
			entity = CreateNewInstance("Content\\Editor\\Reserved\\PathNode\\PathNode.data",
				"PathNode","PathNode");
			
			CSelectionList::Instance->ClearSelectionList();
			CSelectionList::Instance->AddSelection(entity);
			CSelectionList::Instance->RemoveCollision();
			
			Point3D point;
			point = entity->GetLocalToWorld();
			theApp.m_CurPath->pathSlot.GetCurrent()->pathPoints.push_back(point);
			
			EditorPathNode* pathNode;
			pathNode = Cast_Object(EditorPathNode*,entity);
			
			pathNode->pathSlot.Remove();
			pathNode->pathSlot.Add(theApp.m_CurPath);
			theApp.m_CurPath->pathNodes.Add(pathNode);
			pathNode->index = theApp.m_CurPathNodeCount++;
			pathNode->nextnode = NULL;
			pathNode->prevnode = theApp.m_LastPathNode;
			if (theApp.m_LastPathNode)
				theApp.m_LastPathNode->nextnode = pathNode;
			
			pathNode->CreateLink();
			theApp.m_LastPathNode = pathNode;
			theApp.m_showPaths = false;
			theApp.OnToolsMovmentlayerShowpaths();
		}
		else if (entity->IsDerivedFrom(EditorDropNode::DefaultData))
		{
			EditorDropNode* node;
			node = Cast_Object(EditorDropNode*,entity);
			node->SetDropZone(NULL);	// will create a new Adept::DropZone and attach it to EditorDropNode
			theApp.m_showDropZones = false;
			theApp.OnToolsMovmentlayerShowdropzones();
		}
		else if (entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData))
		{
			EditorObjectiveMarker* node;
			node = Cast_Object(EditorObjectiveMarker*,entity);
			node->SetObjective(NULL);	// will create a new MechWarrior4::Objective and attach it to EditorDropNode
			theApp.m_showAI = false;
			theApp.OnToolsMovmentlayerShowobjectives();
		}
		else if (entity->IsDerivedFrom(NavPoint::DefaultData))
		{
			NavPoint* node;
			node = Cast_Object(NavPoint*,entity);
			node->SetToDisplay();
		}
		else if (entity->IsDerivedFrom(EditorLight::DefaultData))
		{
			EditorLight* editorLight;
			editorLight = Cast_Object(EditorLight*,entity);
			editorLight->SetLight();
		}
		else if (entity->IsDerivedFrom(EditorCameraShip::DefaultData))
		{
			EditorCameraShip* node;
			node = Cast_Object(EditorCameraShip*,entity);
			node->SetCameraShip(NULL);	// will create a new CameraShip and attach it to EditorDropNode
			
		}
#if 0
		if (theApp.m_editorState == CMW4GameEdApp::AddingObjectState)
		{
			theApp.currentCommand = new AddCommand(entity);
			Register_Object(theApp.currentCommand);
		}
		else if (!recurseGuard && entity->IsDerivedFrom(Building::DefaultData))
		{
			recurseGuard = true;
			theApp.currentCommand = new SprayCommand(entity);
			Register_Object(theApp.currentCommand);
			recurseGuard = false;
		}
#endif
		
		if ((!recurseGuard && entity->IsDerivedFrom(Building::DefaultData)) &&
			(theApp.m_editorState == CMW4GameEdApp::WaitingToSprayState))
		{
			recurseGuard = true;
			theApp.currentCommand = new SprayCommand(entity);
			Register_Object(theApp.currentCommand);
			recurseGuard = false;
			theApp.m_editorState = CMW4GameEdApp::SprayingState;
		}
		else if(theApp.m_editorState == CMW4GameEdApp::WaitingToAddState)
		{
			theApp.currentCommand = new AddCommand(entity);
			Register_Object(theApp.currentCommand);
			theApp.m_editorState = CMW4GameEdApp::AddingObjectState;
			if (entity->IsDerivedFrom(EditorAmbientLight::DefaultData) ||
				entity->IsDerivedFrom(EditorInfiniteLight::DefaultData) ||
				entity->IsDerivedFrom(EditorObjectiveMarker::DefaultData))
			{
				entity->GetElement()->SetAlwaysCullMode();
				CSelectionList::Instance->ClearSelectionList();
				theApp.m_editorState = CMW4GameEdApp::SelectingObjectState;
				theApp.m_MultiDrop = false;
				theApp.resourceWindow->TLDlg->m_ObjList.EnableWindow();
				theApp.instanceWindow->TLDlg->m_ObjList.EnableWindow();
				//				theApp.instanceWindow->AddInstance(entity);
			}
		}
		
	}
	theApp.displayWindow->SetFocus();	// rqr'd for multi instace add
	return entity;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int CResourceWindow::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CEditorChildWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	TLDlg = new CObjWindow;
	
	TLDlg->Create(CObjWindow::IDD,this);
	
	RECT r;
	memset(&r,0,sizeof(r));
	TLDlg->m_ObjList.Create(WS_VISIBLE | WS_CHILD | LBS_NOINTEGRALHEIGHT | LBS_STANDARD,r,TLDlg,0);
	
	TLDlg->GetDlgItem(IDC_INSTANCEALINGMENTBTN)->ShowWindow(SW_HIDE);
	TLDlg->GetDlgItem(IDC_INSTANCETYPEBTN)->ShowWindow(SW_HIDE);
	TLDlg->ShowWindow(SW_SHOW);
	
	//
	//----------------------------------------
	//Initialize the Instance Information File
	//----------------------------------------
	//
	objectInformation = new NotationFile("Content\\Editor\\editor.contents");
	Register_Object(objectInformation);
	
	{
		MString vehicle_path = Working_Directory;
		vehicle_path += "\\Content\\Mechs\\*.*";
		Directory *vehicle_directory;
		vehicle_directory = new Directory(vehicle_path, true);
		Register_Object(vehicle_directory);
		
		TLDlg->m_TabCtrl.InsertItem(0,TLDlg->mechTab);
		
		vehicle_path.IsolateDirectory();
		
		MakeDirectoryList(
			vehicle_directory,
			MECH_TAB,
			vehicle_path
			);
		
		Unregister_Object(vehicle_directory);
		delete vehicle_directory;
	}
	//
	//-----------------------------------------
	//Initialize the Building Folder in Content
	//-----------------------------------------
	//
	{
		MString prop_path = Working_Directory;
		prop_path += "\\Content\\Buildings\\*.*";
		Directory *prop_directory;
		prop_directory = new Directory(prop_path, true);
		Check_Object(prop_directory);
		Register_Object(prop_directory);
		
		TLDlg->m_TabCtrl.InsertItem(1,TLDlg->buildingTab);
		
		prop_path.IsolateDirectory();
		
		MakeDirectoryList(
			prop_directory,
			BUILDING_TAB,
			prop_path
			);
		
		Unregister_Object(prop_directory);
		delete prop_directory;
	}
	//
	//-----------------------------------------
	//Initialize the Vehicles Folder in Content
	//-----------------------------------------
	//
	
	{
		MString vehicle_path = Working_Directory;
		vehicle_path += "\\Content\\Vehicles\\*.*";
		Directory *vehicle_directory;
		vehicle_directory = new Directory(vehicle_path, true);
		Register_Object(vehicle_directory);
		
		TLDlg->m_TabCtrl.InsertItem(2,TLDlg->vehicleTab);
		
		vehicle_path.IsolateDirectory();
		
		MakeDirectoryList(
			vehicle_directory,
			VEHICLE_TAB,
			vehicle_path
			);
		
		Unregister_Object(vehicle_directory);
		delete vehicle_directory;
	}
	
	{
	/*
	MString prop_path = Working_Directory;
	prop_path += "\\Content\\DropZones\\*.*";
	Directory *prop_directory;
	prop_directory = new Directory(prop_path, true);
	Check_Object(prop_directory);
	Register_Object(prop_directory);
	
	  Stuff::IsolateDirectory(&prop_path);
	  
		MakeDirectoryList(
		prop_directory,
		MISC_TAB,
		prop_path
		);
		
		  Unregister_Object(prop_directory);
		  delete prop_directory;
		*/
		TLDlg->m_TabCtrl.InsertItem(3,TLDlg->miscTab);
		
		MString prop_path = Working_Directory;
		prop_path += "\\Content\\Editor\\Waypoints\\*.*";
		Directory *prop_directory = new Directory(prop_path, true);
		Check_Object(prop_directory);
		Register_Object(prop_directory);
		
		prop_path.IsolateDirectory();
		
		MakeDirectoryList(
			prop_directory,
			MISC_TAB,
			prop_path
			);
		
		Unregister_Object(prop_directory);
		delete prop_directory;
	}
	TLDlg->m_TabCtrl.SetCurSel(0);
	FillTabBox(0);
	
	return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void CResourceWindow::OnSize(UINT nType, int cx, int cy) 
{
	CEditorChildWnd::OnSize(nType, cx, cy);
	
	if(TLDlg)
	{
		TLDlg->SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);
		TLDlg->m_TabCtrl.SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);	
		RECT r,l;
		TLDlg->m_TabCtrl.GetClientRect(&r);
		TLDlg->m_TabCtrl.GetItemRect(0,&l);
		TLDlg->m_ObjList.SetWindowPos(NULL,3,l.bottom + 3,r.right - 7,r.bottom - l.bottom - 7,SWP_NOZORDER);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void CResourceWindow::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MString
CResourceWindow::AssignObjectName(MString name, int *num)
{
	MString object_name;
	char number[256];
	
	//
	// Make the object name
	//
	sprintf(number, "%i", *num);
	(*num)++;
	object_name = name;
	object_name += "_";
	object_name += number;
	
	while (CheckObjectName(object_name))
	{
		sprintf(number, "%i", *num);
		(*num)++;
		object_name = name;
		object_name += "_";
		object_name += number;
	}
	return object_name;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CResourceWindow::MakeDirectoryList(
								   Directory *current_directory, 
								   int tabNumber,
								   MString directory_name
								   )
{
	static int recursionDepth = 0;
	
	Check_Pointer (this);
	Check_Pointer(current_directory);
	
	MString file_directory_name;
	file_directory_name = directory_name;
	file_directory_name.StripExtension();
	file_directory_name += "*.data";
	Directory *file_directory = new Directory(file_directory_name, false);
	Register_Object(file_directory);
	
	MString file_name;
	while((char *)(file_name = file_directory->GetCurrentFileName()) != NULL)
	{
	file_name.StripExtension();
		
		file_name.ToLower();
		if (file_name == "basic")
		{
			file_directory->AdvanceCurrentFile();
			continue;
		}
		
		TabList* newNode = new TabList;
		
		newNode->itemString = file_name;
		newNode->itemPath = directory_name;
		newNode->itemPath += file_name;
		newNode->itemPath += ".data";
		
		char appended_data[MAX_PATH];
		strcpy(appended_data, strstr(newNode->itemPath.GetBuffer(MAX_PATH - 1), "Content"));
		newNode->itemPath = appended_data;
		
		if (file_name == "navpoint")
		{
			miscList.Add(newNode);
		}
		else
		{
			switch (tabNumber)
			{
			case MECH_TAB:
				mechList.Add(newNode);
				break;
			case BUILDING_TAB:
				buildingList.Add(newNode);
				break;
			case VEHICLE_TAB:
				vehicleList.Add(newNode);
				break;
			case MISC_TAB:
				miscList.Add(newNode);
				break;
			}
		}
		file_directory->AdvanceCurrentFile();
	}
	Unregister_Object(file_directory);
	delete file_directory;
	
	if (recursionDepth > 0)
	{
		recursionDepth--;
		return;
	}
	
	MString folder_name;
	while((char *)(folder_name = current_directory->GetCurrentFolderName()) != NULL)
	{
		MString new_directory_name = directory_name;
		new_directory_name += folder_name;
		new_directory_name += "\\*.*";
		Directory *new_directory = new Directory(new_directory_name, true);
		Register_Object(new_directory);
		new_directory_name.IsolateDirectory();
		recursionDepth++;
		MakeDirectoryList(
			new_directory,
			tabNumber,
			new_directory_name
			);
		Unregister_Object(new_directory);
		delete new_directory;
		
		current_directory->AdvanceCurrentFolder();
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
CResourceWindow::CheckObjectName(MString name)
{
	Check_Object(EntityManager::Instance);
	
	if(EntityManager::Instance->GetNameSocket()->Find(name))
	{
		return true;
	}
	return false;
}

void CResourceWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	//	if (theApp.m_editorState != CMW4GameEdApp::AddingObjectState)
	CEditorChildWnd::OnKeyDown(nChar, nRepCnt, nFlags);
	//	else if (nChar == VK_ESCAPE)
	//		theApp.StopMultiPlace();
}

void CResourceWindow::FillTabBox(int tabNumber)
{
	switch (tabNumber)
	{
	case MECH_TAB:
		{
			ChainIteratorOf<TabList*> iterator(&mechList);
			FillTabBox(iterator);
			break;
		}
	case BUILDING_TAB:
		{
			ChainIteratorOf<TabList*> iterator(&buildingList);
			FillTabBox(iterator);
			break;
		}
	case VEHICLE_TAB:
		{
			ChainIteratorOf<TabList*> iterator(&vehicleList);
			FillTabBox(iterator);
			break;
		}
	case MISC_TAB:
		{
			ChainIteratorOf<TabList*> iterator(&miscList);
			FillTabBox(iterator);
			break;
		}
	}
}

void CResourceWindow::FillTabBox(ChainIteratorOf<TabList*> &iterator)
{
	TLDlg->m_ObjList.ResetContent();
	
	TabList* item;
	
	while ((item = iterator.ReadAndNext()) != NULL)
	{
		int index = TLDlg->m_ObjList.AddString(item->itemString);
		TLDlg->m_ObjList.SetItemDataPtr(index,(void*)LPCTSTR(item->itemPath));
	}
}

BOOL CResourceWindow::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
{
	if (UINT(wParam) == IDC_OBJECTTAB)
		FillTabBox(((NMHDR*)(lParam))->code);
	
	*pResult = 0;
	
	return CEditorChildWnd::OnNotify(wParam, lParam, pResult);
}

MechWarrior4::Path* CResourceWindow::CreateMovementPath()
{
	Resource model_resource;
	SPEW(("scottjan","Get rid of the hard coded data file"));
	NotationFile path_file("Content\\Misc\\Path.data");
	Tool::Instance->ConstructDataList(&model_resource, &path_file);
	Check_Object(&model_resource);
	Verify(model_resource.DoesResourceExist());
	
	Entity::ClassID class_ID;
	class_ID = Entity::GetClassIDFromDataListID(model_resource.GetResourceID());
	Verify(class_ID != NullClassID);
	
	LinearMatrix4D	matrix = LinearMatrix4D::Identity;
	
	MechWarrior4::Path::CreateMessage Path_Create_Message(
		sizeof(MechWarrior4::Path::CreateMessage),
		DefaultEventPriority,
		MechWarrior4::Path::CreateMessage::DefaultFlags,
		class_ID,
		MechWarrior4::Path::DefaultFlags,
		model_resource.GetResourceID(),
		matrix,
		0.0f,
		Entity__ExecutionStateEngine::AlwaysExecuteState,
		NameTable::NullObjectID,
		Entity::DefaultAlignment,
		ResourceID::Null
		);
	
	MemoryStream stream(&Path_Create_Message, Path_Create_Message.messageLength);
	
	ReplicatorID Path_id = Connection::Local->GetNextReplicatorID();
	Entity* entity;
	entity = Entity::CreateEntity(&stream, &Path_id, false);
	Check_Object(entity);
	Verify(entity->IsDerivedFrom(Path::DefaultData));
	
	Check_Object(EntityManager::Instance);
	EntityManager::Instance->GetNameSocket()->Remove(entity);
	entity->instanceName = theApp.resourceWindow->AssignObjectName("Path", &theApp.resourceWindow->numEntitiesAdded);
	EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
	Check_Object(Map::Instance);
	Map::Instance->AddChild(entity);
	
	MLRTexturePool::Instance->LoadImages();
	CSelectionList::Instance->RemoveCollision();
	entity->SetPropType(Entity::MissionPropType);
	entity->SyncMatrices(true);
	
	Verify(entity->IsDerivedFrom(Path::DefaultData));
	 NameTable::Instance->AddEntry(entity, NameTable::PathArray);
		NameTable::Instance->IsValid();
	
	MechWarrior4::Path* path;
	path = Cast_Object(MechWarrior4::Path*, entity);
	
	return (path);
}


void CResourceWindow::OnRButtonDblClk(UINT nFlags, CPoint point) 
{
	if(Application::Instance->GetApplicationState() 
		== ApplicationStateEngine::RunningGameState)
	{
		if (TLDlg->m_TabCtrl.GetCurSel() == BUILDING_TAB)
		{
			theApp.m_editorState = CMW4GameEdApp::WaitingToSprayState;
			Entity* entity = CreateNewInstance();
			if (entity != NULL)
			{
				theApp.m_editorState = CMW4GameEdApp::SprayingState;
			}
      else
      {
        theApp.m_editorState = CMW4GameEdApp::IdleState;
      }

		}
	}
	CEditorChildWnd::OnRButtonDblClk(nFlags, point);
}

void CResourceWindow::DisperseWithBitmap(bool cultural_flag)
{
	CFileDialog fdlg(TRUE,NULL,NULL,NULL,"Bitmap Images (*.tif,*.gif,*.tga)|*.tif;*.gif;*.tga||",NULL);	
	
	if(fdlg.DoModal()==IDOK)
	{
		Image img;
		img.Load((char *)(LPCSTR)fdlg.GetPathName());
		img.Rotate180();
		SetCurrentDirectory(Working_Directory);
		BYTE *dat=img.Lock();
		int x,y;

		Scalar minz,maxz,minx,maxx,xsize,zsize;
		float gridxsize,gridzsize;
		
		Map::Instance->GetMapExtents(&minz,&maxz,&minx,&maxx);
		xsize=maxx-minx;
		zsize=maxz-minz;
		
		int total=img.GetHeight()*img.GetWidth();
		int current=0;

		CProgressDlg *ProgressDlg;
		ProgressDlg = new CProgressDlg(IDS_DISPERSE);
		ProgressDlg->Create();
		ProgressDlg->ShowWindow(SW_SHOW);

		ProgressDlg->SetRange(0,total);
		ProgressDlg->SetStep(50);
		ProgressDlg->SetPos(0);

		gridxsize=xsize/img.GetWidth();
		gridzsize=zsize/img.GetHeight();

		int item = TLDlg->m_ObjList.GetCurSel();
		const char *game_model_name = (char *)TLDlg->m_ObjList.GetItemData(item);
		char entity_name[MAX_PATH];
		int length = TLDlg->m_ObjList.GetText(item,entity_name);
		Verify(length < MAX_PATH);
		char instance_name[MAX_PATH];
		TLDlg->m_ObjList.GetText(item,instance_name);

		CSelectionList::Instance->ClearSelectionList();
		for(y=0;y<img.GetHeight();y++)
			for(x=0;x<img.GetWidth();x++)
			{
			current++;
			if((current%50 || current==total)) ProgressDlg->SetPos(current);
				if(dat[x+img.GetPitch()*y])
				{
					Entity *entity = NULL;
					entity = CreateNewInstanceSimple((char*)game_model_name,entity_name,instance_name);

					Point3D pos;
					YawPitchRoll rot;
					Stuff::LinearMatrix4D mat;

					do
					{
					rot.yaw=Stuff::Random::GetFraction()*Two_Pi;
					rot.pitch=0.0f;
					rot.roll=0.0f;

					pos.x=x*gridxsize+Stuff::Random::GetFraction()*gridxsize;
					pos.z=y*gridzsize+Stuff::Random::GetFraction()*gridzsize;
					pos.y=theApp.displayWindow->GetMapPointVertical(pos.x,pos.z); 
					mat.BuildRotation(rot);
					mat.BuildTranslation(pos);


						Map::Instance->AddChild(entity);
						entity->SetNewLocalToParent(mat);
						entity->SyncMatrices(true);
						Map::Instance->UpdateZone(entity);
											
					}
					while(entity->IsMultiZone());


				if ( entity->IsMultiTile()) 
				{
					Map::Instance->RemoveChild(entity);
					NameTable::Instance->RemoveEntry(entity->objectID);
		NameTable::Instance->IsValid();
					delete Cast_Object(Stuff::Plug *, entity);
				}
				else
				{
					Check_Object(NameTable::Instance);
					entity->BindToTile();	
					if(entity->IsDerivedFrom(Vehicle::DefaultData))
								NameTable::Instance->AddEntry(entity, NameTable::VehicleArray);
							else if(entity->IsDerivedFrom(Building::DefaultData) || entity->IsDerivedFrom(Cultural::DefaultData))
								 NameTable::Instance->AddEntry(entity, NameTable::BuildingArray);
							else if(entity->IsDerivedFrom(NavPoint::DefaultData))
								 NameTable::Instance->AddEntry(entity, NameTable::NavArray);
							else if(entity->IsDerivedFrom(NonCom::DefaultData))
								 NameTable::Instance->AddEntry(entity, NameTable::BuildingArray);
							else if(entity->IsDerivedFrom(AI::DefaultData))
								 NameTable::Instance->AddEntry(entity, NameTable::AIArray);
		NameTable::Instance->IsValid();

						if(cultural_flag) theApp.culturalList.Add(entity);
				}
		
					
					
				}
			}
			delete ProgressDlg;
				img.UnLock();
				
				
	}
			theApp.instanceWindow->ResetInstanceLists();

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Entity* CreateNewInstanceSimple(char* game_model_name, char* entity_name, char* instance_name) 
{
	Entity* entity = NULL;
	
	Check_Object(theApp.resourceWindow->objectInformation);
	Page *entity_instance = theApp.resourceWindow->objectInformation->FindPage(instance_name);
	if(!entity_instance)
	{
		PAUSE(("That item does not have an instance in editor.contents"));
	}
	else
	{
		FileDependencies dummy;
		FileDependencies *parent = Resource::ParentFileDependencies;
		Resource::ParentFileDependencies = &dummy;
		entity_instance->SetEntry("Model", game_model_name);
		DynamicMemoryStream entity_stream;
		ReplicatorID entity_id = ReplicatorID::Null;
		Entity::CreateMessage* create_message = 
			Tool::Instance->ConstructCreateMessage(
			&entity_stream,
			entity_instance,
			&entity_id
			);
		
		// 
		// set the default alignment based on the editor settings
		//
		create_message->alignment = theApp.GetDefaultAlignmentForPlacedObjects();
		
		LinearMatrix4D matrix = LinearMatrix4D::Identity;
		
		create_message->localToParent = matrix;
		
		entity_stream.Rewind();
		Check_Object(Connection::Local);
		entity_id = Connection::Local->GetNextReplicatorID();
		
		entity = Entity::CreateEntity(
			&entity_stream,
			&entity_id,
			false
			);
		//
		//--------------------------------------------
		//Make some initial assignments for the entity
		//--------------------------------------------
		//
		Check_Object(entity);
		Check_Object(EntityManager::Instance);
		EntityManager::Instance->GetNameSocket()->Remove(entity);
		entity->instanceName = theApp.resourceWindow->AssignObjectName(entity_name, &theApp.resourceWindow->numEntitiesAdded);
		if (entity->IsDerivedFrom(Vehicle::DefaultData))
		{
			Vehicle* vehicle = Cast_Object(Vehicle*,entity);
			
			EntityManager::Instance->RemoveMover(vehicle);
			EntityManager::Instance->AddMover(vehicle);
		}
		EntityManager::Instance->GetNameSocket()->AddValue(entity, entity->instanceName);
		
		entity->SetPropType(Entity::MissionPropType);
		Resource::ParentFileDependencies = parent;
	}
	return entity;
}

