/*
Program:
Husky Mounted Detection System (HMDS)

Source:
EOIR Technologies
PO Box 1240
Spotsylvania, VA  22553

HMDS Development Team
USA CECOM Night Vision and Electronic Sensors Directorate (NVESD)
10221 Burbeck Rd., STE 430
Fort Belvoir, VA 22060

Conditions for Use:
This software is Copyright(C) EOIR Technologies, Inc.

EOIR Technologies has all commercial interest and rights.
NVESD has full rights, title, and interest.

This software is provided "as is", without warranty by 
EOIR Technologies, Inc and NVESD. In no event shall EOIR 
Technologies, Inc. or NVESD be liable for any loss or for
any indirect, special, punitive, exemplary, incidental, or 
consequential damages arising from the use, possession, or
performance of this software.
*/

var MB_OK = 0x00;
var MB_OKCANCEL = 0x01;
var MB_ABORTRETRYIGNORE = 0x02;
var MB_YESNOCANCEL = 0x03;
var MB_YESNO = 0x04;
var MB_RETRYCANCEL = 0x05;

var MB_ICONHAND = 0x10;
var MB_ICONQUESTION = 0x20;
var MB_ICONEXCLAMATION = 0x30;
var MB_ICONINFORMATION = 0x40;

var IDOK = 1;
var IDCANCEL = 2;
var IDABORT = 3;
var IDRETRY = 4;
var IDIGNORE = 5;
var IDYES = 6;
var IDNO = 7;


var EOIR = EOIR ? EOIR : function()
{
	var obj = 
	{
	};
	
	return obj;
} ();

EOIR.FSO = function()
{
	var obj =
	{
	    m_fso: null,
	
	    get: function()
		{
		    if(this.m_fso == null)
		    {		
			    if(!EOIR.Utils.isWebBased() && window.ActiveXObject != null)
			    {
				    var fso = new ActiveXObject("EOIR.FileSystemObject");
				    if(fso == null)
				    {
					    fso = new ActiveXObject("Scripting.FileSystemObject");
				    }

                    this.m_fso = fso;
			    }
			    else if(EOIR.Utils.isInROCBrowserGecko())
			    {
			        //set permissions to allow XPCOM to run
			        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

			        //connect to and file down the XPCOM object
			        var strClass = "@eoir.com/ctr/fso;1";
			        var fso = Components.classes[strClass].createInstance();
			        fso = fso.QueryInterface(Components.interfaces.nsIFSO);
    			    
    			    this.m_fso = fso;
			    }
			    else
			    {
			        this.m_fso = null;
			    }
			}

			return this.m_fso;		
		},
	
	    deleteFile: function(strFilespec)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					this.get().DeleteFile(strFilespec);
				}
				else
				{
				    this.get().DeleteFile(strFilespec);
				}
				return true;
			}
			catch(e)
			{
			    return false;
			}
	    },
	    
	    deleteFolder: function(strFolderspec)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					this.get().DeleteFolder(strFilespec);
				}
				else
				{
				    this.get().DeleteFolder(strFilespec);
				}
			}
			catch(e)
			{
			}
	    },
	    
	    //boolean FileExists(in string filename);
	    fileExists: function(strFilename)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().FileExists(strFilename);
				}
				else
				{
				    return this.get().FileExists(strFilename);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    //boolean FolderExists(in string path);
	    folderExists: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().FolderExists(strPath);
				}
				else
				{
				    return this.get().FolderExists(strPath);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    	    
	    //string BuildPath(in string part1, in string part2);
	    buildPath: function(strPart1, strPart2)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().BuildPath(strPart1, strPart2);
				}
				else
				{
				    return this.get().BuildPath(strPart1, strPart2);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    //string GetParentFolderName(in string path);
	    getParentFolderName: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetParentFolderName(strPath);
				}
				else
				{
				    return this.get().GetParentFolderName(strPath);
				}
			}
			catch(e)
			{
			    return null;
			}
	    },
	    
	    //void CreateFolder(in string path);
	    createFolder: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					if(strPath.indexOf("file:///") == 0)
					{
					    //remove the file:/// protocol
					    strPath = strPath.substr("file:///".length, strPath.length);
					}
					
					this.get().CreateFolder(strPath);
				}
				else
				{
				    this.get().CreateFolder(strPath);
				}
			}
			catch(e)
			{
			    alert(e);
			}
	    },
	    
	    //string GetTempName();
	    getTempName: function()
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetTempName();
				}
				else
				{
				    return this.get().GetTempName();
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    //string GetExtensionName(in string path);
	    getExtensionName: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetExtensionName(strPath);
				}
				else
				{
				    return this.get().GetExtensionName(strPath);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    //void CopyFile(in string strFrom, in string strTo, in boolean bOverwrite);
	    copyFile: function(strFrom, strTo, bOverwrite)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					this.get().CopyFile(strFrom, strTo, bOverwrite);
				}
				else
				{
				    this.get().CopyFile(strFrom, strTo, bOverwrite);
				}
			}
			catch(e)
			{
			}
	    },
	    
	    //string GetFileName(in string path);
	    getFileName: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetFilename(strPath);
				}
				else
				{
				    return this.get().GetFilename(strPath);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },

	    //nsITextFile CreateTextFile(in string strFile, in boolean bOverwrite);		
	    createTextFile: function(strFile, bOverwrite)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().CreateTextFile(strFile, bOverwrite);
				}
				else
				{
				    return this.get().CreateTextFile(strFile, bOverwrite);
				}
			}
			catch(e)
			{
			    return null;
			}
	    },
	    
	    //nsIFile GetFile(in string path);
	    getFile: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetFile(strPath);
				}
				else
				{
				    return this.get().GetFile(strPath);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    //nsIFile GetFolder(in string path);
	    getFolder: function(strPath)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetFolder(strPath);
				}
				else
				{
				    return this.get().GetFolder(strPath);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    //nsIFile GetSpecialFolder(in long nSpecialFolderType);
	    getSpecialFolder: function(nSpecialFolderType)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetSpecialFolder(nSpecialFolderType);
				}
				else
				{
				    return this.get().GetSpecialFolder(nSpecialFolderType);
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    },
	    
	    getSpecialFolderName: function(nSpecialFolderType)
	    {
	    	try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
					
					return this.get().GetSpecialFolderName(nSpecialFolderType);
				}
				else
				{
				    return null; //doesnt exist in IE version
				}
			}
			catch(e)
			{
			    alert(e);
			    return null;
			}
	    }
	};

	return obj;
} ();

EOIR.Utils = function ()
{
	var obj =
	{
		getFSO: function ()
		{
			if(!EOIR.Utils.isWebBased() && window.ActiveXObject != null)
			{
				var fso = new ActiveXObject("EOIR.FileSystemObject");
				if(fso == null)
				{
					fso = new ActiveXObject("Scripting.FileSystemObject");
				}

				return fso;
			}
			else if(EOIR.Utils.isInROCBrowserGecko())
			{
				//set permissions to allow XPCOM to run
				netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

				//connect to and file down the XPCOM object
				var strClass = "@eoir.com/ctr/fso;1";
				var fso = Components.classes[strClass].createInstance();
				fso = fso.QueryInterface(Components.interfaces.nsIFSO);

				return fso;
			}
			else
			{
				return null;
			}
		},


		disableFlashSecurity: function (strProductName)
		{
			try
			{
				if(EOIR.Utils.canEnableNetscapePrivileges())
				{
					//set permissions to allow XPCOM to run
					netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

					return EOIR.External.get().DisableFlashSecurity(strProductName + ".cfg");
				}
			}
			catch(e)
			{
				return null;
			}


			/* This doesn't work... more specifically, textfile.WriteLine isn't working right.
			try
			{
			if(!EOIR.Utils.isWebBased() && !EOIR.Utils.isInROCBrowser())
			{
			var fso = EOIR.FSO;

			var strAppData;
			try
			{
			strAppData = EOIR.External.getUserHomeDir();
			}
			catch(e)
			{
			strAppData = null;
			}


			if(strAppData == null)
			{
			try
			{
			var ws = new ActiveXObject("WScript.Shell");
			strAppData = ws.SpecialFolders("AppData");
			}
			catch(e) { }
			}

			if(strAppData)
			{
			EOIR.External.debugWrite("0: " + strAppData + "\n");

			var strPath = fso.buildPath(strAppData, "Macromedia\\Flash Player\\#Security\\FlashPlayerTrust");
			if(!fso.folderExists(strPath))
			{
			fso.createFolder(strPath);
			}
			var strProduct = "";
			try
			{
			strProduct = "cerberus";
			//strProduct = EOIR.External.get().Product();
			}
			catch(e)
			{
			//alert("Defaulting to cerberus");
			strProduct = "cerberus";
			}
			strProduct += ".cfg";
			strPath = fso.buildPath(strPath, strProduct);

			var strRootPath = EOIR.Utils.getAbsolutePath("");

			EOIR.External.debugWrite("1: " + strRootPath + "\n");

			if(strRootPath.substr(0, 8) == "file:///")
			{
			strRootPath = strRootPath.substr(8);
			strRootPath = strRootPath.replace(/\x2f/g, "\\");
			}
			else if(strRootPath.substr(0, 6) == "rocz:/")
			{
			EOIR.External.debugWrite("2: " + strRootPath + "\n");
			strRootPath = strRootPath.replace(/\x2f/g, "\\");
			var nSubFileIndex = strRootPath.indexOf("::");
			if(nSubFileIndex != -1)
			{
			EOIR.External.debugWrite("3: " + strRootPath + "\n");
			nSubFileIndex = strRootPath.lastIndexOf("\\", nSubFileIndex);
			strRootPath = strRootPath.substring(6, nSubFileIndex);
			EOIR.External.debugWrite("4: " + strRootPath + "\n");
			}
			}

			if(strRootPath.substr(strRootPath.length - 1) == "\\")
			{
			strRootPath = strRootPath.substr(0, strRootPath.length - 1);
			}

			EOIR.External.debugWrite("5: " + strRootPath + "\n");
			var strTempPath = fso.buildPath(strAppData, strProduct);

			EOIR.External.debugWrite("6: " + strTempPath + "\n");

			//Need to create the cfg in a temporary location.
			//Gecko file writing doesn't like the # in the #Security
			//so it failes to create a file in that folder.
			//Instread create a temp file and copy it into the proper location
			//Once it is copied, it can be deleted.
			var cfgFile = fso.createTextFile(strTempPath, true);
			cfgFile.WriteLine(strRootPath);
			cfgFile.Close();
			fso.copyFile(strTempPath, strPath, true);
			if(strTempPath.substr(0, 8) == "file:///")
			strTempPath = strTempPath.substr(8);
			fso.deleteFile(strTempPath);

			EOIR.External.debugWrite("7: " + strPath + "\n");
			}
			}
			}
			catch(e) { }
			*/
		},


		closeWindow: function ()
		{
			if(EOIR.Utils.isInROCBrowser() || EOIR.Utils.isInROCBrowserGecko())
			{
				EOIR.External.closeWindow();
			}
			else
			{
				try
				{
					window.top.close();
				}
				catch(e) { }
			}
		},

		getRelativePathFromAbsolutePaths: function (strAbsolutePathFrom, strAbsolutePathTo, bPathIncludesFile)
		{
			var arrAbsFromDirs = strAbsolutePathFrom.split("/");
			var arrAbsToDirs = strAbsolutePathTo.split("/");

			var nLen = Math.min(arrAbsFromDirs.length, arrAbsToDirs.length);

			var nLastCommonRootIndex = -1;

			var nIndex = 0;
			while(arrAbsFromDirs[nIndex] == arrAbsToDirs[nIndex] && nIndex < nLen)
			{
				nIndex++;
			}

			nLastCommonRootIndex = nIndex;

			if(nLastCommonRootIndex == nLen && arrAbsFromDirs.length == arrAbsToDirs.length)
			{
				return ".";
			}

			if(nLastCommonRootIndex == 0)
			{
				throw "No common root found!";
			}

			if(bPathIncludesFile)
			{
				arrAbsFromDirs.length--;
			}

			var strRelPath = "";
			for(nIndex = nLastCommonRootIndex; nIndex < arrAbsFromDirs.length; nIndex++)
			{
				if(arrAbsFromDirs[nIndex].length > 0)
				{
					strRelPath += "../";
				}
			}

			for(nIndex = nLastCommonRootIndex; nIndex < arrAbsToDirs.length - 1; nIndex++)
			{
				strRelPath += arrAbsToDirs[nIndex] + "/";
			}

			strRelPath += arrAbsToDirs[nIndex];
			return strRelPath;
		},

		getRelativePathFromMain: function (strPath)
		{
			var strAbsPath = EOIR.Utils.getAbsolutePath("/");
			return decodeURIComponent(strPath).substr(strAbsPath.length - 1);
		},

		getPathFromMain: function (strPath)
		{
			return EOIR.Utils.buildPath(EOIR.Utils.getAbsolutePath("/"), strPath);
		},

		getAbsolutePathFromPath: function (strUrl, strPath)
		{
			strPath = decodeURIComponent(strPath);
			strUrl = strUrl.replace(/\\/g, "/");

			var strSep = "/";

			var nIndex = strUrl.lastIndexOf(strSep);
			if(nIndex != -1)
			{
				strUrl = unescape(strUrl);
				if(window.location.protocol == "file:")
				{
					if(strUrl.substr(0, 1) == "/")
					{
						strUrl = strUrl.substr(1, strUrl.length - 1);
					}
				}
				nIndex = strUrl.lastIndexOf(strSep);
				if(nIndex != -1)
				{
					if(strPath.substr(0, 1) != strSep)
					{
						strPath = strSep + strPath;
					}

					strUrl = strUrl.substr(0, nIndex) + strPath;
				}

				//		alert(window.location.protocol + "\n" + window.location.hostname + "\n" + window.location.port + "\n" + strUrl + "\n" + window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + strUrl);
				if(window.location.protocol == "http:" || window.location.protocol == "https:")
				{
					if(window.location.port == "")
					{
						return window.location.protocol + "//" + window.location.hostname + strUrl;
					}
					else
					{
						return window.location.protocol + "//" + window.location.hostname + ":" + window.location.port + strUrl;
					}
				}
				else if(window.location.protocol == "file:")
				{
					return window.location.protocol + "//" + window.location.hostname + "/" + strUrl;
				}
				else if(window.location.protocol == "ctrz:" || window.location.protocol == "ms-its:" || window.location.protocol == "rocz:")
				{
					return window.location.protocol + strUrl;
				}
				else
				{
					return strUrl;
				}
			}

			return strPath;
		},

		getAbsolutePathFromCurrentLocation: function (strPath)
		{
			return EOIR.Utils.getAbsolutePathFromPath(decodeURIComponent(window.location.pathname), strPath);
		},

		getAbsolutePath: function (strPath)
		{
			var wndROC = EOIR.Utils.getMainWindow();
			if(wndROC != null)
			{
				return EOIR.Utils.getAbsolutePathFromPath(decodeURIComponent(wndROC.location.pathname), strPath);
			}
			else
			{
				var strPathToMain = EOIR.Utils.getPathToMain();
				if(strPathToMain != null)
				{
					return EOIR.Utils.getAbsolutePathFromPath(decodeURIComponent(window.location.pathname), EOIR.Utils.buildPath(strPathToMain, strPath));
				}

				return EOIR.Utils.getAbsolutePathFromCurrentLocation(strPath);
			}
		},

		getMainWindow: function ()
		{
			var wndCur = window;
			while(wndCur != null)
			{
				if(wndCur.frames.length > 0 && wndCur.document.getElementById("navContentFrame") != null)
				{
					return wndCur;
				}
				else
				{
					if(wndCur.parent != null && wndCur.parent.window != wndCur)
					{
						wndCur = wndCur.parent;
					}
					else
					{
						return null;
					}
				}
			}
		},

		getPathToMain: function ()
		{
			try
			{
				var arrElems = document.getElementsByTagName("link");
				for(var i = 0; i < arrElems.length; i++)
				{
					try
					{
						if(arrElems[i].getAttribute("rel").toLowerCase() == "start")
						{
							var strMainPage = arrElems[i].getAttribute("href");
							if(strMainPage != null)
							{
								var nIndex = strMainPage.lastIndexOf("/");
								if(nIndex != -1)
								{
									return strMainPage.substr(0, nIndex + 1);
								}
							}
						}
					}
					catch(e)
					{
					}
				}
			}
			catch(e)
			{
			}

			return "";
		},

		isSep: function (ch)
		{
			return ch == "/" || ch == "\\";
		},

		appendSep: function (str, ch)
		{
			if(str == null)
			{
				return null;
			}

			ch = ch ? ch : "\\";
			if(str.charAt(str.length - 1) != ch)
			{
				return str + ch;
			}
			else
			{
				return str;
			}
		},

		buildPath: function (strFolder, strFile)
		{
			/*			
			try
			{
			var fso = EOIR.Utils.getFSO();
			if(fso != null)
			{
			return fso.BuildPath(strFolder, strFile);
			}
			}
			catch(e)
			{
			}
			*/
			if(strFolder == null)
			{
				return strFile;
			}
			else if(strFile == null)
			{
				return strFolder;
			}

			if(EOIR.Utils.isSep(strFolder.substr(strFolder.length - 1)) && EOIR.Utils.isSep(strFile.substring(0, 1)))
			{
				return strFolder + strFile.substr(1);
			}
			else if(EOIR.Utils.isSep(strFolder.substr(strFolder.length - 1)) || EOIR.Utils.isSep(strFile.substring(0, 1)))
			{
				return strFolder + strFile;
			}
			else
			{
				return strFolder + "/" + strFile;
			}
		},

		getEventObject: function (evt)
		{
			return (evt != null) ? evt : ((window.event != null) ? window.event : "");
		},

		ignoreEvent: function (evt)
		{
			evt = EOIR.Utils.getEventObject(evt);
			EOIR.Utils.stopEvent(evt);

			return false;
		},

		stopEvent: function (evt)
		{
			try
			{
				if(YAHOO.util.Event)
				{
					YAHOO.util.Event.stopEvent(evt);
					return;
				}
			}
			catch(e)
			{
			}

			try
			{
				if(evt.returnValue)
				{
					evt.returnValue = false;
				}
				if(evt.cancelBubble)
				{
					evt.cancelBubble = true;
				}
				if(evt.stopPropagation)
				{
					evt.stopPropagation();
				}
				if(evt.preventDefault)
				{
					evt.preventDefault();
				}
			}
			catch(e)
			{
			}
		},

		onSelectStart: function (evt)
		{
			if(this.getEventObject)
			{
				evt = this.getEventObject(evt);
				try
				{
					var elem = this.getTargetElement(evt);
					if(elem == null)
					{
						evt.returnValue = false;
						return false;
					}

					if(elem.getAttribute("unselectable") != "off")
					{
						if(elem.tagName.toLowerCase() != "input")
						{
							evt.returnValue = false;
							return false;
						}
					}
				}
				catch(e)
				{
					evt.returnValue = false;
					return false;
				}

				return true;
			}
			else
			{
				return false;
			}
		},

		preventSelectionYUI: function (evt)
		{
			var elem = YAHOO.util.Event.getTarget(evt);
			if(elem == null)
			{
				EOIR.Utils.stopEvent(evt);
				return false;
			}
			else
			{
				if(elem.getAttribute("unselectable") != "off")
				{
					if(elem.tagName.toLowerCase() != "input")
					{
						EOIR.Utils.stopEvent(evt);
						return false;
					}
				}
			}
		},

		getTargetElement: function (evt)
		{
			var elem;

			if(evt.currentTarget != null)
			{
				elem = (evt.currentTarget.nodeType == 3) ? evt.currentTarget.parentNode : evt.currentTarget;
			}
			else if(evt.target != null)
			{
				elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target;
			}
			else
			{
				elem = evt.srcElement;
			}

			return elem;
		},

		arrayInsert: function (arr, obj, index)
		{
			var pre = arr.slice(0, index);
			var post = arr.splice(index, arr.length - index);

			pre.push(obj);
			return pre.concat(post);
		},

		indexOf: function (arr, obj)
		{
			for(var i = 0; i < arr.length; i++)
			{
				if(arr[i] == obj)
				{
					return i;
				}
			}

			return -1;
		},

		getSafeString: function (str, strDefault)
		{
			return str == null ? (strDefault == null ? "&nbsp;" : strDefault) : str;
		},

		isValidTextValue: function (elem, nMin, nMax)
		{
			var nVal = parseInt(elem.value);
			if(isNaN(nVal) || (nVal < nMin || nVal > nMax))
			{
				return false;
			}
			else
			{
				return true;
			}
		},

		isValidTextValueFloat: function (elem, fMin, fMax)
		{
			var fVal = parseFloat(elem.value);
			if(isNaN(fVal) || (fVal < fMin || fVal > fMax))
			{
				return false;
			}
			else
			{
				return true;
			}
		},

		getLimitMessage: function (strMessage, min, max)
		{
			return strMessage.replace("<min/>", min).replace("<max/>", max);
		},

		checkForValidTextValue: function (elem, nMin, nMax, strMessage, strCaption)
		{
			if(!EOIR.Utils.isValidTextValue(elem, nMin, nMax))
			{
				elem.focus();
				elem.select();
				EOIR.Utils.showMessageBox(EOIR.Utils.getLimitMessage(strMessage, nMin, nMax), strCaption, MB_OK | MB_ICONEXCLAMATION);
				return false;
			}

			return true;
		},

		checkForValidTextValueFloat: function (elem, fMin, fMax, strMessage, strCaption)
		{
			if(!EOIR.Utils.isValidTextValueFloat(elem, fMin, fMax))
			{
				elem.focus();
				elem.select();
				EOIR.Utils.showMessageBox(EOIR.Utils.getLimitMessage(strMessage, fMin, fMax), strCaption, MB_OK | MB_ICONEXCLAMATION);
				return false;
			}

			return true;
		},

		showYUIMessageBox: function (strMessage, strCaption, nButtons, fnHandler)
		{
			var icon;
			if(nButtons & MB_ICONEXCLAMATION)
			{
				icon = YAHOO.widget.SimpleDialog.ICON_WARN;
			}
			else if(nButtons & MB_ICONINFORMATION)
			{
				icon = YAHOO.widget.SimpleDialog.ICON_INFO;
			}
			else if(nButtons & MB_ICONQUESTION)
			{
				icon = YAHOO.widget.SimpleDialog.ICON_HELP;
			}

			var dlgHandler = function (evt, obj)
			{
				this.hide();
				if(fnHandler != null)
				{
					fnHandler(obj);
				}
			};

			var btns = [];
			switch(nButtons & 0x0F)
			{
				case MB_OK:
					btns = [
								{ text: "OK", handler: { fn: dlgHandler, obj: IDOK }, isDefault: true }
						   ];
					break;

				case MB_OKCANCEL:
					btns = [
								{ text: "OK", handler: { fn: dlgHandler, obj: IDOK }, isDefault: true },
								{ text: "Cancel", handler: { fn: dlgHandler, obj: IDCANCEL} }
						   ];
					break;

				case MB_ABORTRETRYIGNORE:
					btns = [
								{ text: "Abort", handler: { fn: dlgHandler, obj: IDABORT }, isDefault: true },
								{ text: "Retry", handler: { fn: dlgHandler, obj: IDRETRY} },
								{ text: "Ignore", handler: { fn: dlgHandler, obj: IDIGNORE} }
						   ];
					break;

				case MB_YESNO:
					btns = [
								{ text: "Yes", handler: { fn: dlgHandler, obj: IDYES }, isDefault: true },
								{ text: "No", handler: { fn: dlgHandler, obj: IDNO} }
						   ];
					break;

				case MB_YESNOCANCEL:
					btns = [
								{ text: "Yes", handler: { fn: dlgHandler, obj: IDYES }, isDefault: true },
								{ text: "No", handler: { fn: dlgHandler, obj: IDNO} },
								{ text: "Cancel", handler: { fn: dlgHandler, obj: IDCANCEL} }
						   ];
					break;

				case MB_RETRYCANCEL:
					btns = [
								{ text: "Retry", handler: { fn: dlgHandler, obj: IDRETRY }, isDefault: true },
								{ text: "Cancel", handler: { fn: dlgHandler, obj: IDCANCEL} }
						   ];
			}

			var dlg = new YAHOO.widget.SimpleDialog(YAHOO.util.Dom.generateId(),
														{
															fixedcenter: true,
															visible: false,
															draggable: false,
															modal: true,
															close: false,
															text: strMessage.replace(/\n/g, "<br/>"),
															icon: icon,
															constraintoviewport: true,
															buttons: btns,
															zIndex: 9999
														});
			dlg.setHeader(strCaption);
			dlg.render(document.body);
			dlg.element.style.minWidth = "400px";
			dlg.element.style.maxWidth = "400px";
			dlg.show();
			return dlg;
		},

		// This acts more like the YUI SimpleDialog in that it calls a handle function when a button is pressed.
		// The handler should be function(result). <result> is the result from the showMessageBox function.
		showMessageBoxWithHandler: function (strMessage, strCaption, nButtons, fnHandler)
		{
			var res = EOIR.Utils.showMessageBox(strMessage, strCaption, nButtons);
			if(fnHandler != null)
			{
				fnHandler(res);
			}
			return res;
		},

		showMessageBox: function (strMessage, strCaption, nButtons)
		{
			try
			{
				return EOIR.External.msgBox(strMessage, strCaption, nButtons);
			}
			catch(e)
			{
				if(!EOIR.Utils.isInROCBrowser() && !EOIR.Utils.isInROCBrowserGecko())
				{
					if(false) //window.showModalDialog)
					{
					}
					else
					{
						if((nButtons & 0x0F) == MB_OK)
						{
							alert(strMessage);
						}
						else
						{
							var bResult = confirm(strMessage);

							switch(nButtons & 0x0F)
							{
								case MB_OKCANCEL:
									return bResult ? IDOK : IDCANCEL;

								case MB_ABORTRETRYIGNORE:
									return bResult ? IDABORT : IDRETRY;

								case MB_YESNO:
								case MB_YESNOCANCEL:
									return bResult ? IDYES : IDNO;

								case MB_RETRYCANCEL:
									return bResult ? IDRETRY : IDCANCEL;
							}
						}
					}
				}
				else
				{
					var objWShell = new ActiveXObject("WScript.Shell");
					return objWShell.Popup(strMessage, 0, strCaption, nButtons);
				}
			}
		},


		getAppName: function ()
		{
			try
			{
				var name = EOIR.Utils.getProperty("appName");
				if(name == null)
				{
					name = EOIR.Build.getAppName();
					if(name != null)
					{
						EOIR.Utils.setProperty("appName", name);
					}
				}

				return name;
			}
			catch(e)
			{
			}
		},

		isInROCBrowser: function ()
		{
			try
			{
				if(!EOIR.Utils.isInROCBrowserFF() && !EOIR.Utils.isInROCBrowserGecko()) //avoid eternal recursion in these builds
					return EOIR.External.get().isDebug != null;
			}
			catch(e)
			{
			}

			return false;
		},

		isInROCBrowserFF: function ()
		{
			try
			{
				return navigator.userAgent.indexOf("ROC") != -1; //on next fbcb2 release, probably want to update this to be more specific
			}
			catch(e)
			{
			}

			return false;
		},

		isInROCBrowserGecko: function ()
		{
			try
			{
				return navigator.userAgent.indexOf(EOIR.Utils.getAppName()) != -1;
			}
			catch(e)
			{
			}

			return false;
		},

		isWebBased: function ()
		{
			return document.location.protocol.substring(0, 4).toLowerCase() == "http";
		},

		isInBrowser: function ()
		{
			return !(EOIR.Utils.isInROCBrowserFF() || EOIR.Utils.isInROCBrowser() || EOIR.Utils.isInROCBrowserGecko()) && document.location.protocol.substring(0, 2).toLowerCase() != "ms";
		},

		isSCORMCompliant: function ()
		{
			return EOIR.Utils.parseBool(EOIR.Config.getConfigurationParameter("scormcompliant", false));
		},

		parseBool: function (bool)
		{
			if(bool == null)
			{
				return false;
			}

			var strType = typeof (bool);
			if(strType == "string")
			{
				if(bool.toLowerCase() == "true")
				{
					return true;
				}
				else
				{
					var nBool = parseInt(bool);
					if(isNaN(nBool))
					{
						return false;
					}
					else
					{
						return nBool != 0;
					}
				}
			}
			else if(strType == "boolean")
			{
				return bool;
			}
			else if(strType == "number")
			{
				return bool != 0;
			}
			else if(strType == "undefined")
			{
				return false;
			}

			throw "Invalid boolean expression " + bool;
		},

		resetProperties: function ()
		{
			var wndMain = EOIR.Utils.getMainWindow();
			if(wndMain != null)
			{
				wndMain.resetProperties();
			}
		},

		removeProperty: function (strName)
		{
			var wndMain = EOIR.Utils.getMainWindow();
			if(wndMain != null)
			{
				wndMain.removeProperty(strName);
			}
		},

		setProperty: function (strName, vtValue)
		{
			var wndMain = EOIR.Utils.getMainWindow();
			if(wndMain != null)
			{
				wndMain.setProperty(strName, vtValue);
			}
		},

		hasProperty: function (strName)
		{
			var wndMain = EOIR.Utils.getMainWindow();
			if(wndMain != null)
			{
				return wndMain.hasProperty(strName);
			}
			else
			{
				return false;
			}
		},

		getProperty: function (strName, vtDefault)
		{
			return EOIR.Utils.getPropertyDefault(strName, vtDefault);
		},

		getPropertyDefault: function (strName, vtDefault)
		{
			var wndMain = EOIR.Utils.getMainWindow();
			if(wndMain == null)
			{
				return vtDefault;
			}
			else
			{
				var vtProp = wndMain.getProperty(strName);
				if(vtProp == null)
				{
					return vtDefault;
				}
				else
				{
					return vtProp;
				}
			}

			return vtDefault;
		},

		getPropertySetDefault: function (strName, vtDefault)
		{
			var propVal = EOIR.Utils.getPropertyDefault(strName, null);
			if(propVal == null)
			{
				EOIR.Utils.setProperty(strName, vtDefault);
				propVal = vtDefault;
			}

			return propVal;
		},

		getPropertySetEvalDefault: function (strName, strEval)
		{
			var propVal = EOIR.Utils.getPropertyDefault(strName, null);
			if(propVal == null)
			{
				propVal = eval(strEval);
				EOIR.Utils.setProperty(strName, propVal);
			}

			return propVal;
		},

		canEnableNetscapePrivileges: function ()
		{
			try
			{
				return (EOIR.Utils.isInROCBrowserFF() || EOIR.Utils.isInROCBrowserGecko()) && netscape && netscape.security.PrivilegeManager && EOIR.Utils.getPropertyDefault("netscapeExternalOk", true);
			}
			catch(e)
			{
				alert(EOIR.Utils.printStackTrace(e));
				EOIR.Utils.setProperty("netscapeExternalOk", false);
				return false;
			}
		},

		printStackTrace: function (err)
		{
			if(err == null)
			{
				try
				{

					throw new Error("printStackTrace");
				}
				catch(e)
				{
					err = e;
				}
			}

			if(err.stack != null)
			{
				EOIR.External.debugWrite(err.stack);
				return err.stack;
			}

			return "";
		},

		windowCheck: function (strRelURL)
		{
			/*			if(window.parent == null || window.parent.document.getElementById("frmChild") == null)
			//	if(window.parent == null || window.parent.frames.length < 1)
			{
			if(strRelURL == null)
			{
			strRelURL = EOIR.Utils.getPathToMain();
			}
			else
			{
			if(right(strRelURL, 1) != "/")
			{
			strRelURL += "/";
			}
			}

			window.location = strRelURL + "main.htm#" + window.encodeURI(window.location);
			return false;
			}
			else
			{
			if(window.parent.frames.length == 1)
			{
			if(document.title.substr(0, 5) != "ROC-V")
			{
			window.parent.document.title = "ROC-V - " + document.title;
			}
			else
			{
			window.parent.document.title = "ROC-V - " + document.title.substr(6);
			}
			}
			}

			EOIR.Utils.setProperty("helpPage", null);

			/*
			attachEventHandler(window, "load", initializeDocumentBody);	
			if(!isDebug())
			{
			attachEventHandler(window, "error", handleError);
			}
			*/
			/*	if(isDebug())
			{
			attachEventHandler(window, "error", onWindowError);		
			}
			*/
			return true;
		},

		navWindowCheck: function (strRelURL)
		{
			if(window.parent == null || window.parent.document.getElementById("navContentFrame") == null)
			//	if(window.parent == null || window.parent.frames.length < 1)
			{
				if(strRelURL == null)
				{
					strRelURL = EOIR.Utils.getPathToMain();
				}
				else
				{
					if(right(strRelURL, 1) != "/")
					{
						strRelURL += "/";
					}
				}

				alert(strRelURL + "nav_frame.htm#url=" + window.encodeURI(window.location));
				window.location = strRelURL + "nav_frame.htm#url=" + window.encodeURI(window.location);
				return false;
			}
			else
			{
				if(window.parent.frames.length == 1)
				{
					if(document.title.substr(0, 5) != "ROC-V")
					{
						window.parent.document.title = "ROC-V - " + document.title;
					}
					else
					{
						window.parent.document.title = "ROC-V - " + document.title.substr(6);
					}
				}
			}

			EOIR.Utils.setProperty("helpPage", null);
			return true;
		},

		getExtension: function (str)
		{
			var nIndex = str.lastIndexOf(".");
			return (nIndex != -1) ? str.substr(nIndex + 1) : "";
		},

		replaceExtension: function (str, ext)
		{
			var nIndex = str.lastIndexOf(".");
			return (nIndex != -1) ? str.substr(0, nIndex + 1) + ext : str;
		},

		getPreviewUrl: function (strFile, cx, cy)
		{
			if(!EOIR.Utils.isInROCBrowser() && !EOIR.Utils.isInROCBrowserGecko())
			{
				return null;
			}
			else
			{
				try
				{
					var strRegisteredTempFile = EOIR.Utils.getRegisteredTempFile(strFile);
					if(strRegisteredTempFile != null)
					{
						EOIR.External.debugWrite("generatePreview (registered) " + strFile + "  " + strRegisteredTempFile + "\n");
						return strRegisteredTempFile;
					}
					var strPreviewUrl = EOIR.Utils.buildPath(EOIR.Utils.getTempEOIRPath(), EOIR.Utils.getTempFile() + ".bmp");

					if(EOIR.Utils.generatePreview(strFile, strPreviewUrl, cx, cy))
					{
						EOIR.Utils.registerTempFile(strPreviewUrl, strFile);
					}
					else
					{
						return null;
					}
					return strPreviewUrl;
				}
				catch(e)
				{
					alert("Exception in getPreviewUrl: " + e.message);
					return null;
				}
			}
		},

		generatePreview: function (strFile, strPreview, cx, cy)
		{
			EOIR.External.debugWrite("generatePreview " + strFile + "  " + strPreview + "\n");
			try
			{
				EOIR.External.generatePreview(strFile, strPreview, cx, cy);
				return true;
			}
			catch(e)
			{
				return false;
			}
		},

		cacheUrl: function (strUrl)
		{
			if(!EOIR.Utils.isInROCBrowser() && !EOIR.Utils.isInROCBrowserGecko())
			{
				return strUrl;
			}
			else
			{
				try
				{
					// This doesn't work properly right now. Use the downloadUrl function instead.
					//	return EOIR.External.cacheUrl(strUrl);
					return this.downloadUrl(strUrl, true);
				}
				catch(e)
				{
					//					alert("Exception in EOIR.Utils.cacheUrl: " + e.description);
					EOIR.External.debugWrite("Exception in EOIR.Utils.cacheUrl: " + e.message);
					return null;
				}
			}
		},

		downloadUrl: function (strUrl, bUseRegistrationCache)
		{
			if(!EOIR.Utils.isInROCBrowser() && !EOIR.Utils.isInROCBrowserGecko())
			{
				return strUrl;
			}
			else
			{
				var strDownloadFile = this.buildPath(this.getTempEOIRPath(), this.getTempFile() + "." + this.getExtension(strUrl));
				var strTempFile = this.downloadUrlToFile(strUrl, strDownloadFile, bUseRegistrationCache);
				if(strTempFile != null)
				{
					return strTempFile;
				}

				return null;
			}
		},

		downloadUrlTo: function (strUrl, strDir, bUseRegistrationCache)
		{
			if(!EOIR.Utils.isInROCBrowser() && !EOIR.Utils.isInROCBrowserGecko())
			{
				return strUrl;
			}
			else
			{
				strDir = strDir ? strDir : this.getTempPath();
				var strDownloadFile = this.buildPath(strDir, this.getFilenameFromPath(strUrl));
				if(this.downloadUrlToFile(strUrl, strDownloadFile, bUseRegistrationCache))
				{
					return strDownloadFile;
				}

				return null;
			}
		},

		downloadUrlToFile: function (strUrl, strFile, bUseRegistrationCache)
		{
			if(!EOIR.Utils.isInROCBrowser() && !EOIR.Utils.isInROCBrowserGecko())
			{
				return strFile;
			}
			else
			{
				try
				{
					if(bUseRegistrationCache)
					{
						var strRegisteredTempFile = this.getRegisteredTempFile(strUrl);
						if(strRegisteredTempFile != null)
						{
							EOIR.External.debugWrite("downloadUrl (registered) " + strUrl + "  " + strRegisteredTempFile + "\n");
							return strRegisteredTempFile;
						}
					}

					if(EOIR.External.downloadUrl(strUrl, strFile))
					{
						this.registerTempFile(strFile, strUrl);
						return strFile;
					}
				}
				catch(e)
				{
					//alert("Exception in EOIR.Utils.downloadUrlToFile: " + e.message);
					EOIR.External.debugWrite("Exception in EOIR.Utils.downloadUrlToFile: " + e.message);
				}

				return null;
			}
		},

		getRegisteredTempFile: function (strTempFile)
		{
			var arrTempFiles = EOIR.Utils.getPropertyDefault("TempFileArray", null);
			if(arrTempFiles == null)
			{
				return null;
			}

			for(var i = 0; i < arrTempFiles.length; i++)
			{
				try
				{
					if(arrTempFiles[i].origfile.toLowerCase() == strTempFile.toLowerCase())
					{
						return arrTempFiles[i].tempfile;
					}
				}
				catch(e)
				{
				}
			}

			return null;
		},

		registerTempFile: function (strTempFile, strOrigFile)
		{
			var arrTempFiles = EOIR.Utils.getPropertyDefault("TempFileArray", null);
			if(arrTempFiles == null)
			{
				arrTempFiles = new Array();
				EOIR.Utils.setProperty("TempFileArray", arrTempFiles);
			}

			arrTempFiles.push(
				{
					tempfile: strTempFile,
					origfile: strOrigFile
				});
		},

		cleanTempFiles: function ()
		{
			if(EOIR.Utils.isInROCBrowser() || EOIR.Utils.isInROCBrowserGecko())
			{
				var arrTempFiles = EOIR.Utils.getPropertyDefault("TempFileArray", null);
				if(arrTempFiles != null)
				{
					var arrTempFilesTemp = [];
					for(var i = 0; i < arrTempFiles.length; i++)
					{
						try
						{
							if(!EOIR.FSO.deleteFile(arrTempFiles[i].tempfile))
							{
								arrTempFilesTemp.push(arrTempFiles[i]);
							}
						}
						catch(e)
						{
						}
					}

					if(arrTempFilesTemp.length > 0)
					{
						EOIR.Utils.setProperty("TempFileArray", arrTempFilesTemp);
					}
					else
					{
						arrTempFiles.length = 0;
					}
				}
			}
		},

		getFilenameFromPath: function (strFile, sep)
		{
			sep = sep ? sep : "/";
			var nLastPathComp = strFile.lastIndexOf(sep);
			if(nLastPathComp != -1)
			{
				return strFile.substr(nLastPathComp + 1);
			}

			return strFile;
		},

		getTempPath: function ()
		{
			var strTempPath = "";
			if(EOIR.Utils.isInROCBrowser())
			{
				strTempPath = EOIR.FSO.getSpecialFolder(2).Path;
			}
			else if(EOIR.Utils.isInROCBrowserGecko())
			{
				netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

				strTempPath = EOIR.FSO.getSpecialFolder(2).path;
			}
			strTempPath = strTempPath.replace(/\\/g, "/");
			return strTempPath;
		},

		getTempFile: function (strPath, strPrefix)
		{
			if(EOIR.Utils.isInROCBrowser() || EOIR.Utils.isInROCBrowserGecko())
			{
				return EOIR.FSO.getTempName();
			}
		},

		getTempEOIRPath: function ()
		{
			return EOIR.Utils.buildPath(EOIR.Utils.getTempPath(), "EOIR");
		},

		getParentElement: function (elem)
		{
			if(elem.parentElement)
			{
				return elem.parentElement;
			}
			else
			{
				return elem.parentNode;
			}
		},

		getParentElementMatchingTag: function (elem, strTagName)
		{
			var elemParent = elem;
			while(elemParent != null)
			{
				if(elemParent.tagName != null)
				{
					if(elemParent.tagName.toLowerCase() == strTagName.toLowerCase())
					{
						return elemParent;
					}
				}

				elemParent = EOIR.Utils.getParentElement(elemParent);
			}

			return elemParent;
		},

		runAndWait: function (strPath)
		{
			return EOIR.Utils.run(strPath, true);
		},

		run: function (strPath, bWait)
		{
			if(EOIR.Utils.isInROCBrowserGecko())
				strPath = strPath.replace("file:///", "", "g");

			try
			{
				bWait = bWait || false;

				EOIR.External.debugWrite("Executing " + strPath + "\n");
				EOIR.External.run(strPath, bWait);
			}
			catch(e)
			{
				try
				{
					var ws = new ActiveXObject("WScript.Shell");
					ws.Run(strPath, 1, bWait);
				}
				catch(e)
				{
					return false;
				}
			}

			return true;
		},

		runProcess: function (strPath)
		{
			if(EOIR.Utils.isInROCBrowserGecko())
				strPath = strPath.replace("file:///", "", "g");

			return EOIR.External.runProcess(strPath);
		},

		isProcessRunning: function (hProcess)
		{
			return EOIR.External.getIsProcessRunning(hProcess);
		},

		closeProcess: function (hProcess)
		{
			try
			{
				EOIR.External.closeProcess(hProcess);
			}
			catch(e)
			{
			}
		},

		launchDocument: function (strDoc, params)
		{
			try
			{
				EOIR.External.launchDocument(strDoc, params);
				return true;
			}
			catch(e)
			{
				return false;
			}
		},

		showWaitCursor: function (bShow)
		{
			try
			{
				EOIR.External.showWaitCursor(bShow);
				//		document.body.disabled = !bShow;
			}
			catch(e)
			{
				if(bShow)
				{
					document.body.style.cursor = "wait";
				}
				else
				{
					document.body.style.cursor = "default";
				}
			}
		},

		writeTextFile: function (strText, strFilename)
		{
			if(EOIR.Utils.canEnableNetscapePrivileges())
				netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

			try
			{
				var ts = EOIR.FSO.createTextFile(strFilename, true);
				ts.Write(strText);
				ts.Close();
			}
			catch(e)
			{
				if(strFilename.substr(0, 7) == "file://")
				{
					strFilename = strFilename.substr(7);
					//		strFilename = strFilename.replace(/\x2f/g, "\\");
				}

				try
				{
					if(strFilename.substr(0, 1) == "/" && strFilename.substr(2, 1) == ":")
					{
						strFilename = strFilename.substr(1);
					}

					var ts = EOIR.FSO.createTextFile(strFilename, true);
					ts.Write(strText);
					ts.Close();
				}
				catch(e)
				{
					try
					{
						if(EOIR.Utils.canEnableNetscapePrivileges())
						{
							//set permissions to allow XPCOM to run
							netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

							EOIR.External.saveText(strFilename, strText);
						}
					}
					catch(e)
					{
						throw e;
					}
				}
			}
		},

		// This is here since under IE, the xmlFile.save doesn't work due to security issues. In the ROCViewer though, it does.
		writeXMLFile: function (xmlFile, strFilename)
		{
			if(!EOIR.Utils.isWebBased())
			{
				try
				{
					// This doesn't work for some reason... maybe browser security issue.
					xmlFile.save(strFilename);
				}
				catch(e)
				{
					try
					{
						EOIR.Utils.writeTextFile(EOIR.XML.serializeChildren(xmlFile), strFilename);
					}
					catch(e)
					{
						EOIR.Utils.showMessageBox("There was an error writing the file " + strFilename + ".\n\n" + e.message, "File Error", MB_OK | MB_ICONEXCLAMATION);
					}
				}
			}
		},

		getIFrameDocument: function (id)
		{
			// if contentDocument exists, W3C compliant (Mozilla)
			if($(id).contentDocument)
			{
				return $(id).contentDocument;
			}
			else
			{
				// IE
				return document.frames[id].document;
			}
		},

		getPageParameters: function ()
		{
			var strQuery = window.location.hash.substr(1);
			if(strQuery.length == 0)
			{
				strQuery = window.location.search.substr(1);
			}

			var arrParsed = new Array();

			var arrParams = strQuery.split("&");
			if(arrParams.length == 0)
			{
				var arrParam = strQuery.split("=");
				if(arrParam.length >= 2)
				{
					arrParsed[arrParam[0]] = unescape(arrParam[1]);
					for(var j = 2; j < arrParam.length; j++)
					{
						arrParsed[arrParam[0]] += "=" + unescape(arrParam[j]);
					}
				}
				else
				{
					arrParsed[arrParam[0]] = true;
				}
			}
			else
			{
				for(var i = 0; i < arrParams.length; i++)
				{
					var arrParam = arrParams[i].split("=");
					if(arrParam.length >= 2)
					{
						arrParsed[arrParam[0]] = unescape(arrParam[1]);
						for(var j = 2; j < arrParam.length; j++)
						{
							arrParsed[arrParam[0]] += "=" + unescape(arrParam[j]);
						}
					}
					else
					{
						arrParsed[arrParam[0]] = true;
					}
				}
			}

			return arrParsed;
		},

		getPageParameter: function (strParamName, strDefaultValue)
		{
			var params = this.getPageParameters();

			var strValue;
			if(params == null)
			{
				strValue = strDefaultValue;
			}
			else
			{
				strValue = params[strParamName];
				if(strValue == null)
				{
					strValue = strDefaultValue;
				}
			}

			return strValue;
		},

		getRandomNumber: function (min, max)
		{
			return Math.round(Math.random() * (max - min) + min);
		},

		randomizeArray: function (arr)
		{
			return arr != null ? arr.sort(function () { return 0.5 - Math.random(); }) : null;
		},

		//given the name/id of the flash object, returns the object
		//   in the browser appropriate way
		getObject: function (strName)
		{
			if(window.document[strName])
			{
				//mozilla
				return window.document[strName];
			}
			if(navigator.appName.indexOf("Microsoft Internet") == -1)
			{
				//firefox, opera, and possibly safari (?)
				if(document.embeds && document.embeds[strName])
					return document.embeds[strName];
			}
			else
			{
				//IE
				return document.getElementById(strName);
			}
		},

		setTitleBarLabel: function (strTitle, strSubTitle)
		{
			try
			{
				var wnd = window;
				var bExit = false;

				do
				{
					try
					{
						wnd.setTitleBarTitle(strTitle, strSubTitle);
						bExit = true;
					}
					catch(e)
					{
						wnd = wnd.parent;
					}
				} while(!bExit && wnd != window.top);
			}
			catch(e)
			{
			}
		},

		getTitleBarLabel: function ()
		{
			try
			{
				var wnd = window;

				do
				{
					try
					{
						return wnd.getTitleBarTitle();
					}
					catch(e)
					{
						wnd = wnd.parent;
					}
				} while(wnd != window.top);

			}
			catch(e)
			{
			}

			return null;
		},

		setPageNumLabel: function (strPageNumLabel)
		{
			try
			{
				var wnd = window;
				var bExit = false;

				do
				{
					try
					{
						wnd.setPageTitle(strPageNumLabel);
						bExit = true;
					}
					catch(e)
					{
						wnd = wnd.parent;
					}
				} while(!bExit && wnd != window.top);
			}
			catch(e)
			{
			}
		},

		getInsertionIndex: function (o, v, i)
		{
			var h = o.length, l = -1, m;
			while(h - l > 1)
				if(o[m = h + l >> 1] < v) l = m;
				else h = m;
			return o[h] != v ? i ? h : -1 : h;
		},

		getInsertionIndexComp: function (o, v, i, fnComp)
		{
			var h = o.length, l = -1, m;
			while(h - l > 1)
				if(fnComp(o[m = h + l >> 1], v) < 0) l = m;
				else h = m;
			return fnComp(o[h], v) != 0 ? i ? h : -1 : h;
		},

		getUnique: function (arr)
		{
			var r = [];
			o: for(var i = 0, n = arr.length; i < n; i++)
			{
				for(var x = 0, y = r.length; x < y; x++)
				{
					if(r[x] == arr[i]) continue o;
				}
				r[r.length] = arr[i];
			}
			return r;
		},

		isDigit: function (a)
		{
			return (a >= '0' && a <= '9');
		},

		getFileName: function (bOpenDialog, strFilter, strDefaultFile, strDefaultExt)
		{
			try
			{
				var strFilename;

				try
				{
					// First, let's try the *new* way to get the external.
					strFilename = EOIR.External.filenameFromCommonDlg(bOpenDialog, strFilter, strDefaultFile, strDefaultExt);
				}
				catch(e)
				{
					try
					{
						// Then, let's try the old way.
						strFilename = getExternal().FilenameFromCommonDlg(bOpenDialog, strFilter, strDefaultFile, strDefaultExt);
					}
					catch(e)
					{
						// Oops, neither one worked. Let's try the ActiveX way (below).
						throw e;
					}
				}

				if(strFilename == "")
				{
					return null;
				}
				else
				{
					return strFilename;
				}
			}
			catch(e)
			{
				try
				{
					// This requires an ActiveX control be registered. ROCBrowser should never get here.
					var objCmdDlg = new ActiveXObject("MSComDlg.CommonDialog");
					objCmdDlg.Filter = strFilter;
					objCmdDlg.FilterIndex = 1;
					objCmdDlg.MaxFileSize = 256;
					objCmdDlg.Flags = 6;
					objCmdDlg.FileName = strDefaultFile;
					objCmdDlg.CancelError = true;
					objCmdDlg.DefaultExt = strDefaultExt;

					try
					{
						if(bOpenDialog)
						{
							objCmdDlg.ShowOpen();
						}
						else
						{
							objCmdDlg.ShowSave();
						}

						return objCmdDlg.FileName;
					}
					catch(e)
					{
						return null;
					}
				}
				catch(e)
				{
					return null;
				}
			}

			return null;
		},

		getBrowserInfo: function ()
		{
			var nVer = navigator.appVersion;
			var nAgt = navigator.userAgent;
			var browserName = navigator.appName;
			var fullVersion = '' + parseFloat(navigator.appVersion);
			var majorVersion = parseInt(navigator.appVersion, 10);
			var nameOffset, verOffset, ix;

			// In MSIE, the true version is after "MSIE" in userAgent
			if((verOffset = nAgt.indexOf("MSIE")) != -1)
			{
				browserName = "Microsoft Internet Explorer";
				fullVersion = nAgt.substring(verOffset + 5);
			}
			// In Opera, the true version is after "Opera" 
			else if((verOffset = nAgt.indexOf("Opera")) != -1)
			{
				browserName = "Opera";
				fullVersion = nAgt.substring(verOffset + 6);
			}
			// In Chrome, the true version is after "Chrome" 
			else if((verOffset = nAgt.indexOf("Chrome")) != -1)
			{
				browserName = "Chrome";
				fullVersion = nAgt.substring(verOffset + 7);
			}
			// In Safari, the true version is after "Safari" 
			else if((verOffset = nAgt.indexOf("Safari")) != -1)
			{
				browserName = "Safari";
				fullVersion = nAgt.substring(verOffset + 7);
			}
			// In Firefox, the true version is after "Firefox" 
			else if(((verOffset = nAgt.indexOf("Firefox")) != -1) && (!EOIR.Utils.isInROCBrowserGecko()))
			{
				browserName = "Firefox";
				fullVersion = nAgt.substring(verOffset + 8);
			}
			// In most other browsers, "name/version" is at the end of userAgent 
			else if((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/')))
			{
				browserName = nAgt.substring(nameOffset, verOffset);
				fullVersion = nAgt.substring(verOffset + 1);
				if(browserName.toLowerCase() == browserName.toUpperCase())
				{
					browserName = navigator.appName;
				}
			}
			// trim the fullVersion string at semicolon/space if present
			if((ix = fullVersion.indexOf(";")) != -1) fullVersion = fullVersion.substring(0, ix);
			if((ix = fullVersion.indexOf(" ")) != -1) fullVersion = fullVersion.substring(0, ix);

			majorVersion = parseInt('' + fullVersion, 10);
			if(isNaN(majorVersion))
			{
				fullVersion = '' + parseFloat(navigator.appVersion);
				majorVersion = parseInt(navigator.appVersion, 10);
			}

			return {
				name: browserName,
				fullver: fullVersion,
				majver: majorVersion
			};
		},

		// This does the same thing as StrCmpLogical which takes numbers into account when
		// sorting strings. Can be passed to array.sort().
		strCmpLogical: function (a, b)
		{
			try
			{
				//				return EOIR.External.get().LogicalStrCmp(a, b);
				return EOIR.External.strCmpLogical(a, b);
			}
			catch(e)
			{
				var i = 0;
				var j = 0;

				if(a && b)
				{
					while(i < a.length)
					{
						if(j == b.length)
						{
							return 1;
						}
						else if(EOIR.Utils.isDigit(a.charAt(i)))
						{
							if(!EOIR.Utils.isDigit(b.charAt(j)))
							{
								return -1;
							}

							var nA, nB;
							nA = parseInt(a.substr(i));
							nB = parseInt(b.substr(j));

							if(nA < nB)
							{
								return -1;
							}
							else if(nA > nB)
							{
								return 1;
							}

							while(EOIR.Utils.isDigit(a.charAt(i)))
							{
								i++;
							}
							while(EOIR.Utils.isDigit(b.charAt(j)))
							{
								j++;
							}
						}
						else if(EOIR.Utils.isDigit(b.charAt(j)))
						{
							return 1;
						}
						else
						{
							var diff = a.charCodeAt(i) - b.charCodeAt(j);
							if(diff > 0)
							{
								return 1;
							}
							else if(diff < 0)
							{
								return -1;
							}

							i++;
							j++;
						}
					}

					return (j < b.length) ? -1 : 0;
				}
			}

			return 0;
			/*
			2127 INT WINAPI StrCmpLogicalW(LPCWSTR lpszStr, LPCWSTR lpszComp)
			2128 {
			2129   INT iDiff;
			2130 
			2131   TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszComp));
			2132 
			2133   if (lpszStr && lpszComp)
			2134   {
			2135     while (*lpszStr)
			2136     {
			2137       if (!*lpszComp)
			2138         return 1;
			2139       else if (isdigitW(*lpszStr))
			2140       {
			2141         int iStr, iComp;
			2142 
			2143         if (!isdigitW(*lpszComp))
			2144           return -1;
			2145 
			2146         /* Compare the numbers *-/
			2147         StrToIntExW(lpszStr, 0, &iStr);
			2148         StrToIntExW(lpszComp, 0, &iComp);
			2149 
			2150         if (iStr < iComp)
			2151           return -1;
			2152         else if (iStr > iComp)
			2153           return 1;
			2154 
			2155         /* Skip *-/
			2156         while (isdigitW(*lpszStr))
			2157           lpszStr++;
			2158         while (isdigitW(*lpszComp))
			2159           lpszComp++;
			2160       }
			2161       else if (isdigitW(*lpszComp))
			2162         return 1;
			2163       else
			2164       {
			2165         iDiff = ChrCmpIW(*lpszStr,*lpszComp);
			2166         if (iDiff > 0)
			2167           return 1;
			2168         else if (iDiff < 0)
			2169           return -1;
			2170 
			2171         lpszStr++;
			2172         lpszComp++;
			2173       }
			2174     }
			2175     if (*lpszComp)
			2176       return -1;
			2177   }
			2178   return 0;
			2179 }
			*/
		}


	};

	return obj;
} ();

EOIR.Utils.getAttributeSafe = function(domNode, strAttr)
{
    var strValue = null; //""; //see https://developer.mozilla.org/en/DOM:element.getAttribute#Notes for proper return value for this function
    try
    {
        strValue = domNode.getAttribute(strAttr);
    }
    catch(e)
    {
        //gecko support?
        if(domNode.hasChildNodes())
        {
            for(var j = 0; j < domNode.childNodes.length; j++)
            {
                var node = domNode.childNodes[j];
                if(node.nodeType == 2)
                {
                    strValue = node.getAttribute(strAttr);
                    break;
                }
            }
        }
    }
    return strValue;
}

EOIR.Utils.setAttributeSafe = function(domNode, strAttr, value)
{
    try
    {
        domNode.setAttribute(strAttr, value);
    }
    catch(e)
    {
        //gecko support?
        if(domNode.hasChildNodes())
        {
            for(var j = 0; j < domNode.childNodes.length; j++)
            {
                var node = domNode.childNodes[j];
                if(node.nodeType == 2)
                {
                    node.setAttribute(strAttr, value);
                    break;
                }
            }
        }
    }
}

EOIR.Utils.Filter = function()
{
	var obj =
	{
		setFilter: function(elem, strFilter)
		{
			try
			{
				elem.style.filter = strFilter;
			}
			catch(e)
			{
			}
		},

		enableFilter: function(elem, strFilt, bEnable)
		{
			try
			{
				var filt = elem.filters[strFilt];
				if(filt != null)
				{
					filt.Enabled = bEnable;
					return true;
				}
			}
			catch(e)
			{
			}

			return false;
		},

		isHighlighted: function(elem)
		{
			try
			{
				var filt = elem.filters["DXImageTransform.Microsoft.Shadow"];
				if(filt != null)
				{
					return filt.Enabled;
				}
			}
			catch(e)
			{
			}

			return false;
		},

		pulseElement: function(elem)
		{
			if(!this.isHighlighted(elem))
			{
				this.highlightElement(elem);
			}
			else
			{
				this.hideHighlight(elem);
			}
		},

		highlightElement: function(elem, color)
		{
			if(!this.enableFilter(elem, "DXImageTransform.Microsoft.Shadow", true))
			{
				if(color == null)
				{
					color = "green";
				}

				this.setFilter(elem, "progid:DXImageTransform.Microsoft.Shadow(color='" + color + "', Direction=135, Strength=8)");
			}
		},

		hideHighlight: function(elem)
		{
			this.enableFilter(elem, "DXImageTransform.Microsoft.Shadow", false);
		}
	}
	return obj;
} ();


var $;
try
{
	$ = YAHOO.util.Dom.get;
}
catch(e)
{
	$ = function(strElem) { return document.getElementById(strElem); };
}

