// EditEntityDlg.cpp : implementation file
//

#include "stdafx.h"
#include "mw4gameed.h"
#include "EditEntityDlg.h"
#include <Adept\Entity.hpp>
#include <Adept\GameModelAttribute.hpp>
#include <Adept\EntityClassData.hpp>
#include <Adept\Resource.hpp>
#include "GenericTextDlg.h"
#include <MW4\Vehicle.hpp>
#include <MW4\Subsystem.hpp>
#include <MW4\BeamWeapon.hpp>
#include <Adept\DamageObject.hpp>
#include <MW4\Building.hpp>

#define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c))

extern CMW4GameEdApp theApp;

/////////////////////////////////////////////////////////////////////////////
// EditEntityDlg dialog


EditEntityDlg::EditEntityDlg(CWnd* pParent, Entity *entity,int type,void* data)
	: CDialog(EditEntityDlg::IDD, pParent),
	modelUndoChain(NULL),
	damageUndoChain(NULL)
{
	//{{AFX_DATA_INIT(EditEntityDlg)
	//}}AFX_DATA_INIT
	selectedEntity = entity;
	m_Title.LoadString(IDS_EDITENTITYWINDOWTITLE);

	needsSave = false;
	newGameModel = false;
	dlgType = type;
	exData = data;
}

EditEntityDlg::~EditEntityDlg()
{
}

void EditEntityDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(EditEntityDlg)
	DDX_Control(pDX, IDC_GAMEMODELEDIT, m_gameModelEdit);
	DDX_Control(pDX, IDC_ENTITYEDITBOX, m_floatingEdit);
	DDX_Control(pDX, IDC_EntityValues, m_entityValueList);
	DDX_Control(pDX, IDCANCEL, m_CancelBtn);
	DDX_Control(pDX, IDC_EntityProperties, m_entityPropertiesList);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(EditEntityDlg, CDialog)
	//{{AFX_MSG_MAP(EditEntityDlg)
	ON_LBN_DBLCLK(IDC_EntityProperties, OnDblclkEntityProperties)
	ON_LBN_SELCHANGE(IDC_EntityProperties, OnSelchangeEntityProperties)
	ON_LBN_SELCHANGE(IDC_EntityValues, OnSelchangeEntityValues)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_GAMEMODELSAVEBTN, OnGamemodelsavebtn)
	ON_EN_CHANGE(IDC_ENTITYEDITBOX, OnChangeEntityeditbox)
	ON_EN_KILLFOCUS(IDC_ENTITYEDITBOX, OnKillfocusEntityeditbox)
	ON_WM_SIZE()
	ON_LBN_DBLCLK(IDC_EntityValues, OnDblclkEntityProperties)
	ON_BN_CLICKED(IDMYOK, OnMyok)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// EditEntityDlg message handlers

BOOL EditEntityDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	m_floatingEdit.ShowWindow(SW_HIDE);

	SetWindowText(m_Title);
	
	//Need to update the list here!
	if(selectedEntity)
	{
		switch (dlgType)
		{
		case EDIT_GAME_MODEL:
			InitGameModel();
			break;
		case EDIT_DAMAGE_OBJECTARMOR:
			InitDamageObjectArmor();
			break;
		case EDIT_DAMAGE_OBJECTINTERNAL:
			InitDamageObjectInternal();
			break;
		}
	}
	else if (dlgType == EDIT_SUBSYSTEM)
	{
		InitSubsystem();
	}
	
	RECT pr,vr,cr;

	GetClientRect(&cr);
	m_entityPropertiesList.GetWindowRect(&pr);
	ScreenToClient(&pr);
	m_entityValueList.GetWindowRect(&vr);
	ScreenToClient(&vr);

	m_entityPropertiesList.SetWindowPos(NULL,pr.left,pr.top,pr.right - pr.left,cr.bottom - pr.top - 6,SWP_NOZORDER);
	m_entityValueList.SetWindowPos(NULL,vr.left,vr.top,vr.right - vr.left,cr.bottom - vr.top - 6,SWP_NOZORDER);

	timer = SetTimer(2,25,NULL);

	warned = false;

	ShowWindow(SW_SHOW);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void EditEntityDlg::InitGameModel()
{
	Check_Object(selectedEntity);

	const Entity__GameModel *model = selectedEntity->GetGameModel();
	Check_Object(model);
	Entity::ClassData *class_data;
	class_data = selectedEntity->GetClassData();
	Check_Object(class_data);
	TableIteratorOf<ModelAttributeEntry *, Entity__GameModel::AttributeID>
		iterator(&class_data->gameModelAttributeTable.attributesByID);
	ModelAttributeEntry *attrib_entry;

	int attribute_count = iterator.GetSize();

	for(int i=Entity__GameModel::AnyAttributeID + 1; i < attribute_count; i++)
	{
		attrib_entry = 
			class_data->gameModelAttributeTable.GetAttributeEntry(i);
		Check_Object(attrib_entry);
		m_entityPropertiesList.AddString(attrib_entry->attributeName);
	}

	char *attribute_text;
	attribute_text = new char[128];
	Register_Pointer(attribute_text);
	char *attribute_name;
	attribute_name = new char[MAX_PATH];
	Register_Pointer(attribute_name);

	for(i=0; i < m_entityPropertiesList.GetCount(); i++)
	{
		m_entityPropertiesList.GetText(i,attribute_name);

		attrib_entry = 
				class_data->gameModelAttributeTable.GetAttributeEntry(attribute_name);
		Check_Object(attrib_entry);

		(*class_data->modelWriteToText)((Entity__GameModel *)model, attrib_entry, &attribute_text);

		m_entityValueList.AddString(attribute_text);

		UndoGameModelChanges* ugmc = new UndoGameModelChanges;
		ugmc->attribute_name = attribute_name;
		ugmc->attribute_value = attribute_text;
		modelUndoChain.Add(ugmc);
	}
	Unregister_Pointer(attribute_name);
	delete [] attribute_name;
	Unregister_Pointer(attribute_text);
	delete [] attribute_text;
}

void EditEntityDlg::InitDamageObjectArmor()
{
	Check_Object(selectedEntity);

	GetDlgItem(IDC_EDITRESINSTRUCTIONS)->SetWindowText("Double-Click on the value you wish to change.");
	GetDlgItem(IDC_RESOURCENAMETEXT)->ShowWindow(SW_HIDE);
	GetDlgItem(IDC_GAMEMODELEDIT)->ShowWindow(SW_HIDE);
	GetDlgItem(IDC_GAMEMODELSAVEBTN)->ShowWindow(SW_HIDE);

	SortedChainOf<DamageObject*, int> *chain = NULL;

	if (selectedEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
	{
		MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,selectedEntity);
		chain = &vehicle->damageObjects;
	}
/*
	else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
	{
		Building* building = Cast_Object(Building*,selectedEntity);
		chain = &building->damageObjects;
	}
*/
	else
	{
		MessageBox("You cannot edit the armor on this object","Object cannot be edited");
		return;
	}
	Check_Object(chain);
	SortedChainIteratorOf<DamageObject*, int> iterator(chain);
	DamageObject* damObj;

	char damVal[MAX_PATH];
	int index;

	while ((damObj = iterator.ReadAndNext()) != NULL)
	{
		char name[128];
		sprintf(name,"%s_Max",(char *)damObj->damageObjectName);
		index = m_entityPropertiesList.AddString(name);
		sprintf(damVal,"%3.0f",damObj->baseArmorValue);
		m_entityValueList.InsertString(index,damVal);
		UndoDamageObjectChanges* udoc = new UndoDamageObjectChanges;
		udoc->name= name;
		udoc->value = damObj->baseArmorValue;
		damageUndoChain.Add(udoc);

		sprintf(name,"%s_Current",(char *)damObj->damageObjectName);
		index = m_entityPropertiesList.AddString(name);
		sprintf(damVal,"%3.0f",damObj->currentArmorValue);
		m_entityValueList.InsertString(index,damVal);
		udoc = new UndoDamageObjectChanges;
		udoc->name = name;
		udoc->value = damObj->currentArmorValue;
		damageUndoChain.Add(udoc);
	}
}

void EditEntityDlg::InitDamageObjectInternal()
{
	Check_Object(selectedEntity);

	GetDlgItem(IDC_EDITRESINSTRUCTIONS)->SetWindowText("Double-Click on the value you wish to change.");
	GetDlgItem(IDC_RESOURCENAMETEXT)->ShowWindow(SW_HIDE);
	GetDlgItem(IDC_GAMEMODELEDIT)->ShowWindow(SW_HIDE);
	GetDlgItem(IDC_GAMEMODELSAVEBTN)->ShowWindow(SW_HIDE);

	SortedChainOf<DamageObject*, int> *chain = NULL;

	if (selectedEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
	{
		MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,selectedEntity);
		chain = &vehicle->damageObjects;
	}
/*
	else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
	{
		Building* building = Cast_Object(Building*,selectedEntity);
		chain = &building->damageObjects;
	}
*/
	else
	{
		MessageBox("You cannot edit the internal structure on this object","Object cannot be edited");
		return;
	}
	Check_Object(chain);
	SortedChainIteratorOf<DamageObject*, int> iterator(chain);
//	DamageObject* damObj;

//	char damVal[MAX_PATH];
//	int index;

//	while ((damObj = iterator.ReadAndNext()) != NULL)
//	{
//		char name[128];
//		sprintf(name,"%s_Max",(char *)damObj->damageObjectName);
//		index = m_entityPropertiesList.AddString(name);
//		sprintf(damVal,"%3.0f",damObj->baseInternalDamage);
//		sprintf(damVal,"%3.0f",damObj->baseInternalDamage);
//		m_entityValueList.InsertString(index,damVal);

//		sprintf(name,"%s_Current",(char *)damObj->damageObjectName);
//		index = m_entityPropertiesList.AddString(name);
//		sprintf(damVal,"%3.0f",damObj->currentInternalDamage);
//		m_entityValueList.InsertString(index,damVal);
//	}
}

void EditEntityDlg::InitSubsystem()
{
	GetDlgItem(IDC_EDITRESINSTRUCTIONS)->SetWindowText("Double-Click on the value you wish to change.");
	GetDlgItem(IDC_RESOURCENAMETEXT)->ShowWindow(SW_HIDE);
	GetDlgItem(IDC_GAMEMODELEDIT)->ShowWindow(SW_HIDE);
	GetDlgItem(IDC_GAMEMODELSAVEBTN)->ShowWindow(SW_HIDE);

	char path[MAX_PATH];
	sprintf(path,"%s",(char*)exData);

	Resource subsystem(path);
	Verify(subsystem.DoesResourceExist());
	Resource gameModelResource;
	Entity::GetGameModelResourceFromDataListID(&gameModelResource,subsystem.GetResourceID());

	Entity__GameModel *model = Cast_Pointer(Entity__GameModel*,gameModelResource.GetPointer());

	Entity::ClassID class_id = Entity::GetClassIDFromDataListID(subsystem.GetResourceID());
	Entity__ClassData* class_data = (Entity__ClassData*)Entity::FindClassData(class_id);

	TableIteratorOf<ModelAttributeEntry *, Entity__GameModel::AttributeID>
		iterator(&class_data->gameModelAttributeTable.attributesByID);
	ModelAttributeEntry *attrib_entry;

	int attribute_count = iterator.GetSize();

	for(int i=Entity__GameModel::AnyAttributeID + 1; i < attribute_count; i++)
	{
		attrib_entry = 
			class_data->gameModelAttributeTable.GetAttributeEntry(i);
		Check_Object(attrib_entry);
		m_entityPropertiesList.AddString(attrib_entry->attributeName);
	}

	char *attribute_text;
	attribute_text = new char[128];
	Register_Pointer(attribute_text);
	char *attribute_name;
	attribute_name = new char[MAX_PATH];
	Register_Pointer(attribute_name);

	for(i=0; i < m_entityPropertiesList.GetCount(); i++)
	{
		m_entityPropertiesList.GetText(i,attribute_name);

		attrib_entry = 
				class_data->gameModelAttributeTable.GetAttributeEntry(attribute_name);
		Check_Object(attrib_entry);

		(*class_data->modelWriteToText)((Entity__GameModel *)model, attrib_entry, &attribute_text);

		m_entityValueList.AddString(attribute_text);

		UndoGameModelChanges* ugmc = new UndoGameModelChanges;
		ugmc->attribute_name = attribute_name;
		ugmc->attribute_value = attribute_text;
		modelUndoChain.Add(ugmc);
	}
	Unregister_Pointer(attribute_name);
	delete [] attribute_name;
	Unregister_Pointer(attribute_text);
	delete [] attribute_text;
}

void EditEntityDlg::OnDblclkEntityProperties() 
{
	switch (dlgType)
	{
	case EDIT_GAME_MODEL:
		{
			Check_Object(selectedEntity);

			char* p = __mbsrchr(selectedEntity->GetModelName(),'\\');
			if (!p)
				p = (char*) selectedEntity->GetModelName();

			if (!strchr(p,'_'))
			{
				if (!warned)
				{
					if (MessageBox("This appears to be a default resource.  Are you really sure you want to change this, DOES SEAN KNOW YOU'RE DOING THIS?",
								   "Hey! This is default data you're messing with!",MB_YESNO) == IDNO)
								return;

					warned = true;
				}
			}
			break;
		}
	case EDIT_DAMAGE_OBJECTARMOR:
		{
			Check_Object(selectedEntity);
			break;
		}
	case EDIT_DAMAGE_OBJECTINTERNAL:
		{
			Check_Object(selectedEntity);
			break;
		}
	default:
		break;
	}
	char buffer[64];
	m_entityValueList.GetText(m_entityValueList.GetCurSel(),buffer);
	RECT r;
	m_entityValueList.GetItemRect(m_entityValueList.GetCurSel(),&r);
	m_entityValueList.ClientToScreen(&r);
	ScreenToClient(&r);
	m_floatingEdit.SetWindowPos(&wndTop,r.left,r.top - 3,r.right - r.left,r.bottom - r.top + 6,SWP_NOZORDER | SWP_SHOWWINDOW);
	m_floatingEdit.SetWindowText(buffer);
	m_floatingEdit.SetFocus();
	m_floatingEdit.SetSel(0,-1);
}

void EditEntityDlg::OnSelchangeEntityProperties() 
{
	m_entityValueList.SetCurSel(m_entityPropertiesList.GetCurSel());
}

void EditEntityDlg::OnSelchangeEntityValues() 
{
	m_entityPropertiesList.SetCurSel(m_entityValueList.GetCurSel());
}

void EditEntityDlg::OnTimer(UINT nIDEvent) 
{
	static int propLast = 0;
	static int valLast = 0;
	static int propTop = 0;
	static int valTop = 0;

	int caret = m_entityPropertiesList.GetCaretIndex();
	if (caret != propLast)
		m_entityValueList.SetCurSel(caret);
	else
	{
		caret = m_entityValueList.GetCaretIndex();
		if (caret != valLast)
			m_entityPropertiesList.SetCurSel(caret);
	}
	
	int top = m_entityPropertiesList.GetTopIndex();
	if (top != propTop)
		m_entityValueList.SetTopIndex(top);
	else
	{
		top = m_entityValueList.GetTopIndex();
		if (top != valTop)
			m_entityPropertiesList.SetTopIndex(top);
	}

	propLast = valLast = caret;
	propTop = valTop = top;
	
	CDialog::OnTimer(nIDEvent);
}

void EditEntityDlg::OnOK() 
{
	// someone in MFC thought it would be a good idea to have this function get called everytime
	// the ENTER key is pressed.

	OnKillfocusEntityeditbox();
}

void EditEntityDlg::OnCancel() 
{
	KillTimer(2);

	switch (dlgType)
	{
	case EDIT_GAME_MODEL:
		{
			Check_Object(selectedEntity);
			UndoGameModelChanges* ugmc;
			ChainIteratorOf<UndoGameModelChanges*> iterator(&modelUndoChain);

			while((ugmc = iterator.ReadAndNext()) != NULL)
			{
				const Entity__GameModel *model = selectedEntity->GetGameModel();
				Check_Object(model);
				Entity::ClassData *class_data;
				class_data = selectedEntity->GetClassData();
				Check_Object(class_data);

				ModelAttributeEntry *attrib_entry;
				attrib_entry = 
						class_data->gameModelAttributeTable.GetAttributeEntry(ugmc->attribute_name.GetBuffer(MAX_PATH));
				Check_Object(attrib_entry);

				char *error_message;
				error_message = new char[256];
				Register_Pointer(error_message);

				(*class_data->modelVerifier)((Entity__GameModel *)model, attrib_entry,
						ugmc->attribute_value.GetBuffer(MAX_PATH), &error_message,255);

				Unregister_Pointer(error_message);
				delete [] error_message;
			}
			break;
		}
	case EDIT_DAMAGE_OBJECTARMOR:
		{
			Check_Object(selectedEntity);
			UndoDamageObjectChanges* udoc;
			ChainIteratorOf<UndoDamageObjectChanges*> undoIterator(&damageUndoChain);
			while((udoc = undoIterator.ReadAndNext()) != NULL)
			{
				SortedChainOf<DamageObject*, int> *chain = NULL;

				if (selectedEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
				{
					MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,selectedEntity);
					chain = &vehicle->damageObjects;
				}
/*
				else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
				{
					Building* building = Cast_Object(Building*,selectedEntity);
					chain = &building->damageObjects;
				}
*/
				Check_Object(chain);
				SortedChainIteratorOf<DamageObject*, int> iterator(chain);
				DamageObject* damObj;

				bool max = false;
				char buffer[256],*p;

				strcpy(buffer,udoc->name.GetBuffer(255));
				
				if (strstr(buffer,"Max"))
					max = true;

				p = strrchr(buffer,'_');
				*p = 0;

				while ((damObj = iterator.ReadAndNext()) != NULL)
				{
					if (!strcmp(damObj->damageObjectName,buffer))
						break;
				}
				Check_Object(damObj);

				if (max)
				{
					damObj->baseArmorValue = udoc->value;
				}
				else
				{
					damObj->currentArmorValue = udoc->value;
				}
			}
			break;
		}
	case EDIT_DAMAGE_OBJECTINTERNAL:
		{
			Check_Object(selectedEntity);
			UndoDamageObjectChanges* udoc;
			ChainIteratorOf<UndoDamageObjectChanges*> undoIterator(&damageUndoChain);
			while((udoc = undoIterator.ReadAndNext()) != NULL)
			{
				SortedChainOf<DamageObject*, int> *chain = NULL;

				if (selectedEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
				{
					MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,selectedEntity);
					chain = &vehicle->damageObjects;
				}
/*
				else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
				{
					Building* building = Cast_Object(Building*,selectedEntity);
					chain = &building->damageObjects;
				}
*/
				Check_Object(chain);
				SortedChainIteratorOf<DamageObject*, int> iterator(chain);
				DamageObject* damObj;

				bool max = false;
				char buffer[256],*p;

				strcpy(buffer,udoc->name.GetBuffer(255));
				
				if (strstr(buffer,"Max"))
					max = true;

				p = strrchr(buffer,'_');
				*p = 0;

				while ((damObj = iterator.ReadAndNext()) != NULL)
				{
					if (!strcmp(damObj->damageObjectName,buffer))
						break;
				}
				Check_Object(damObj);

				if (max)
				{
				//	damObj->baseInternalDamage = udoc->value;
				}
				else
				{
				//	damObj->currentInternalDamage = udoc->value;
				}
			}
			break;
		}
	case EDIT_SUBSYSTEM:
		{
			UndoGameModelChanges* ugmc;
			ChainIteratorOf<UndoGameModelChanges*> iterator(&modelUndoChain);

			while((ugmc = iterator.ReadAndNext()) != NULL)
			{
				char path[MAX_PATH];
				sprintf(path,"%s",(char*)exData);

				Resource subsystem(path);
				Verify(subsystem.DoesResourceExist());
				Resource gameModelResource;
				Entity::GetGameModelResourceFromDataListID(&gameModelResource,subsystem.GetResourceID());

				Entity__GameModel *model = Cast_Pointer(Entity__GameModel*,gameModelResource.GetPointer());
				Check_Object(model);

				Entity::ClassID class_id = Entity::GetClassIDFromDataListID(subsystem.GetResourceID());
				Entity__ClassData* class_data = (Entity__ClassData*)Entity::FindClassData(class_id);
				Check_Object(class_data);

				ModelAttributeEntry *attrib_entry;
				attrib_entry = 
						class_data->gameModelAttributeTable.GetAttributeEntry(ugmc->attribute_name.GetBuffer(MAX_PATH));
				Check_Object(attrib_entry);

				char *error_message;
				error_message = new char[256];
				Register_Pointer(error_message);

				(*class_data->modelVerifier)((Entity__GameModel *)model, attrib_entry,
						ugmc->attribute_value.GetBuffer(MAX_PATH), &error_message,255);

				Unregister_Pointer(error_message);
				delete [] error_message;
			}
			break;
		}
	}
	CDialog::OnCancel();
}

void EditEntityDlg::OnGamemodelsavebtn() 
{
	MessageBox("Not yet implemented.","Not Yet Implimented");
}

void EditEntityDlg::OnChangeEntityeditbox() 
{
	switch (dlgType)
	{
	case EDIT_GAME_MODEL:
		{
			Check_Object(selectedEntity);

			int id = m_entityPropertiesList.GetCaretIndex();
			char *attribute_name;
			attribute_name = new char[MAX_PATH];
			Register_Pointer(attribute_name);
			m_entityPropertiesList.GetText(id, attribute_name);

			const Entity__GameModel *model = selectedEntity->GetGameModel();
			Check_Object(model);
			Entity::ClassData *class_data;
			class_data = selectedEntity->GetClassData();
			Check_Object(class_data);

			ModelAttributeEntry *attrib_entry;
			attrib_entry = 
					class_data->gameModelAttributeTable.GetAttributeEntry(attribute_name);
			Check_Object(attrib_entry);

			CString data;
			m_floatingEdit.GetWindowText(data);

			char *error_message;
			error_message = new char[256];
			Register_Pointer(error_message);

			if(!(*class_data->modelVerifier)((Entity__GameModel *)model, attrib_entry, data.GetBuffer(MAX_PATH), &error_message,255))
			{
				char error[256];
				sprintf(
					error,
					"Error with %s: %s",
					(char *)attrib_entry->attributeName, 
					error_message
				);

				char buffer[64];
				m_entityValueList.GetText(m_entityValueList.GetCurSel(),buffer);
				m_floatingEdit.SetWindowText(buffer);
				m_floatingEdit.ShowWindow(SW_HIDE);
				Invalidate();

				AfxMessageBox(error, MB_OK);
			}

			Unregister_Pointer(attribute_name);
			delete [] attribute_name;
			Unregister_Pointer(error_message);
			delete [] error_message;
			break;
		}
	case EDIT_DAMAGE_OBJECTARMOR:
		{
			Check_Object(selectedEntity);
			char buffer[256],*p;
			m_floatingEdit.GetWindowText(buffer,255);
			Scalar value = (Scalar) atof(buffer);

			SortedChainOf<DamageObject*, int> *chain = NULL;

			if (selectedEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
			{
				MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,selectedEntity);
				chain = &vehicle->damageObjects;
			}
/*
			else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
			{
				Building* building = Cast_Object(Building*,selectedEntity);
				chain = &building->damageObjects;
			}
*/
			Check_Object(chain);
			SortedChainIteratorOf<DamageObject*, int> iterator(chain);
			DamageObject* damObj;

			bool max = false;

			m_entityPropertiesList.GetText(m_entityPropertiesList.GetCurSel(),buffer);
			if (strstr(buffer,"Max"))
				max = true;

			p = strrchr(buffer,'_');
			*p = 0;

			while ((damObj = iterator.ReadAndNext()) != NULL)
			{
				if (!strcmp(damObj->damageObjectName,buffer))
					break;
			}
			Check_Object(damObj);

			if (max)
			{
				damObj->baseArmorValue = value;
			}
			else
			{
				damObj->currentArmorValue = value;
			}
			break;
		}
	case EDIT_DAMAGE_OBJECTINTERNAL:
		{
			Check_Object(selectedEntity);
			char buffer[256],*p;
			m_floatingEdit.GetWindowText(buffer,255);
//			Scalar value = (Scalar) atof(buffer);

			SortedChainOf<DamageObject*, int> *chain = NULL;

			if (selectedEntity->IsDerivedFrom(MechWarrior4::Vehicle::DefaultData))
			{
				MechWarrior4::Vehicle* vehicle = Cast_Object(MechWarrior4::Vehicle*,selectedEntity);
				chain = &vehicle->damageObjects;
			}
/*
			else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
			{
				Building* building = Cast_Object(Building*,selectedEntity);
				chain = &building->damageObjects;
			}
*/
			Check_Object(chain);
			SortedChainIteratorOf<DamageObject*, int> iterator(chain);
			DamageObject* damObj;

			bool max = false;

			m_entityPropertiesList.GetText(m_entityPropertiesList.GetCurSel(),buffer);
			if (strstr(buffer,"Max"))
				max = true;

			p = strrchr(buffer,'_');
			*p = 0;

			while ((damObj = iterator.ReadAndNext()) != NULL)
			{
				if (!strcmp(damObj->damageObjectName,buffer))
					break;
			}
			Check_Object(damObj);

			if (max)
			{
//				damObj->baseInternalDamage = value;
			}
			else
			{
//				damObj->currentInternalDamage = value;
			}
			break;
		}
	case EDIT_SUBSYSTEM:
		{
			char path[MAX_PATH];
			sprintf(path,"%s",(char*)exData);

			Resource subsystem(path);
			Verify(subsystem.DoesResourceExist());
			Resource gameModelResource;
			Entity::GetGameModelResourceFromDataListID(&gameModelResource,subsystem.GetResourceID());

			Entity__GameModel *model = Cast_Pointer(Entity__GameModel*,gameModelResource.GetPointer());
			Check_Object(model);

			Entity::ClassID class_id = Entity::GetClassIDFromDataListID(subsystem.GetResourceID());
			Entity__ClassData* class_data = (Entity__ClassData*)Entity::FindClassData(class_id);
			Check_Object(class_data);

			int id = m_entityPropertiesList.GetCaretIndex();
			char *attribute_name;
			attribute_name = new char[MAX_PATH];
			Register_Pointer(attribute_name);
			m_entityPropertiesList.GetText(id, attribute_name);

			ModelAttributeEntry *attrib_entry;
			attrib_entry = 
					class_data->gameModelAttributeTable.GetAttributeEntry(attribute_name);
			Check_Object(attrib_entry);

			CString data;
			m_floatingEdit.GetWindowText(data);

			char *error_message;
			error_message = new char[256];
			Register_Pointer(error_message);

			if(!(*class_data->modelVerifier)((Entity__GameModel *)model, attrib_entry, data.GetBuffer(MAX_PATH), &error_message,255))
			{
				char error[256];
				sprintf(
					error,
					"Error with %s: %s",
					(char *)attrib_entry->attributeName, 
					error_message
				);

				char buffer[64];
				m_entityValueList.GetText(m_entityValueList.GetCurSel(),buffer);
				m_floatingEdit.SetWindowText(buffer);
				m_floatingEdit.ShowWindow(SW_HIDE);
				Invalidate();

				AfxMessageBox(error, MB_OK);
			}

			Unregister_Pointer(attribute_name);
			delete [] attribute_name;
			Unregister_Pointer(error_message);
			delete [] error_message;
			break;
		}
	}
}

void EditEntityDlg::OnKillfocusEntityeditbox() 
{
	switch (dlgType)
	{
	case EDIT_GAME_MODEL:
	case EDIT_SUBSYSTEM:
		{
			CString data;
			m_floatingEdit.GetWindowText(data);

			int index = m_entityValueList.GetCurSel();
			m_entityValueList.DeleteString(index);
			m_entityValueList.InsertString(index,LPCTSTR(data));
			m_entityValueList.SetCurSel(index);
		}
	case EDIT_DAMAGE_OBJECTARMOR:
	case EDIT_DAMAGE_OBJECTINTERNAL:
		{
			char buffer[256];
			m_floatingEdit.GetWindowText(buffer,255);
			Scalar value = (Scalar) atof(buffer);
			sprintf(buffer,"%3.0f",value);

			int index = m_entityValueList.GetCurSel();
			m_entityValueList.DeleteString(index);
			m_entityValueList.InsertString(index,buffer);
			break;
		}
	}
	m_floatingEdit.ShowWindow(SW_HIDE);
	Invalidate();
}

void EditEntityDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	if (m_entityPropertiesList.m_hWnd)
	{
		RECT pr,vr;

		m_entityPropertiesList.GetWindowRect(&pr);
		ScreenToClient(&pr);
		m_entityValueList.GetWindowRect(&vr);
		ScreenToClient(&vr);

		m_entityPropertiesList.SetWindowPos(NULL,pr.left,pr.top,pr.right - pr.left,cy - pr.top - 6,SWP_NOZORDER);
		m_entityValueList.SetWindowPos(NULL,vr.left,vr.top,vr.right - vr.left,cy - vr.top - 6,SWP_NOZORDER);
	}
}

void EditEntityDlg::OnMyok() 
{
	switch (dlgType)
	{
	case EDIT_GAME_MODEL:
		{
			Resource* resource = selectedEntity->GetDataListResource();
			PlugOf<Resource*> *plug = new PlugOf<Resource*>(resource);
			theApp.dirtyGameModelResources.Add(plug);
			break;
		}
	case EDIT_DAMAGE_OBJECTARMOR:
	case EDIT_DAMAGE_OBJECTINTERNAL:
		{
/*
			char path[MAX_PATH],string[256];
			sprintf(path,"Content\\Mechs\\Damage\\Mech%d.damage",theApp.nextDamageFileID++);
			FILE* file;

			file = fopen(path,"w");
			Register_Pointer(file);

			ChainOf<DamageObject*> *chain = NULL;

			if (selectedEntity->IsDerivedFrom(Vehicle::DefaultData))
			{
				Vehicle* vehicle = Cast_Object(Vehicle*,selectedEntity);
				chain = &vehicle->damageObjects;
			}
//			else if (selectedEntity->IsDerivedFrom(Building::DefaultData))
//			{
//				Building* building = Cast_Object(Building*,selectedEntity);
//				chain = &building->damageObjects;
//			}

			Check_Object(chain);
			ChainIteratorOf<DamageObject*> iterator(chain);
			DamageObject* damObj;

			while ((damObj = iterator.ReadAndNext()) != NULL)
			{
				sprintf(string,"[%s]\n",(char*)damObj->damageObjectName);
				fputs(string,file);

				sprintf(string,"BaseInternalDamage=%f\n",damObj->baseInternalDamage);
				fputs(string,file);

				sprintf(string,"BaseArmorValue=%f\n",damObj->baseArmorValue);
				fputs(string,file);

				sprintf(string,"CurrentInternalDamage=%f\n",damObj->currentInternalDamage);
				fputs(string,file);

				sprintf(string,"CurrentArmorValue=%f\n",damObj->currentArmorValue);
				fputs(string,file);

				for (int i = 0; i < damObj->damageEffects.GetLength(); i++)
				{
					sprintf(string,"DamageEffect=%s,%f\n","ugh",damObj->damageEffects[0].armorPercent);
					fputs(string,file);
				}

				const char* mode = NULL;
				DamageObject::DamageModeTextToAscii(mode);
				sprintf(string,"DamageMode=%s\n",mode);
				fputs(string,file);
			}

			Unregister_Pointer(file);
*/
			break;
		}
	case EDIT_SUBSYSTEM:
		{
			Resource* subsystem = NULL;
			subsystem = new Resource((const char*)exData);
			Check_Object(subsystem);

			PlugOf<Resource*> *plug = new PlugOf<Resource*>(subsystem);
			theApp.dirtyGameModelResources.Add(plug);
			theApp.WriteDirtyGameModels();
			break;
		}
	}
	KillTimer(2);
	
	CDialog::OnOK();
}
