// NFOPropertiesDlg.cpp : implementation file
//

#include "stdafx.h"
#include "NFO File Editor.h"
#include "NFO File EditorDlg.h"
#include "NFOPropertiesDlg.h"
#include "NFORuleDlg.h"
#include "NFOErrorDlg.h"
#include "NFOTeamDlg.h"
#include "NFOBotDlg.h"

#if !defined(STUFF_STUFF_HPP)
	#include "Stuff\Stuff.hpp"
#endif


#include <GameOS\GameOS.hpp>
#include <MFCPlatform\MFCPlatform.hpp>
#include <Stuff\NotationFile.hpp>

#if 0 // def _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CNFOPropertiesDlg dialog


CNFOPropertiesDlg::CNFOPropertiesDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CNFOPropertiesDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CNFOPropertiesDlg)
	//}}AFX_DATA_INIT
}

CNFOPropertiesDlg::~CNFOPropertiesDlg()
{
	// cleanup, yeah!
	RemoveAllTeamInfo();
	RemoveAllBotInfo();
	RemoveAllScriptInfo();
}

void CNFOPropertiesDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CNFOPropertiesDlg)
	DDX_Control(pDX, IDC_NFO_NAME, m_FileName);
	DDX_Control(pDX, IDC_RESTORE, m_Restore);
	DDX_Control(pDX, IDC_NFO_REMOVE_BOT, m_RemoveBot);
	DDX_Control(pDX, IDC_NFO_EDIT_BOT, m_EditBot);
	DDX_Control(pDX, IDC_NFO_BOT_LIST, m_BotList);
	DDX_Control(pDX, IDC_NFO_ADD_BOT, m_AddBot);
	DDX_Control(pDX, IDC_NFO_REMOVE_TEAM, m_RemoveTeam);
	DDX_Control(pDX, IDC_NFO_REMOVE_RULE, m_RemoveRule);
	DDX_Control(pDX, IDC_NFO_EDIT_TEAM, m_EditTeam);
	DDX_Control(pDX, IDC_NFO_EDIT_RULE, m_EditRule);
	DDX_Control(pDX, IDC_NFO_ADD_TEAM, m_AddTeam);
	DDX_Control(pDX, IDC_NFO_ADD_RULE, m_AddRule);
	DDX_Control(pDX, IDC_NFO_TEAM_LIST, m_TeamList);
	DDX_Control(pDX, IDC_NFO_PROPERTY_LIST, m_PropertyList);
	DDX_Control(pDX, IDC_NFO_LONGNAME, m_LongName);
	DDX_Control(pDX, IDC_NFO_LINK, m_Link);
	DDX_Control(pDX, IDC_NFO_INFO, m_Info);
	DDX_Control(pDX, IDC_NFO_AUTHOR, m_Author);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CNFOPropertiesDlg, CDialog)
	//{{AFX_MSG_MAP(CNFOPropertiesDlg)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_NFO_PROPERTY_LIST, OnItemchangedNFOPropertyList)
	ON_BN_CLICKED(IDC_NFO_EDIT_RULE, OnNFOEditRule)
	ON_BN_CLICKED(IDC_NFO_ADD_RULE, OnNFOAddRule)
	ON_BN_CLICKED(IDC_NFO_ADD_TEAM, OnNFOAddTeam)
	ON_BN_CLICKED(IDC_NFO_EDIT_TEAM, OnNFOEditTeam)
	ON_BN_CLICKED(IDC_NFO_REMOVE_RULE, OnNFORemoveRule)
	ON_BN_CLICKED(IDC_NFO_REMOVE_TEAM, OnNFORemoveTeam)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_NFO_TEAM_LIST, OnItemchangedNFOTeamList)
	ON_BN_CLICKED(IDC_NFO_ADD_BOT, OnNFOAddBot)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_NFO_BOT_LIST, OnItemchangedNFOBotList)
	ON_BN_CLICKED(IDC_NFO_EDIT_BOT, OnNFOEditBot)
	ON_BN_CLICKED(IDC_NFO_REMOVE_BOT, OnNFORemoveBot)
	ON_BN_CLICKED(IDC_RESTORE, OnRestore)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CNFOPropertiesDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	m_pTeamInfo = NULL;
	m_pBotInfo = NULL;

	for (int i = 0; i < GameTypeCount; i++)
		m_pScriptInfo[i] = NULL;

	// Set up the columns
	m_PropertyList.InsertColumn(0, "Rule Name", LVCFMT_LEFT, 70, 1);
	m_PropertyList.InsertColumn(1, "Rule Set", LVCFMT_LEFT, 150, 2);
	m_PropertyList.InsertColumn(2, "Scenario Name", LVCFMT_LEFT, 90, 3);
	m_PropertyList.InsertColumn(3, "Team Allowed", LVCFMT_LEFT, 80, 4);
	m_PropertyList.InsertColumn(4, "Team Count", LVCFMT_LEFT, 80, 5);
	m_PropertyList.InsertColumn(5, "Scenario Text File Name", LVCFMT_LEFT, 150, 6);
	m_PropertyList.InsertColumn(6, "Kill Limit Allowed", LVCFMT_LEFT, 100, 7);
	m_PropertyList.InsertColumn(7, "Kill Limit Count", LVCFMT_LEFT, 90, 8);
	m_PropertyList.InsertColumn(8, "Respawn Limit Allowed", LVCFMT_LEFT, 130, 9);
	m_PropertyList.InsertColumn(9, "Respawn Limit Count", LVCFMT_LEFT, 120, 10);
	m_PropertyList.InsertColumn(10, "Night", LVCFMT_LEFT, 50, 11);
	m_PropertyList.InsertColumn(11, "Weather", LVCFMT_LEFT, 60, 12);
	m_PropertyList.InsertColumn(12, "Radar Mode", LVCFMT_LEFT, 80, 13);
	m_PropertyList.InsertColumn(13, "Stock 'Mechs Only", LVCFMT_LEFT, 120, 14);
	m_PropertyList.InsertColumn(14, "Max Tonnage", LVCFMT_LEFT, 80, 15);
	m_PropertyList.InsertColumn(15, "Min Tonnage", LVCFMT_LEFT, 80, 16);
	m_PropertyList.InsertColumn(16, "Game Length", LVCFMT_LEFT, 80, 17);
	m_PropertyList.InsertColumn(17, "Custom Script Name", LVCFMT_LEFT, 120, 18);
	m_PropertyList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
	m_TeamList.InsertColumn(0, "Team #", LVCFMT_LEFT, 50, 0);
	m_TeamList.InsertColumn(1, "Max Tonnage", LVCFMT_LEFT, 80, 1);
	m_TeamList.InsertColumn(2, "Min Tonnage", LVCFMT_LEFT, 80, 2);
	m_TeamList.InsertColumn(3, "Max Total Tonnage", LVCFMT_LEFT, 100, 3);
	m_TeamList.InsertColumn(4, "Max # of Players", LVCFMT_LEFT, 100, 4);
	m_TeamList.InsertColumn(5, "Skin", LVCFMT_LEFT, 50, 5);
	m_TeamList.InsertColumn(6, "Alignment", LVCFMT_LEFT, 80, 6);
	m_TeamList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
	m_BotList.InsertColumn(0, "Rule #", LVCFMT_LEFT, 60, 0);
	m_BotList.InsertColumn(1, "# of Bots", LVCFMT_LEFT, 60, 1);
	m_BotList.InsertColumn(2, "Team #", LVCFMT_LEFT, 50, 2);
	m_BotList.InsertColumn(3, "Max Tonnage", LVCFMT_LEFT, 80, 3);
	m_BotList.InsertColumn(4, "Min Tonnage", LVCFMT_LEFT, 80, 4);
	m_BotList.InsertColumn(5, "Max AI Level", LVCFMT_LEFT, 80, 5);
	m_BotList.InsertColumn(6, "Min AI Level", LVCFMT_LEFT, 80, 6);
	m_BotList.SetExtendedStyle(LVS_EX_FULLROWSELECT);

	CNFOFileEditorDlg* pParent = (CNFOFileEditorDlg*) GetOwner();

	if (pParent->m_bEditNFO)
	{
		int value = LoadNFO();
		ASSERT(value == TRUE);
		if (value == FALSE)
		{
			CDialog::OnOK();
			return TRUE;
		}
	}
	else
	{
		m_FileName.SetWindowText("new.nfo");
		m_Restore.EnableWindow(FALSE);
	}
	
	m_EditRule.EnableWindow(FALSE);
	m_RemoveRule.EnableWindow(FALSE);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}
	
BOOL CNFOPropertiesDlg::LoadNFO()
{
	CNFOFileEditorDlg* pParent = (CNFOFileEditorDlg*) GetOwner();

	// Get the current selected NFO
	int curSel = pParent->m_NFOList.GetCurSel();
	ASSERT(curSel != LB_ERR);
	if (curSel == LB_ERR)
		return FALSE;
	
	// Get the name of the NFO
	char filename[256];
	int text_value = pParent->m_NFOList.GetText(curSel, filename);
	ASSERT(text_value != LB_ERR);
	if (text_value == LB_ERR)
		return FALSE;

	m_FileName.SetWindowText(filename);
	
	// Now use the notation file
	Stuff::MString nfo_name;
	int mission = pParent->m_MissionList.GetCurSel();
	switch (mission)
	{
	case 0: // missions
		nfo_name = "resource\\Missions\\";
		break;
	case 1:
		nfo_name = "resource\\UserMissions\\";
		break;
	}
	nfo_name += filename;
	Stuff::NotationFile notefile(nfo_name, Stuff::NotationFile::Standard, true);

	// First grab some of the important info in the file
	Stuff::Page *page = notefile.FindPage("info");
	if (page != NULL)
	{
		const char* buffer = '\0';
		page->GetEntry("Author", &buffer);
		m_Author.SetSel(0, -1);
		m_Author.Clear();
		m_Author.ReplaceSel(buffer);
		page->GetEntry("info", &buffer);
		m_Info.SetSel(0, -1);
		m_Info.Clear();
		m_Info.ReplaceSel(buffer);
		page->GetEntry("link", &buffer);
		m_Link.SetSel(0, -1);
		m_Link.Clear();
		m_Link.ReplaceSel(buffer);
		page->GetEntry("longname", &buffer);
		m_LongName.SetSel(0, -1);
		m_LongName.Clear();
		m_LongName.ReplaceSel(buffer);
	}
	
	m_PropertyList.DeleteAllItems();
	m_TeamList.DeleteAllItems();
	m_BotList.DeleteAllItems();
	RemoveAllTeamInfo();
	RemoveAllBotInfo();

	// Then see if we have a ruleset tab and if so, collect the available rules
	BOOL bTypeExists = FALSE;
	for (int j = 0; j < GameTypeCount; j++)
	{
		m_bTypeAvailable[j] = FALSE;
	}
	m_bSinglePlayer = FALSE;
	// Set default for max team and max alignment
	m_iMaxTeam[0] = 0;
	m_iMaxTeam[1] = 8;
	m_iMaxTeam[2] = 0;
	m_iMaxTeam[3] = 8;
	m_iMaxTeam[4] = 2;
	m_iMaxTeam[5] = 0;
	m_iMaxTeam[6] = 8;
	m_iMaxTeam[7] = 8;
	m_iMaxTeam[8] = 0;
	m_iMaxTeam[9] = 8;
	m_iMaxTeam[10] = 0;
	m_iMaxTeam[11] = 4;
	m_iMaxTeam[12] = 0;
	m_iMaxTeam[13] = 0;
	m_iMaxTeam[14] = 8;
	m_iMaxTeam[15] = 0;
	m_iMaxTeam[16] = 8;
	m_iMaxTeam[17] = 2;
	m_iMaxTeam[18] = 0;
	m_iMaxTeam[19] = 8;
	m_iMaxTeam[20] = 8;
	m_iMaxTeam[21] = 0;
	m_iMaxTeam[22] = 8;
	m_iMaxTeam[23] = 8;
	m_iMaxTeam[24] = 4;
	m_iMaxTeam[25] = 8;
	m_iMaxTeam[26] = 8;
	m_iMaxAlignment[0] = 0;
	m_iMaxAlignment[1] = 6;
	m_iMaxAlignment[2] = 0;
	m_iMaxAlignment[3] = 6;
	m_iMaxAlignment[4] = 2;
	m_iMaxAlignment[5] = 0;
	m_iMaxAlignment[6] = 6;
	m_iMaxAlignment[7] = 6;
	m_iMaxAlignment[8] = 0;
	m_iMaxAlignment[9] = 6;
	m_iMaxAlignment[10] = 0;
	m_iMaxAlignment[11] = 2;
	m_iMaxAlignment[12] = 0;
	m_iMaxAlignment[13] = 0;
	m_iMaxAlignment[14] = 6;
	m_iMaxAlignment[15] = 0;
	m_iMaxAlignment[16] = 6;
	m_iMaxAlignment[17] = 2;
	m_iMaxAlignment[18] = 0;
	m_iMaxAlignment[19] = 6;
	m_iMaxAlignment[20] = 6;
	m_iMaxAlignment[21] = 0;
	m_iMaxAlignment[22] = 6;
	m_iMaxAlignment[23] = 6;
	m_iMaxAlignment[24] = 2;
	m_iMaxAlignment[25] = 6;
	m_iMaxAlignment[26] = 6;
	page = notefile.FindPage("ruleset");
	if (page != NULL)
	{
		Stuff::ChainIteratorOf<Stuff::Note*> *note_iterator = page->MakeNoteIterator();

		Stuff::Note *note;		
		int rule_set = -1;
		int max_team = -1;
		int max_alignment = -1;
		const char* script = NULL;
		while ((note = note_iterator->ReadAndNext()) != NULL)
		{
			if (_stricmp(note->GetName(), "type") == 0)
			{
				note->GetEntry(&rule_set);
				
				// store single player if available
				if (rule_set == SinglePlayer)
				{
					m_bSinglePlayer = TRUE;
					continue;
				}

				if ((rule_set > -1) && (rule_set < GameTypeCount))
				{
					m_bTypeAvailable[rule_set] = TRUE;
					bTypeExists = TRUE;
				}
			}
			else
			{
				if ((rule_set > -1) && (rule_set < GameTypeCount))
				{
					if (_stricmp(note->GetName(), "team") == 0)
					{
						note->GetEntry(&max_team);
						if ((max_team > -1) && (max_team < 9))
							m_iMaxTeam[rule_set] = max_team;
					}
					else if (_stricmp(note->GetName(), "alignment") == 0)
					{
						note->GetEntry(&max_alignment);
						if ((max_alignment > -1) && (max_alignment < 7))
							m_iMaxAlignment[rule_set] = max_alignment;
					}
					else if (_stricmp(note->GetName(), "scriptName") == 0)
					{
						note->GetEntry(&script);
						if ((rule_set >= CustomAttrition) && (rule_set <= CustomUndefined) && (script != NULL))
						{
							SCRIPT_INFO* pInfo = new SCRIPT_INFO;
							strncpy(pInfo->script, script, 256);
							pInfo->pNext = NULL;
							
							SCRIPT_INFO* pCurInfo = m_pScriptInfo[rule_set];
							if (pCurInfo == NULL)
								m_pScriptInfo[rule_set] = pInfo;
							else
							{
								while (pCurInfo->pNext != NULL)
									pCurInfo = pCurInfo->pNext;
								pCurInfo->pNext = pInfo;
							}
						}
					}
				}
			}
		}
	}

	// Grab the scenarios
	page = notefile.FindPage("scenarios");
	if (page != NULL)
	{
		Stuff::ChainIteratorOf<Stuff::Note*> *note_iterator = page->MakeNoteIterator();

		Stuff::Note *note;
		int scenario_count = 0;
		char intbuf[256];
		while ((note = note_iterator->ReadAndNext()) != NULL)
		{
			Stuff::NotationFile scenario_file;
			note->GetEntry(&scenario_file);
				
			Stuff::Page *server_page = scenario_file.FindPage("server");
			if (server_page != NULL)
			{
				const char *scenario_name = NULL;
				const char *scenario_read_name = NULL;
				int rule_set = -1;
				int team_allowed = -1;
				int team_count = -1;
				const char *scenario_text = NULL;
				int kill_allowed = -1;
				int kill_count = -1;
				int respawn_allowed = -1;
				int respawn_count = -1;
				int night = -1;
				int weather = -1;
				int radar_mode = -1;
				int stock_mech_only = -1;
				int max_ton = -1;
				int min_ton = -1;
				int game_len = -1;
				const char *script = NULL;

				scenario_name = note->GetName();
				server_page->GetEntry("ruleset",&rule_set);
				server_page->GetEntry("name",&scenario_read_name);
				server_page->GetEntry("teamAllowed",&team_allowed);
				server_page->GetEntry("teamCount",&team_count);
				server_page->GetEntry("scenarioText",&scenario_text);
				server_page->GetEntry("killLimit", &kill_allowed);
				server_page->GetEntry("killLimitNumber", &kill_count);
				server_page->GetEntry("respawnLimit", &respawn_allowed);
				server_page->GetEntry("respawnLimitNumber", &respawn_count);
				server_page->GetEntry("isNight", &night);	
				server_page->GetEntry("weather", &weather);
				server_page->GetEntry("radarMode", &radar_mode);
				server_page->GetEntry("onlyStockMech", &stock_mech_only);
				server_page->GetEntry("maximumTonnage", &max_ton);
				server_page->GetEntry("minimumTonnage", &min_ton);
				server_page->GetEntry("gameLength", &game_len);
				server_page->GetEntry("scriptName", &script);

				if ((scenario_name == NULL) || (scenario_name[0] == '\0') ||
					(scenario_read_name == NULL) || (scenario_read_name[0] == '\0'))
				{
					// skip the current scenario
					continue;
				}		
				
				m_PropertyList.InsertItem(scenario_count, scenario_name);

				if (!((rule_set > -1) && (rule_set < GameTypeCount)))
				{
					rule_set = 0;
					m_bTypeAvailable[0] = TRUE;
				}
				else
				{
					// if current rule set is valid and no [ruleset] tag exists, store the rule
					if (bTypeExists == FALSE)
						m_bTypeAvailable[rule_set] = TRUE;
					else
					{
						if (m_bTypeAvailable[rule_set] == FALSE)
						{
							rule_set = 0;
							m_bTypeAvailable[0] = TRUE;
						}
					}
				}
				if (pParent->m_iTeam[rule_set] == 1)
				{
					if (team_allowed == 1)
					{
						if (!((team_count > 0) && (team_count < 9)))
							team_count = 8;
					}
					else
					{
						team_allowed = 1;
						team_count = 8;
					}
				}
				else
				{
					team_allowed = 0;
					team_count = 0;
				}
				m_PropertyList.SetItemText(scenario_count, 1, pParent->m_szScenarioName[rule_set]);				
				m_PropertyList.SetItemText(scenario_count, 2, scenario_read_name);
				m_PropertyList.SetItemText(scenario_count, 3, pParent->m_szYesNo[team_allowed]);
				m_PropertyList.SetItemText(scenario_count, 4, _itoa(team_count, intbuf, 10));
				if (scenario_text != NULL)
					m_PropertyList.SetItemText(scenario_count, 5, scenario_text);
				else
					m_PropertyList.SetItemText(scenario_count, 5, "\0");
				if ((kill_allowed > -1) && (kill_allowed < 2))
				{
					m_PropertyList.SetItemText(scenario_count, 6, pParent->m_szYesNo[kill_allowed]);
					if (kill_allowed == 1)
					{
						if ((kill_count > 0) && (kill_count < 100))
							m_PropertyList.SetItemText(scenario_count, 7, _itoa(kill_count, intbuf, 10));
						else
							m_PropertyList.SetItemText(scenario_count, 7, "10");
					}
					else
					{
						m_PropertyList.SetItemText(scenario_count, 7, "0");
					}
				}
				if (respawn_allowed != -1)
				{
					m_PropertyList.SetItemText(scenario_count, 8, pParent->m_szYesNo[respawn_allowed]);
					if (respawn_allowed == 1)
					{
						if ((respawn_count > 0) && (respawn_count < 100))
							m_PropertyList.SetItemText(scenario_count, 9, _itoa(respawn_count, intbuf, 10));
						else
							m_PropertyList.SetItemText(scenario_count, 9, "10");
					}
					else
					{
						m_PropertyList.SetItemText(scenario_count, 9, "0");
					}
				}
				if ((night > -1) && (night < 2))
					m_PropertyList.SetItemText(scenario_count, 10, pParent->m_szTOD[night]);
				if ((weather > -1) && (weather < 2))
					m_PropertyList.SetItemText(scenario_count, 11, pParent->m_szYesNo[weather]);
				if ((radar_mode > -1) && (radar_mode < 2))
					m_PropertyList.SetItemText(scenario_count, 12, pParent->m_szRadar[radar_mode]);
				if ((stock_mech_only > -1) && (stock_mech_only < 2))
					m_PropertyList.SetItemText(scenario_count, 13, pParent->m_szYesNo[stock_mech_only]);				
				if ((max_ton >= 25) && (max_ton <= 100))
				{
					m_PropertyList.SetItemText(scenario_count, 14, _itoa(max_ton, intbuf, 10));
				}
				if ((min_ton >= 25) && (min_ton <= 100))
				{
					m_PropertyList.SetItemText(scenario_count, 15, _itoa(min_ton, intbuf, 10));
				}
				if ((max_ton != -1) && (min_ton != -1) && (max_ton < min_ton))
				{
					m_PropertyList.SetItemText(scenario_count, 14, "");
					m_PropertyList.SetItemText(scenario_count, 15, "");
				}
				if ((game_len > 0) && (game_len <= 120))
					m_PropertyList.SetItemText(scenario_count, 16, _itoa(game_len, intbuf, 10));
				if (script != NULL)
					m_PropertyList.SetItemText(scenario_count, 17, script);


				TEAM_INFO* pTeamdata = new TEAM_INFO;
				BOT_INFO* pBotdata = new BOT_INFO;	
				if ((!pTeamdata) || (!pBotdata))
				{
					CNFOErrorDlg dlg;
					dlg.m_Error = "Not enough memory to view the current NFO file.";
					dlg.DoModal();

					return FALSE;
				}

				// Do the team data
				int count = 0;
				if ((team_allowed == 1) && (team_count > 0) && (team_count < 9))
				{
					for (int i = 0; i < team_count; ++i)
					{
						Stuff::NotationFile team_file;
						char team_str[50];
						sprintf(&team_str[0], "team_%d", i);
						if (server_page->GetEntry(team_str, &team_file))
						{
							Stuff::Page* team_page = team_file.FindPage("teamdata");
							if (team_page)
							{
								int max_ton = -1;
								int min_ton = -1;
								int max_total_ton = -1;
								int max_team_count = -1;
								const char *skin = NULL;
								int alignment = -1;

								team_page->GetEntry("maximumTonnage", &max_ton);
								team_page->GetEntry("minimumTonnage", &min_ton);
								team_page->GetEntry("maximumTotalTonnage", &max_total_ton);
								team_page->GetEntry("maxPlayersOnTeam", &max_team_count);
								team_page->GetEntry("skin", &skin);
								team_page->GetEntry("alignment", &alignment);

								pTeamdata->team_num[i] = i + 1;
				
								if ((max_ton >= 25) && (max_ton <= 100))
									pTeamdata->max_ton[i] = max_ton;
								else
									pTeamdata->max_ton[i] = -1;
								if ((min_ton >= 25) && (min_ton <= 100))
									pTeamdata->min_ton[i] = min_ton;
								else
									pTeamdata->min_ton[i] = -1;
								if ((max_total_ton >= 100) && (max_total_ton <= 1600))
									pTeamdata->max_total_ton[i] = max_total_ton;
								else
									pTeamdata->max_total_ton[i] = -1;
								if ((max_ton != -1) && (min_ton != -1) && (max_ton < min_ton))
								{
									pTeamdata->max_ton[i] = -1;
									pTeamdata->min_ton[i] = -1;
								}
								if ((max_team_count > 0) && (max_team_count <= 16))
									pTeamdata->max_team_count[i] = max_team_count;
								else
									pTeamdata->max_team_count[i] = -1;
								// 0 to 9 and a to z
								if ((skin != NULL) && (((skin[0] >= '0') && (skin[0] <= '9')) || ((skin[0] >= 'a') && (skin[0] <= 'z'))))
									pTeamdata->skin[i] = skin[0];
								else
									pTeamdata->skin[i] = (char) -1;
								if ((alignment >= 0) && (alignment < 8))
									pTeamdata->alignment[i] = alignment;
								else
									pTeamdata->alignment[i] = -1;
							}
							else
							{
								pTeamdata->team_num[i] = i + 1;
								pTeamdata->max_ton[i] = -1;
								pTeamdata->min_ton[i] = -1;
								pTeamdata->max_total_ton[i] = -1;
								pTeamdata->max_team_count[i] = -1;
								pTeamdata->skin[i] = (char) -1;
								pTeamdata->alignment[i] = -1;
							}
							
							count = i + 1;
						}
						else
							pTeamdata->team_num[i] = -1;
					}

					pTeamdata->team_count = count;
				}
				else
					pTeamdata->team_count = 0;

				AppendTeamInfo(pTeamdata);

				// Do the bot data
				count = 0;
				for (int i = 0; i < 14; ++i)
				{
					Stuff::NotationFile bot_file;
					char bot_str[50];
					sprintf(&bot_str[0], "bot_%d", i);
					
					if (server_page->GetEntry(bot_str, &bot_file))
					{
						Stuff::Page* bot_page = bot_file.FindPage("botdata");
						if (bot_page)
						{
							int bot_count = -1;
							int team_num = -1;
							int max_ton = -1;
							int min_ton = -1;
							int max_level = -1;
							int min_level = -1;

							bot_page->GetEntry("botCount", &bot_count);
							bot_page->GetEntry("team", &team_num);
							bot_page->GetEntry("maximumTonnage", &max_ton);
							bot_page->GetEntry("minimumTonnage", &min_ton);
							bot_page->GetEntry("maximumLevel", &max_level);
							bot_page->GetEntry("minimumLevel", &min_level);

							if ((bot_count > 0) && (bot_count <= 14))
								pBotdata->bot_count[i] = bot_count;
							else
								pBotdata->bot_count[i] = -1;
							if (team_allowed == 1)
							{
								if ((team_num > 0) && (team_num <= team_count))
									pBotdata->team_num[i] = team_num;
								else
									pBotdata->team_num[i] = 1;
							}
							else
								pBotdata->team_num[i] = -1;	
							if ((max_ton >= 25) && (max_ton <= 100))
								pBotdata->max_ton[i] = max_ton;
							else
								pBotdata->max_ton[i] = -1;
							if ((min_ton >= 25) && (min_ton <= 100))
								pBotdata->min_ton[i] = min_ton;
							else
								pBotdata->min_ton[i] = -1;
							if ((max_ton != -1) && (min_ton != -1) && (max_ton < min_ton))
							{
								pBotdata->max_ton[i] = -1;
								pBotdata->min_ton[i] = -1;
							}
							if ((max_level >= 0) && (max_level <= 9))
								pBotdata->max_level[i] = max_level;
							else
								pBotdata->max_level[i] = -1;
							if ((min_level >= 0) && (min_level <= 9))
								pBotdata->min_level[i] = min_level;
							else
								pBotdata->min_level[i] = -1;
							if ((max_level != -1) && (min_level != -1) && (max_level < min_level))
							{
								pBotdata->max_level[i] = -1;
								pBotdata->min_level[i] = -1;
							}
						}
						else
						{
							pBotdata->bot_count[i] = -1;
							pBotdata->team_num[i] = -1;
							pBotdata->max_ton[i] = -1;
							pBotdata->min_ton[i] = -1;
							pBotdata->max_level[i] = -1;
							pBotdata->min_level[i] = -1;
						}
						
						count++;
					}
					else
					{
						// if no more bot rule, break
						break;
					}
				}

				pBotdata->rule_count = count;
				AppendBotInfo(pBotdata);

				scenario_count++;
			}
		}
		
		delete note_iterator;
	}

	m_AddTeam.EnableWindow(FALSE);
	m_EditTeam.EnableWindow(FALSE);
	m_RemoveTeam.EnableWindow(FALSE);

	m_AddBot.EnableWindow(FALSE);
	m_EditBot.EnableWindow(FALSE);
	m_RemoveBot.EnableWindow(FALSE);

	return TRUE;
}


BOOL CNFOPropertiesDlg::SaveNFO()
{
	CNFOFileEditorDlg* pParent = (CNFOFileEditorDlg*) GetOwner();

	char filename[256];
	m_FileName.GetWindowText(filename, 256);
	
	// Now use the notation file	
	Stuff::MString nfo_name;
	int mission = pParent->m_MissionList.GetCurSel();
	switch (mission)
	{
	case 0: // missions
		nfo_name = "resource\\Missions\\";
		break;
	case 1:
		nfo_name = "resource\\UserMissions\\";
		break;
	}
	nfo_name += filename;
	Stuff::NotationFile notefile(nfo_name, Stuff::NotationFile::Standard, true);

	Stuff::Page *bang_page = notefile.AddPage("");
	bang_page->AppendEntry("!include", "Content\\GameTypes.h");
	bang_page->AppendEntry("!preservecase", "true");

	Stuff::Page *page = notefile.AddPage("info");
	if (page != NULL)
	{
		char author[256];
		char info[256];
		char link[256];
		char longname[256];
		int length = 0;

		length = m_Author.GetLine(0, author, 256);
		author[length] = '\0';
		length = m_Info.GetLine(0, info, 256);
		info[length] = '\0';
		length = m_Link.GetLine(0, link, 256);
		link[length] = '\0';
		length = m_LongName.GetLine(0, longname, 256);
		longname[length] = '\0';

		page->AppendEntry("author", author);
		page->AppendEntry("info", info);
		page->AppendEntry("link", link);
		page->AppendEntry("longname", longname);
	}

	page = notefile.AddPage("ruleset");
	if (page != NULL)
	{
		for (int i = 0; i < GameTypeCount; i++)
		{
			if (m_bTypeAvailable[i] == TRUE)
			{
				page->AppendEntry("type", pParent->m_szScenarioGameTypeName[i]);
				if (pParent->m_iTeam[i] == TRUE)
				{
					page->AppendEntry("team", m_iMaxTeam[i]);
					page->AppendEntry("alignment", m_iMaxAlignment[i]);
				}

				SCRIPT_INFO* pInfo = m_pScriptInfo[i];
				while (pInfo != NULL)
				{
					page->AppendEntry("scriptName", pInfo->script);
					pInfo = pInfo->pNext;
				}
			}
		}

		if (m_bSinglePlayer == TRUE)
		{
			page->AppendEntry("type", "$(SinglePlayer)");
		}
	}

	page = notefile.AddPage("scenarios");
	if (page != NULL)
	{
		int scenario_count = m_PropertyList.GetItemCount();
		for (int count = 0; count < scenario_count; count++)
		{
			char scenario_name[256];
			char rule_set[256];
			char map_name[256];
			char team_allowed[256];
			char team_count[256];
			char scenario_text[256];	
			char kill_allowed[256];
			char kill_count[256];
			char respawn_allowed[256];
			char respawn_count[256];
			char night[256];
			char weather[256];
			char radar_mode[256];
			char stock_mech_only[256];
			char max_ton[256];
			char min_ton[256];
			char game_len[256];
			char script[256];
				
			char intbuf[256];
			int i = 0;

			m_PropertyList.GetItemText(count, 0, scenario_name, 256);
			m_PropertyList.GetItemText(count, 1, rule_set, 256);
			m_PropertyList.GetItemText(count, 2, map_name, 256);
			m_PropertyList.GetItemText(count, 3, team_allowed, 256);
			m_PropertyList.GetItemText(count, 4, team_count, 256);
			m_PropertyList.GetItemText(count, 5, scenario_text, 256);
			m_PropertyList.GetItemText(count, 6, kill_allowed, 256);
			m_PropertyList.GetItemText(count, 7, kill_count, 256);
			m_PropertyList.GetItemText(count, 8, respawn_allowed, 256);
			m_PropertyList.GetItemText(count, 9, respawn_count, 256);
			m_PropertyList.GetItemText(count, 10, night, 256);
			m_PropertyList.GetItemText(count, 11, weather, 256);
			m_PropertyList.GetItemText(count, 12, radar_mode, 256);
			m_PropertyList.GetItemText(count, 13, stock_mech_only, 256);
			m_PropertyList.GetItemText(count, 14, max_ton, 256);
			m_PropertyList.GetItemText(count, 15, min_ton, 256);
			m_PropertyList.GetItemText(count, 16, game_len, 256);
			m_PropertyList.GetItemText(count, 17, script, 256);
			Stuff::Note* note = page->AddNote(scenario_name);

			Stuff::NotationFile scenario_file;

			Stuff::Page* scenario_page = scenario_file.AddPage("server");
			for (i = 0; i < GameTypeCount; i++)
			{
				if (_stricmp(rule_set, pParent->m_szScenarioName[i]) == 0)
				{
					scenario_page->AppendEntry("	ruleset", pParent->m_szScenarioGameTypeName[i]);
				}
			}
			scenario_page->AppendEntry("	name", map_name);
			if (_stricmp(team_allowed, pParent->m_szYesNo[0]) == 0)
				scenario_page->AppendEntry("	teamAllowed", "0");
			else
				scenario_page->AppendEntry("	teamAllowed", "1");
			scenario_page->AppendEntry("	teamcount", atoi(team_count));
			if (scenario_text[0] != '\0')
				scenario_page->AppendEntry("	scenariotext", scenario_text);
			if (kill_allowed[0] != '\0')
			{
				if (_stricmp(kill_allowed, pParent->m_szYesNo[0]) == 0)
					scenario_page->AppendEntry("	killLimit", "0");
				else
					scenario_page->AppendEntry("	killLimit", "1");
			}
			if (kill_count[0] != '\0')
				scenario_page->AppendEntry("	killLimitNumber", atoi(kill_count));
			if (respawn_allowed[0] != '\0')
			{
				if (_stricmp(respawn_allowed, pParent->m_szYesNo[0]) == 0)
					scenario_page->AppendEntry("	respawnLimit", "0");
				else
					scenario_page->AppendEntry("	respawnLimit", "1");
			}
			if (respawn_count[0] != '\0')
				scenario_page->AppendEntry("	respawnLimitNumber", atoi(respawn_count));
			if (night[0] != '\0')
			{
				if (_stricmp(night, pParent->m_szTOD[0]) == 0)
					scenario_page->AppendEntry("	isNight", "0");
				else
					scenario_page->AppendEntry("	isNight", "1");
			}	
			if (weather[0] != '\0')
			{
				if (_stricmp(weather, pParent->m_szYesNo[0]) == 0)
					scenario_page->AppendEntry("	weather", "0");
				else
					scenario_page->AppendEntry("	weather", "1");
			}
			for (i = 0; i < 3; i++)
			{
				if (_stricmp(radar_mode, pParent->m_szRadar[i]) == 0)
				{
					scenario_page->AppendEntry("	radarmode", _itoa(i, intbuf, 10));
				}
			}
			if (stock_mech_only[0] != '\0')
			{
				if (_stricmp(stock_mech_only, pParent->m_szYesNo[0]) == 0)
					scenario_page->AppendEntry("	onlyStockMech", "0");
				else
					scenario_page->AppendEntry("	onlyStockMech", "1");
			}
			if (max_ton[0] != '\0')
				scenario_page->AppendEntry("	maximumtonnage", atoi(max_ton));
			if (min_ton[0] != '\0')
				scenario_page->AppendEntry("	minimumtonnage", atoi(min_ton));
			if (game_len[0] != '\0')
				scenario_page->AppendEntry("	gameLength", atoi(game_len));
			if (script[0] != '\0')
				scenario_page->AppendEntry("	scriptName", script);

			// save out the teams
			if ((_stricmp(team_allowed, pParent->m_szYesNo[1]) == 0) && atoi(team_count))
			{
				TEAM_INFO* pTeamInfo = FindTeamInfo(count);
				ASSERT(pTeamInfo != NULL);
				for (i = 0; i < pTeamInfo->team_count; i++)
				{
					if (pTeamInfo->team_num[i] != -1)
					{
						char team_name[256];
						sprintf(&team_name[0], "team_%d", i);
						Stuff::Note* team_note = scenario_page->AddNote(team_name);
						Stuff::NotationFile team_file;
						Stuff::Page* team_page = team_file.AddPage("teamdata");

						if (pTeamInfo->max_ton[i] != -1)
							team_page->AppendEntry("	maximumTonnage", pTeamInfo->max_ton[i]);
						if (pTeamInfo->min_ton[i] != -1)
							team_page->AppendEntry("	minimumTonnage", pTeamInfo->min_ton[i]);
						if (pTeamInfo->max_total_ton[i] != -1)
							team_page->AppendEntry("	maximumTotalTonnage", pTeamInfo->max_total_ton[i]);
						if (pTeamInfo->max_team_count[i] != -1)
							team_page->AppendEntry("	MaxPlayersOnTeam", pTeamInfo->max_team_count[i]);
						if (pTeamInfo->skin[i] != (char) -1)
						{
							char skin[2];
							skin[0] = pTeamInfo->skin[i];
							skin[1] = '\0';
							team_page->AppendEntry("	Skin", skin);
						}
						if (pTeamInfo->alignment[i] != -1)
							team_page->AppendEntry("	Alignment", pTeamInfo->alignment[i]);

						team_note->SetEntry(&team_file);
					}
				}
			}
				
			// save out the bots
			BOT_INFO* pBotInfo = FindBotInfo(count);
			ASSERT(pBotInfo != NULL);
			for (i = 0; i < pBotInfo->rule_count; i++)
			{
				char bot_name[256];
				sprintf(&bot_name[0], "bot_%d", i);
				Stuff::Note* bot_note = scenario_page->AddNote(bot_name);
				Stuff::NotationFile bot_file;
				Stuff::Page* bot_page = bot_file.AddPage("botdata");

				if (pBotInfo->bot_count[i] != -1)
					bot_page->AppendEntry("	botCount", pBotInfo->bot_count[i]);
				if (pBotInfo->team_num[i] != -1)
					bot_page->AppendEntry("	team", pBotInfo->team_num[i]);
				if (pBotInfo->max_ton[i] != -1)
					bot_page->AppendEntry("	maximumTonnage", pBotInfo->max_ton[i]);
				if (pBotInfo->min_ton[i] != -1)
					bot_page->AppendEntry("	minimumTonnage", pBotInfo->min_ton[i]);
				if (pBotInfo->max_level[i] != -1)
					bot_page->AppendEntry("	maximumLevel", pBotInfo->max_level[i]);
				if (pBotInfo->min_level[i] != -1)
					bot_page->AppendEntry("	minimumLevel", pBotInfo->min_level[i]);

				bot_note->SetEntry(&bot_file);
			}

			note->SetEntry(&scenario_file);
		}
	}

	notefile.Save();

	return TRUE;
}

void CNFOPropertiesDlg::RefreshBotList(BOT_INFO* pBotInfo, int nSelected)
{
	CNFOFileEditorDlg* pParent = (CNFOFileEditorDlg*) GetOwner();

	m_BotList.DeleteAllItems();

	int i;
	char intbuf[256];
	if (pBotInfo->rule_count)
	{
		for (i = 0; i < pBotInfo->rule_count; i++)
		{
			LVITEM item;
			item.mask = LVIF_TEXT;
			item.iItem = i;
			item.iSubItem = 0;
			item.pszText = _itoa(i, intbuf, 10);
			m_BotList.InsertItem(&item);

			if (pBotInfo->bot_count[i] != -1)
				m_BotList.SetItemText(i, 1, _itoa(pBotInfo->bot_count[i], intbuf, 10));	

			if (pBotInfo->team_num[i] != -1)
				m_BotList.SetItemText(i, 2, _itoa(pBotInfo->team_num[i], intbuf, 10));

			if (pBotInfo->max_ton[i] != -1)
				m_BotList.SetItemText(i, 3, _itoa(pBotInfo->max_ton[i], intbuf, 10));	

			if (pBotInfo->min_ton[i] != -1)
				m_BotList.SetItemText(i, 4, _itoa(pBotInfo->min_ton[i], intbuf, 10));
				
			if (pBotInfo->max_level[i] != -1)
				m_BotList.SetItemText(i, 5, _itoa(pBotInfo->max_level[i], intbuf, 10));	

			if (pBotInfo->min_level[i] != -1)
				m_BotList.SetItemText(i, 6, _itoa(pBotInfo->min_level[i], intbuf, 10));
		}
	}
	else
	{
		m_EditBot.EnableWindow(FALSE);
		m_RemoveBot.EnableWindow(FALSE);
	}

	// find out the rule set and see if it allows bots
	char rule_set_name[256];
	m_PropertyList.GetItemText(nSelected, 1, rule_set_name, 256);
	int rule_set = -1;
	for (i = 0; i < GameTypeCount; i++)
	{
		if (_stricmp(rule_set_name, pParent->m_szScenarioName[i]) == 0)
		{
			rule_set = i;
			break;
		}
	}
	ASSERT(rule_set != -1);

	if ((pBotInfo->rule_count < 14) && (pParent->m_bBots[rule_set]))
		m_AddBot.EnableWindow(TRUE);
}

TEAM_INFO* CNFOPropertiesDlg::FindTeamInfo(int index)
{
	if (index < 0)
		return NULL;

	int count = 0;
	TEAM_INFO* cur = m_pTeamInfo;
	while ((count != index) && (cur != NULL))
	{
		cur = cur->pNext;
		count++;
	}

	return cur;
}

BOOL CNFOPropertiesDlg::AppendTeamInfo(TEAM_INFO* info)
{
	if (m_pTeamInfo == NULL)
	{
		m_pTeamInfo = info;
		m_pTeamInfo->pNext = NULL;
		return TRUE;
	}

	TEAM_INFO* cur = m_pTeamInfo;
	while (cur->pNext != NULL)
	{
		cur = cur->pNext;
	}
	cur->pNext = info;
	info->pNext = NULL;

	return TRUE;
}

BOOL CNFOPropertiesDlg::RemoveTeamInfo(int index)
{
	// if index is invalid or no teaminfo present, return
	if ((index < 0) || (m_pTeamInfo == NULL))
		return FALSE;

	int count = 0;
	TEAM_INFO* cur = m_pTeamInfo;

	// handle special case for index equals to 0
	if (index == 0)
	{
		m_pTeamInfo = m_pTeamInfo->pNext;
		delete cur;
		return TRUE;
	}

	// finding the correct info
	TEAM_INFO* prev = m_pTeamInfo;
	while ((count != index) && (cur != NULL))
	{
		prev = cur;
		cur = cur->pNext;
		count++;
	}

	// We can't find the info(most likely invaid index), so return
	if (cur == NULL)
		return FALSE;

	// go ahead and remove the info
	prev->pNext = cur->pNext;
	delete cur;
	return TRUE;
}


BOT_INFO* CNFOPropertiesDlg::FindBotInfo(int index)
{
	if (index < 0)
		return NULL;

	int count = 0;
	BOT_INFO* cur = m_pBotInfo;
	while ((count != index) && (cur != NULL))
	{
		cur = cur->pNext;
		count++;
	}

	return cur;
}

BOOL CNFOPropertiesDlg::AppendBotInfo(BOT_INFO* info)
{
	if (m_pBotInfo == NULL)
	{
		m_pBotInfo = info;
		m_pBotInfo->pNext = NULL;
		return TRUE;
	}

	BOT_INFO* cur = m_pBotInfo;
	while (cur->pNext != NULL)
	{
		cur = cur->pNext;
	}
	cur->pNext = info;
	info->pNext = NULL;

	return TRUE;
}

BOOL CNFOPropertiesDlg::RemoveBotInfo(int index)
{
	// if index is invalid or no teaminfo present, return
	if ((index < 0) || (m_pBotInfo == NULL))
		return FALSE;

	int count = 0;
	BOT_INFO* cur = m_pBotInfo;

	// handle special case for index equals to 0
	if (index == 0)
	{
		m_pBotInfo = m_pBotInfo->pNext;
		delete cur;
		return TRUE;
	}

	// finding the correct info
	BOT_INFO* prev = m_pBotInfo;
	while ((count != index) && (cur != NULL))
	{
		prev = cur;
		cur = cur->pNext;
		count++;
	}

	// We can't find the info(most likely invaid index), so return
	if (cur == NULL)
		return FALSE;

	// go ahead and remove the info
	prev->pNext = cur->pNext;
	delete cur;
	return TRUE;
}

BOOL CNFOPropertiesDlg::RemoveRuleFromBotInfo(BOT_INFO* info, int index)
{
	ASSERT(info != NULL);
	ASSERT(index < 14);

	for (int i = index; i < 13; i++)
	{
		info->bot_count[i] = info->bot_count[i + 1];
		info->team_num[i] = info->team_num[i + 1];
		info->max_ton[i] = info->max_ton[i + 1];
		info->min_ton[i] = info->min_ton[i + 1];
		info->max_level[i] = info->max_level[i + 1];
		info->min_level[i] = info->min_level[i + 1];
	}

	info->rule_count--;

	return TRUE;
}

void CNFOPropertiesDlg::RemoveAllTeamInfo()
{	
	while (m_pTeamInfo != NULL)
	{
		TEAM_INFO* pNext = m_pTeamInfo->pNext;
		delete m_pTeamInfo;
		m_pTeamInfo = pNext;
	}
}

void CNFOPropertiesDlg::RemoveAllBotInfo()
{	
	while (m_pBotInfo != NULL)
	{
		BOT_INFO* pNext = m_pBotInfo->pNext;
		delete m_pBotInfo;
		m_pBotInfo = pNext;
	}
}

void CNFOPropertiesDlg::RemoveAllScriptInfo()
{	
	for (int i = 0; i < GameTypeCount; i++)
	{
		while (m_pScriptInfo[i] != NULL)
		{
			SCRIPT_INFO* pNext = m_pScriptInfo[i]->pNext;
			delete m_pScriptInfo[i];
			m_pScriptInfo[i] = pNext;
		}
	}
}

void CNFOPropertiesDlg::OnItemchangedNFOPropertyList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	ASSERT(pNMListView->iItem != -1);
	int nSelected = pNMListView->iItem;
	UINT uNewState = pNMListView->uNewState;
	
	m_TeamList.DeleteAllItems();
	m_BotList.DeleteAllItems();

	char intbuf[256];
	TEAM_INFO* pTeamInfo = FindTeamInfo(nSelected);
	ASSERT(pTeamInfo != NULL);
	if ((pTeamInfo) && (uNewState & LVIS_SELECTED))
	{	
		// if the current item is selected
		// then go ahead and update the team list
		CNFOFileEditorDlg* pParent = (CNFOFileEditorDlg*) GetOwner();

		char team_allowed[256];
		char team_count[256];
		m_PropertyList.GetItemText(nSelected, 3, team_allowed, 256);
		m_PropertyList.GetItemText(nSelected, 4, team_count, 256);
		m_AddTeam.EnableWindow(FALSE);

		if (pTeamInfo->team_count)
		{
			for (int i = 0; i < pTeamInfo->team_count; i++)
			{
				if (pTeamInfo->team_num[i] != -1)
				{
					LVITEM item;
					item.mask = LVIF_TEXT;
					item.iItem = i;
					item.iSubItem = 0;
					item.pszText = _itoa(pTeamInfo->team_num[i], intbuf, 10);
					m_TeamList.InsertItem(&item);
					int count = m_TeamList.GetItemCount() - 1;

					if (pTeamInfo->max_ton[i] != -1)
						m_TeamList.SetItemText(count, 1, _itoa(pTeamInfo->max_ton[i], intbuf, 10));	

					if (pTeamInfo->min_ton[i] != -1)
						m_TeamList.SetItemText(count, 2, _itoa(pTeamInfo->min_ton[i], intbuf, 10));
					
					if (pTeamInfo->max_total_ton[i] != -1)
						m_TeamList.SetItemText(count, 3, _itoa(pTeamInfo->max_total_ton[i], intbuf, 10));	
					
					if (pTeamInfo->max_team_count[i] != -1)
						m_TeamList.SetItemText(count, 4, _itoa(pTeamInfo->max_team_count[i], intbuf, 10));	
					
					if (pTeamInfo->skin[i] != (char) -1)
					{
						char skin[2];
						skin[0] = pTeamInfo->skin[i];
						skin[1] = '\0';
						m_TeamList.SetItemText(count, 5, skin);	
					}
					
					if (pTeamInfo->alignment[i] != -1)
						m_TeamList.SetItemText(count, 6, _itoa(pTeamInfo->alignment[i], intbuf, 10));
				}
			}
		}
		else
		{
			m_EditTeam.EnableWindow(FALSE);
			m_RemoveTeam.EnableWindow(FALSE);
		}
		
		if ((_stricmp(team_allowed, pParent->m_szYesNo[1]) == 0) && atoi(team_count))
		{
			if (m_TeamList.GetItemCount() < atoi(team_count))
				m_AddTeam.EnableWindow(TRUE);
		}
	}
	else
	{
		m_AddTeam.EnableWindow(FALSE);
		m_EditTeam.EnableWindow(FALSE);
		m_RemoveTeam.EnableWindow(FALSE);
	}

	// See if this has any bot rules
	BOT_INFO* pBotInfo = FindBotInfo(nSelected);
	ASSERT(pBotInfo != NULL);
	if ((pBotInfo) && (uNewState & LVIS_SELECTED))
	{
		RefreshBotList(pBotInfo, nSelected);
	}
	else
	{
		m_AddBot.EnableWindow(FALSE);
		m_EditBot.EnableWindow(FALSE);
		m_RemoveBot.EnableWindow(FALSE);
	}

	m_EditRule.EnableWindow(TRUE);
	m_RemoveRule.EnableWindow(TRUE);

	*pResult = 0;
}

void CNFOPropertiesDlg::OnNFOEditRule() 
{	
	// if no selected rule, don't bring up the dialog
	int curSel = m_PropertyList.GetSelectionMark();
	if (curSel == LB_ERR)
		return;

	m_bEditRule = TRUE;

	CNFORuleDlg dlg;
	int value = dlg.DoModal();
	ASSERT(value != -1);
		
	// the current item has changed data
	// go ahead and see if we want to enable the add team button
	if (value == 1)
	{
		// Reselect the current scenario so that it will refresh the team list and bot list
		m_PropertyList.SetSelectionMark(curSel);
		m_PropertyList.SetItemState(curSel, 0, 255);
		m_PropertyList.SetItemState(curSel, LVIS_FOCUSED | LVIS_SELECTED, 255);
	}
}

void CNFOPropertiesDlg::OnNFOAddRule() 
{	
	m_bEditRule = FALSE;

	CNFORuleDlg dlg;
	int value = dlg.DoModal();
	ASSERT(value != -1);

	// The new item has been added, 
	if (value == 1)
	{
		// Reselect the current scenario so that it will refresh the team list and bot list
		int lastItem = m_PropertyList.GetItemCount() - 1;
		m_PropertyList.SetSelectionMark(lastItem);
		m_PropertyList.SetItemState(lastItem, LVIS_FOCUSED | LVIS_SELECTED, 255);
	}
}

void CNFOPropertiesDlg::OnOK() 
{	
	char filename[256];
	m_FileName.GetWindowText(filename, 256);
	int file_len = strlen(filename);
	if (file_len == 0)
	{
		CNFOErrorDlg dlg;
		dlg.m_Error = "Empty File Name is not allowed.";
		dlg.DoModal();
		return;
	}

	CNFOFileEditorDlg* pParent = (CNFOFileEditorDlg*) GetOwner();

	Stuff::MString nfo_name;
	int mission = pParent->m_MissionList.GetCurSel();
	switch (mission)
	{
	case 0: // missions
		nfo_name = "resource\\Missions\\";
		break;
	case 1:
		nfo_name = "resource\\UserMissions\\";
		break;
	}
	nfo_name += filename;

	int value;
	if (GetFileAttributes(nfo_name) != -1)
	{
		if (pParent->m_bEditNFO != TRUE)
		{
			CNFOErrorDlg dlg;
			dlg.m_Error = "A file with the same name already exists.  Please specify another file name.";
			dlg.DoModal();
			return;
		}
		else
		{
			value = DeleteFile(nfo_name);
			ASSERT(value != 0);
			if (value == 0)
			{
				CNFOErrorDlg dlg;
				dlg.m_Error = "I/O failure.  The file might be write-protected or the hard disk might be corrupted.";
				dlg.DoModal();
				return;
			}
		}
	}

	HANDLE hdl = CreateFile(nfo_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hdl == INVALID_HANDLE_VALUE)
	{
		CNFOErrorDlg dlg;
		dlg.m_Error = "I/O failure.  The file might be write-protected or the hard disk might be corrupted.";
		dlg.DoModal();
		return;
	}

	value = CloseHandle(hdl);
	ASSERT(value != 0);
	if (value == 0)
	{
		CNFOErrorDlg dlg;
		dlg.m_Error = "I/O failure.  The file might be write-protected or the hard disk might be corrupted.";
		dlg.DoModal();
		return;
	}

	SaveNFO();

	CDialog::OnOK();
}

void CNFOPropertiesDlg::OnNFOAddTeam() 
{
	m_bEditRule = FALSE;

	CNFOTeamDlg dlg;
	int value = dlg.DoModal();
	ASSERT(value != -1);	

	int curSel = m_PropertyList.GetSelectionMark();
	ASSERT(curSel != LB_ERR);
	char team_count[256];
	m_PropertyList.GetItemText(curSel, 4, team_count, 256);
	if (m_TeamList.GetItemCount() == atoi(team_count))
		m_AddTeam.EnableWindow(FALSE);
}

void CNFOPropertiesDlg::OnNFOEditTeam() 
{
	// if no selected team rule, don't bring up the dialog
	int curSel = m_TeamList.GetSelectionMark();
	if (curSel == LB_ERR)
		return;

	m_bEditRule = TRUE;

	CNFOTeamDlg dlg;
	int value = dlg.DoModal();
	ASSERT(value != -1);	
}

void CNFOPropertiesDlg::OnNFORemoveRule() 
{
	int curSel = m_PropertyList.GetSelectionMark();
	if (curSel == LB_ERR)
		return;
 
	m_PropertyList.SetSelectionMark(-1);

	m_PropertyList.DeleteItem(curSel);
	RemoveTeamInfo(curSel);
	RemoveBotInfo(curSel);

	m_EditRule.EnableWindow(FALSE);
	m_RemoveRule.EnableWindow(FALSE);
}

void CNFOPropertiesDlg::OnNFORemoveTeam() 
{
	int curSel = m_TeamList.GetSelectionMark();
	if (curSel == LB_ERR)
		return;

	m_TeamList.SetSelectionMark(-1);

	char team_num[256];
	m_TeamList.GetItemText(curSel, 0, team_num, 256);
	m_TeamList.DeleteItem(curSel);
	TEAM_INFO* pInfo = FindTeamInfo(m_PropertyList.GetSelectionMark());
	pInfo->team_num[atoi(team_num) - 1] = -1;

	m_AddTeam.EnableWindow(TRUE);
	m_EditTeam.EnableWindow(FALSE);
	m_RemoveTeam.EnableWindow(FALSE);	
}

void CNFOPropertiesDlg::OnItemchangedNFOTeamList(NMHDR* pNMHDR, LRESULT* pResult) 
{	
	m_EditTeam.EnableWindow(TRUE);
	m_RemoveTeam.EnableWindow(TRUE);
	
	*pResult = 0;
}

void CNFOPropertiesDlg::OnNFOAddBot() 
{
	m_bEditRule = FALSE;

	CNFOBotDlg dlg;
	int value = dlg.DoModal();
	ASSERT(value != -1);

	if (m_BotList.GetItemCount() == 14)
		m_AddBot.EnableWindow(FALSE);
}

void CNFOPropertiesDlg::OnItemchangedNFOBotList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	m_EditBot.EnableWindow(TRUE);
	m_RemoveBot.EnableWindow(TRUE);
	
	*pResult = 0;
}

void CNFOPropertiesDlg::OnNFOEditBot() 
{
	// if no selected bot rule, don't bring up the dialog
	int curSel = m_BotList.GetSelectionMark();
	if (curSel == LB_ERR)
		return;

	m_bEditRule = TRUE;

	CNFOBotDlg dlg;
	int value = dlg.DoModal();
	ASSERT(value != -1);	
}

void CNFOPropertiesDlg::OnNFORemoveBot() 
{
	int curSel = m_BotList.GetSelectionMark();
	if (curSel == LB_ERR)
		return;

	m_BotList.SetSelectionMark(-1);

	m_BotList.DeleteItem(curSel);
	
	BOT_INFO* pBotInfo = FindBotInfo(m_PropertyList.GetSelectionMark());
	ASSERT(pBotInfo != NULL);
	RemoveRuleFromBotInfo(pBotInfo, curSel);
	RefreshBotList(pBotInfo, curSel);

	m_AddBot.EnableWindow(TRUE);
	m_EditBot.EnableWindow(FALSE);
	m_RemoveBot.EnableWindow(FALSE);	
}

void CNFOPropertiesDlg::OnRestore() 
{
	ASSERT(m_bEditRule == TRUE);

	int value = LoadNFO();
	ASSERT(value == TRUE);
	if (value == FALSE)
	{
		CDialog::OnOK();
	}
	
	m_EditRule.EnableWindow(FALSE);
	m_RemoveRule.EnableWindow(FALSE);
}
