// LocalizerDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Localizer.h"
#include "LocalizerDlg.h"
#include <Stuff\\Stuff.hpp>

using namespace Stuff;

#define MISSIONSLOTSIZE 500
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();
	
	// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA
	
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL
	
	// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLocalizerDlg dialog

CLocalizerDlg::CLocalizerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLocalizerDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CLocalizerDlg)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	LastRCSlot=-1;
	LastRCSearch="";
	
}

void CLocalizerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLocalizerDlg)
	DDX_Control(pDX, IDC_MISLIST, m_MisList);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CLocalizerDlg, CDialog)
//{{AFX_MSG_MAP(CLocalizerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_LOCALIZE, OnLocalize)
ON_BN_CLICKED(IDC_EXIT, OnExit)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLocalizerDlg message handlers

BOOL CLocalizerDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	
	// Add "About..." menu item to system menu.
	
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);
	
	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
	
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	WIN32_FIND_DATA file_data;
	HANDLE mission_search = FindFirstFile("Content\\Missions\\*.*" , &file_data);
	
	if(mission_search != INVALID_HANDLE_VALUE)
	{
		do
		if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			CString mis_name(file_data.cFileName);
			if(mis_name.CompareNoCase(".") && mis_name.CompareNoCase(".."))
			{
				
				m_MisList.AddString(file_data.cFileName);
			}
		}
		while (FindNextFile(mission_search,&file_data));
	}	
	
	for (int i = 0; i < m_MisList.GetCount(); i++)
		m_MisList.SetSel(i,true);
	
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}


void CLocalizerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CLocalizerDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting
		
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
		
		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		
		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CLocalizerDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CLocalizerDlg::OnOK() 
{
	// TODO: Add extra validation here
	
}

void CLocalizerDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	
	//	CDialog::OnCancel();
}

void CLocalizerDlg::OnLocalize() 
{
	LoadLangRC();
	int selCount = m_MisList.GetSelCount();
	int* selected = new int [selCount];
	m_MisList.GetSelItems(selCount,selected);
	for (int i = 0; i < selCount; i++)
	{
		CString text;
		m_MisList.GetText(selected[i],text);
		Localize(text);
	}
	
	delete selected;
	SaveLangRC();
}

void CLocalizerDlg::OnExit() 
{
	CDialog::OnOK();
}

void CLocalizerDlg::Localize(CString &mis_name)
{
	RemoveMission(mis_name);
	NextVal=FindSlotFor(mis_name);
	
	CString mis_path;
	CString contents_path;
	mis_path="Content\\Missions\\"+mis_name;
	contents_path=mis_path+"\\"+mis_name+".contents";
	
	
	NotationFile contents_file(contents_path,NotationFile::Standard,true);
	
	NotationFile::PageIterator *entity_page_list = contents_file.MakePageIterator();
	Check_Object(entity_page_list);
	
	
	
	Page *entity_page;
	bool dhiname;
	CString stringid;
	
	
	while ((entity_page = entity_page_list->ReadAndNext()) != NULL)
	{
		Check_Object(entity_page);
		if(entity_page->FindNote("DoesHaveInstanceName"))
		{
			
			entity_page->GetEntry("DoesHaveInstanceName",&dhiname);
			if(dhiname)
			{
				const char *ent_name;
				if(!entity_page->GetEntry("LocalizedInstanceName",&ent_name))
					ent_name=entity_page->GetName();
				stringid=AddLocalizedString(mis_name,ent_name,ent_name);
				stringid="$("+stringid+")";
				entity_page->SetEntry("NameIndex",stringid);
			}
		}
		
		CString btname;
		btname=entity_page->GetName();
		btname+="_";
		const char *obj_text;
		if(entity_page->GetEntry("failtextstr",&obj_text) )
		{
			stringid=AddLocalizedString(mis_name,btname+"failtext",obj_text);
			stringid="$("+stringid+")";
			entity_page->SetEntry("failtext",stringid);
		}
		
		if(entity_page->GetEntry("succeedtextstr",&obj_text) ) 
		{
			stringid=AddLocalizedString(mis_name,btname+"succeedtext",obj_text);
			stringid="$("+stringid+")";
			entity_page->SetEntry("succeedtext",stringid);
		}
		
		if(entity_page->GetEntry("neutraltextstr",&obj_text) ) 
		{
			stringid=AddLocalizedString(mis_name,btname+"neutraltext",obj_text);
			stringid="$("+stringid+")";
			entity_page->SetEntry("neutraltext",stringid);
		}
		
		if(entity_page->GetEntry("descriptextstr",&obj_text) ) 
		{
			stringid=AddLocalizedString(mis_name,btname+"descriptext",obj_text);
			stringid="$("+stringid+")";
			entity_page->SetEntry("descriptext",stringid);
		}
		
		
	}
	
	
	contents_file.Save();
	
	FileStream fstream;
	fstream.Open(contents_path,FileStream::WriteOnly);
	fstream<<"!Include=Content\\Defines\\MissionLang.defines\x0D\x0A";
	fstream<<"!concatenate=no\x0D\x0A";
	fstream<<"!preservecase=yes\x0D\x0A\x0D\x0A";
	contents_file.Write(&fstream);
	fstream.Close();
	
	
	
	RCFile.Insert(NextRCPos(),"\n");
	
}

int CLocalizerDlg::NextRCPos()
{
	int ststart=RCFile.Find("STRINGTABLE DISCARDABLE");
	Verify(ststart>=0);
	ststart=RCFile.Find("END\n",ststart);
	Verify(ststart>=0);
	
	return ststart;
}


int CLocalizerDlg::NextHPos()
{
	int strpos;
	strpos=HFile.Find("APSTUDIO_INVOKED");
	Verify(strpos>=0);
	
	do	strpos--; while(strpos>=0 && HFile[strpos]!='#');
	Verify(strpos>=0);
	
	do	strpos--; while(strpos>=0 && HFile[strpos]!='#');
	
	if(strpos>=0)
	{
		strpos=HFile.Find('\n',strpos)+1;
	}
	else
	{
		strpos=0;
	}
	
	return strpos;
}

#define VALTAG1 "_APS_NEXT_RESOURCE_VALUE"
#define VALTAG2 "_APS_NEXT_SYMED_VALUE"

int CLocalizerDlg::NextHVal()
{
	int strpos=HFile.Find(VALTAG1);
	Verify(strpos>=0);
	CString numstr;
	numstr=HFile.Mid(strpos+strlen(VALTAG1),HFile.Find('\n',strpos));
	numstr.TrimLeft();
	numstr.TrimRight();
	Verify(numstr.GetLength()>0);
	return atoi(numstr);
}

void CLocalizerDlg::SetHNextVals()
{
	int strpos;
	CString str;
	
	NextVal=GetHighestVal();
	
	
	strpos=RemoveLineContaining(HFile,VALTAG1);
	Verify(strpos>=0);
	str.Format("#define %s\t\t%i\n",VALTAG1,NextVal);
	HFile.Insert(strpos,str);
	
	strpos=RemoveLineContaining(HFile,VALTAG2);
	Verify(strpos>=0);
	str.Format("#define %s\t\t%i\n",VALTAG2,NextVal);
	HFile.Insert(strpos,str);
	
}

CString CLocalizerDlg::AddLocalizedString(CString mis_name,CString usname,CString sname)
{
	mis_name.MakeUpper();
	usname.MakeUpper();
	CString idname;
	if(sname.GetLength()==0) sname=" ";
	
	idname="IDS_LC_"+mis_name+"_"+usname;
	idname.Replace(' ','_');
	CString str;
	//	sname.Replace("\"","\\\"");
	sname.Replace("\"","'");
	str.Format("\t%s \"%s\"\n",idname,sname);
	if(str.Find("MissionLang")>=0) str=" ";
	RCFile.Insert(NextRCPos(),str);
	
	int myval;
	myval=IdList.GetID(idname);
	if(myval<0)
	{
	myval=IdList.NextFreeId(NextVal);
	NextVal=myval+1;
	}
	
	str.Format("#define %s\t\t\t%i\n",idname,myval);
	HFile.Insert(NextHPos(),str);
	
	return idname;
}

void CLocalizerDlg::RemoveMission(CString &mis_name)
{
	mis_name.MakeUpper();
	
	
	while(RemoveRCEntry(RCFile,"IDS_LC_"+mis_name)>=0);
	while(RemoveLineContaining(HFile,"IDS_LC_"+mis_name)>=0);
	
	
}

void CLocalizerDlg::LocalizeAll()
{
	LoadLangRC();
	CString misname;
	WIN32_FIND_DATA file_data;
	HANDLE mission_search = FindFirstFile("Content\\Missions\\*.*" , &file_data);
	if(mission_search != INVALID_HANDLE_VALUE)
	{
		do
		if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			CString mis_name(file_data.cFileName);
			if(mis_name.CompareNoCase(".") && mis_name.CompareNoCase(".."))
			{
				misname=CString(file_data.cFileName);
				
				Localize(misname);
			}
		}
		while (FindNextFile(mission_search,&file_data));
	}	
	SaveLangRC();
	LocalizeCampaigns();
}

void CLocalizerDlg::LocalizeCampaigns()
{
	LoadLangRC();
	
	RemoveMission(CString("Campaign"));
	NextVal=FindSlotFor("Campaign");
	
	CString misname;
	WIN32_FIND_DATA file_data;
	HANDLE mission_search = FindFirstFile("Content\\Campaigns\\*.contents" , &file_data);
	if(mission_search != INVALID_HANDLE_VALUE)
	{
		do
		{
			LocalizeCampCon(file_data.cFileName);
		}
		while (FindNextFile(mission_search,&file_data));
	}	
	
	mission_search = FindFirstFile("Content\\Campaigns\\*.campaign" , &file_data);
	if(mission_search != INVALID_HANDLE_VALUE)
	{
		do
		{
			LocalizeCampCon(file_data.cFileName);
		}
		while (FindNextFile(mission_search,&file_data));
	}	
	
	
	SaveLangRC();
	
	
}

void CLocalizerDlg::LocalizeCampCon(CString str)
{
	CString contents_path="Content\\Campaigns\\"+str;
	NotationFile note_file(contents_path,NotationFile::Standard,true);
	
	NotationFile::PageIterator *pages=note_file.MakePageIterator();
	Page *page;
	const char *text;
	
	CString stringid,btname;
	btname=str.Left(str.ReverseFind('.'));
	
	CString pname;
	while(page=pages->ReadAndNext())
	{
		pname=page->GetName();
		int loc=pname.ReverseFind('.');
		if(loc>0)
		{
			pname=pname.Left(loc);
		}
		
		loc=pname.ReverseFind('\\');
		if(loc>0)
		{
			pname=pname.Mid(loc+1);
		}
		
		if(page->GetEntry("DisplayNameText",&text))
		{
			stringid=AddLocalizedString("Campaign",btname+pname+"DisplayName",text);
			stringid="$("+stringid+")";
			page->SetEntry("DisplayNameIndex",stringid);
		}
		
		if(page->GetEntry("PointNameText",&text))
		{
			stringid=AddLocalizedString("Campaign",btname+pname+"PointName",text);
			stringid="$("+stringid+")";
			page->SetEntry("PointNameIndex",stringid);
		}
		
		if(page->GetEntry("RolloverText",&text))
		{
			stringid=AddLocalizedString("Campaign",btname+pname+"Rollover",text);
			stringid="$("+stringid+")";
			page->SetEntry("RolloverIndex",stringid);
		}
		
		if(page->GetEntry("RightClickText",&text))
		{
			stringid=AddLocalizedString("Campaign",btname+pname+"RightClick",text);
			stringid="$("+stringid+")";
			page->SetEntry("RightClickIndex",stringid);
		}
		
	}
	
	note_file.Save();
	
	FileStream fstream;
	fstream.Open(contents_path,FileStream::WriteOnly);
	fstream<<"!Include=Content\\Defines\\MissionLang.defines\x0D\x0A";
	fstream<<"!concatenate=no\x0D\x0A";
	fstream<<"!preservecase=yes\x0D\x0A\x0D\x0A";
	
	note_file.Write(&fstream);
	fstream.Close();
}	


int CLocalizerDlg::RemoveLineContaining(CString &base,CString contains)
{
	int strpos=base.Find(contains);
	if(strpos>=0)
	{
		do	strpos--; while(strpos>=0 && base[strpos]!='\n');
		strpos++;
		int eol=base.Find('\n',strpos);
		if(eol<0) eol=base.GetLength();
		base.Delete(strpos,(eol-strpos)+1);
	}
	return strpos;
}

int CLocalizerDlg::RemoveRCEntry(CString &base,CString contains)
{
	int q=0;
	//if(base!=LastRCSearch) LastRCSlot=-1;
	
	int strpos=base.Find(contains);
	//LastRCSlot=strpos;	
	//LastRCSearch=contains;
	if(strpos>=0)
	{
		do	strpos--; while(strpos>=0 && base[strpos]!='\n');
		strpos++;
		int endquote=base.Find('"',strpos);
		Verify(endquote>=0);
		do
		{
			endquote++;
			endquote=base.Find('"',endquote);
			endquote++;
		}
		while(base[endquote]=='"');
		
		while(base[endquote]=='\n') endquote++;
		
		base.Delete(strpos,endquote-strpos);
	}
	return strpos;
	
}


void CLocalizerDlg::LoadLangRC()
{
	DWORD bread;
	char *buf;
	int bufsize;
	HANDLE fhan;
	
	fhan=CreateFile("Code\\MissionLang\\MissionLangScript.rc",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	Verify(fhan!=INVALID_HANDLE_VALUE);
	bufsize=GetFileSize(fhan,NULL);
	buf=new char[bufsize+1];
	ReadFile(fhan,buf,bufsize,&bread,NULL);
	CloseHandle(fhan);
	buf[bufsize]=0;
	RCFile=buf;
	Verify(RCFile.GetLength()==bufsize);
	delete buf;
	
	
	fhan=CreateFile("Code\\MissionLang\\resource.h",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	Verify(fhan!=INVALID_HANDLE_VALUE);
	bufsize=GetFileSize(fhan,NULL);
	buf=new char[bufsize+1];
	ReadFile(fhan,buf,bufsize,&bread,NULL);
	CloseHandle(fhan);
	buf[bufsize]=0;
	HFile=buf;
	Verify(HFile.GetLength()==bufsize);
	delete buf;
	
	NextVal=NextHVal();
	RCFile.Replace("\x0D\x0A","\n");
	HFile.Replace("\x0D\x0A","\n");
	
	GetTagList();
	
	
	
	
}

void CLocalizerDlg::GetTagList()
{	
	int lastpos=0;
	CString substr,numstr;
	int eof=HFile.Find("APSTUDIO_READONLY_SYMBOLS");
	while(lastpos!=-1 && lastpos<eof)
	{
		lastpos=HFile.Find("#define",lastpos);
		lastpos+=strlen("#define")+1;
		if(lastpos>=0 && lastpos<eof)
		{
			while(isspace(HFile.GetAt(lastpos))) lastpos++; //Trim leading White spaces
			int substrcnt=0;	
			while(!isspace(HFile.GetAt(lastpos+substrcnt))) substrcnt++;
			substr=HFile.Mid(lastpos,substrcnt);
			lastpos+=substrcnt;
			while(isspace(HFile.GetAt(lastpos))) lastpos++; //Trim trailing White spaces
			if(!isdigit(HFile.GetAt(lastpos)))
				STOP(("H file is formated incorrectly"));
			substrcnt=0;
			while(isdigit(HFile.GetAt(lastpos+substrcnt))) substrcnt++;
			numstr=HFile.Mid(lastpos,substrcnt);
			lastpos+=substrcnt;
			int id=atoi(numstr);
			IdList.AddTag(substr,id);
		}
		
	}
}

int CLocalizerDlg::CountNeededSlots(CString &mis_name)
{
	CString mis_path;
	CString contents_path;
	mis_path="Content\\Missions\\"+mis_name;
	contents_path=mis_path+"\\"+mis_name+".contents";
	
	NotationFile contents_file(contents_path,NotationFile::Standard,true);
	NotationFile::PageIterator *entity_page_list = contents_file.MakePageIterator();
	Check_Object(entity_page_list);
	
	Page *entity_page;
	bool dhiname;
	CString stringid;
	int count=0;	
	while ((entity_page = entity_page_list->ReadAndNext()) != NULL)
	{
		Check_Object(entity_page);
		if(entity_page->FindNote("DoesHaveInstanceName"))
		{
			entity_page->GetEntry("DoesHaveInstanceName",&dhiname);
			if(dhiname) count++;
		}
		
		if(entity_page->FindNote("failtextstr") ) count++;
		if(entity_page->FindNote("succeedtextstr") ) count++;
		if(entity_page->FindNote("neutraltextstr") ) count++;
		if(entity_page->FindNote("descriptextstr") ) count++;
		
		
	}
	
	return count;
}

#define LOWESTVAL 2000
#define ENDDEFSECTION "#ifdef APSTUDIO_INVOKED"

int CLocalizerDlg::FindSlotFor(CString misname)
{
	NotationFile ldfile("Content\\Missions\\Localize.Info");
	Page *page=ldfile.SetPage("MissionData");
	Check_Object(page);
	bool found=false;
	int val,hival;
	hival=LOWESTVAL;
	
				Page::NoteIterator *notelist=page->MakeNoteIterator();
				Check_Object(notelist);
				notelist->First();
				Note *note;
				CString notename;
				
				while((note=(Note *)notelist->ReadAndNext()) && !found)
				{
					notename=note->GetName();
					note->GetEntry(&val);
					hival=hival>val?hival:val;
					if(!notename.CompareNoCase(misname)) found=true;
					
				}
				
				if(!found)
				{
					val=hival+MISSIONSLOTSIZE;
					page->SetEntry(misname,val);
				}
				
				ldfile.Save();
				return val;
}

int CLocalizerDlg::GetHighestVal()
{
	int strpos,valcount,val;
	int veof=HFile.Find(ENDDEFSECTION);
	Verify(veof>=0);
	
	strpos=0;
	valcount=0;
	do
	{
		strpos=HFile.Find("#define",strpos)+1;
		valcount++;
	}
	while(strpos>-1 && strpos<veof);
	valcount--;
	
	
	if(valcount==0) return LOWESTVAL;
	
	int *valarray=new int[valcount];
	CString arg;
	int eol;
	strpos=0;
	val=0;
	
	do
	{
		strpos=HFile.Find("#define",strpos);
		Verify(strpos>=0);
		strpos+=strlen("#define");
		if(strpos<veof)
		{
			for(;HFile[strpos]==' ' || HFile[strpos]=='\n' || HFile[strpos]=='\t';strpos++);
			for(;HFile[strpos]!=' ' && HFile[strpos]!='\n' && HFile[strpos]!='\t';strpos++);
			for(;HFile[strpos]==' ' || HFile[strpos]=='\n' || HFile[strpos]=='\t';strpos++);
			
			bool alldigits=true;
			Verify(HFile[strpos]!='\n' && HFile[strpos]!=' ' && HFile[strpos]!='\n' && HFile[strpos]!='\t' && strpos<HFile.GetLength());
			for(eol=strpos;HFile[eol]!='\n' && alldigits;eol++)
			{
				if(!isdigit(HFile[eol])) alldigits=false;
			}
			
			if(alldigits==false)
			{
				Verify(val<valcount);
				valarray[val++]=-1;
			}
			else
			{
				Verify(val<valcount);
				valarray[val++]=atoi(HFile.Mid(strpos,eol-strpos));
			}
		}
		strpos++;
	} 
	while(strpos<veof);
	Verify(val==valcount);
	
	int lowval=LOWESTVAL;
	int highestval=-1;
	for(val=0;val<valcount;val++) 
		if(valarray[val]>highestval) highestval=valarray[val];
		
		return highestval;
}


void CLocalizerDlg::SaveLangRC()
{
	HANDLE fhan;
	DWORD bread;
	SetHNextVals();
	
	RCFile.Replace("\n","\x0D\x0A");
	HFile.Replace("\n","\x0D\x0A");
	
	fhan=CreateFile("Code\\MissionLang\\MissionLangScript.rc",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	Verify(fhan!=INVALID_HANDLE_VALUE);
	WriteFile(fhan,RCFile.GetBuffer(0),RCFile.GetLength(),&bread,NULL);
	CloseHandle(fhan);
	
	fhan=CreateFile("Code\\MissionLang\\resource.h",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
	Verify(fhan!=INVALID_HANDLE_VALUE);
	WriteFile(fhan,HFile.GetBuffer(0),HFile.GetLength(),&bread,NULL);
	CloseHandle(fhan);
	
}

void TagList::AddTag(CString str,int id)
{
	int curid=FindIDIndex(id);
	if(curid>=0 && Tags[curid]!=str) PAUSE(("ID %i already taken by %s",id,(LPCSTR)Tags[curid]));
	Tags[TagTot]=str;
	IDs[TagTot]=id;
	TagTot++;
}

int	 TagList::GetID(CString str)
{
	int idx=FindStringIndex(str);
	if(idx<0) return idx;
	return IDs[idx];
}

int TagList::FindStringIndex(CString str)
{
	int i;
	
	for(i=0;i<TagTot;i++)
	{
		if(str==Tags[i]) return i;
	}
	
	return -1;
}

int TagList::FindIDIndex(int id)
{
	int i;
	
	for(i=0;i<TagTot;i++)
	{
		if(id==IDs[i]) return i;
	}
	
	return -1;
}

int TagList::NextFreeId(int start)
{
	while(FindIDIndex(start)>=0) start++;
	return start;
}