/*
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.
*/

// Depends on XML
// Depends on Utils


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

	return obj;
} ();

EOIR.Config = function(fnLoaded, strConfigCode, strConfigFile)
{
	this.m_xml = null;
	this.m_strConfigCode = strConfigCode;

	this.getConfigCode = function() { return (this.m_strConfigCode == null) ? "" : this.m_strConfigCode; }

	this._load = function(strConfigCode, fnLoaded, strConfigFile)
	{
		if(strConfigFile == null)
		{
			strConfigFile = EOIR.Config.getConfigFile(strConfigCode);
		}

		if(EOIR.Utils.isWebBased())
		{
			strConfigFile += "?time=" + new Date().getTime();
		}

		if(this.m_xml == null)
		{
			// There's a problem with this. If we're changing instructor codes, then the cached config is no longer
			// valid. Need to rework this.
			//			this.m_xml = EOIR.Utils.getProperty("xmlconfig");
			if(this.m_xml == null)
			{
				var wndMain = EOIR.Utils.getMainWindow();
				if(false) //if(window != wndMain && wndMain != null)
				{
					// Force the config to always be loaded in the main EOIR window
					// if possible. This is to allow the caching to work properly
					// on some browsers (Firefox) that like to garbage collect
					// objects when the page that creates the objects exits.
					return wndMain.EOIR.Config.get(fnLoaded);
				}
				else
				{
					if(false) //EOIR.Utils.isWebBased() && !EOIR.Utils.isSCORMCompliant())
					{
						this.m_xml = EOIR.Config._executeConfigFunction("eval=config_get()");
						if(fnLoaded != null)
						{
							fnLoaded(this);
						}
					}
					else
					{
						this.m_xml = EOIR.XML.createObject();
						try
						{
							EOIR.XML.loadDocument(this.m_xml, strConfigFile, fnLoaded != null, fnLoaded, null, this);
						}
						catch(e)
						{
							this.m_xml = null;
							throw e;
						}
					}

					//					EOIR.Utils.setProperty("xmlconfig", this.m_xml);
				}

				if(this.m_xml == null)
				{
					alert("Could not load configuration file: " + strConfigFile);
				}
			}
			else
			{
				if(fnLoaded != null)
				{
					fnLoaded(this);
				}
			}
		}
		else
		{
			if(fnLoaded != null)
			{
				fnLoaded(this);
			}
		}

		// Return ourselves if we're the main EOIR window or if that window
		// doesn't exist.	
		return this;
	};

	this.unloadConfigFile = function()
	{
		this.m_xml = null;
	}
	this.loadConfigFile = function()
	{
		this._load(null, null);
	}

	this.getXMLDocument = function()
	{
		return this.m_xml;
	}

	this.isValid = function()
	{
		return this.m_xml != null;
	}

	this.getTargetSets = function()
	{
		var objNodeList = this.m_xml.selectNodes("configuration/filesets/fileset");
		var arr = [];

		for(var i = 0; i < objNodeList.length; i++)
		{
			arr.push(new EOIR.TargetSet(
				objNodeList[i].getAttribute("id"),
				objNodeList[i].getAttribute("description")));
		}

		return arr;
	}

	this.getEditableTargetSets = function()
	{
		var objNodeList = this.m_xml.selectNodes("configuration/filesets/fileset");
		var arr = [];

		for(var i = 0; i < objNodeList.length; i++)
		{
			if(objNodeList[i].getAttribute("editable") != "false")
			{
				arr.push(new EOIR.TargetSet(
				    objNodeList[i].getAttribute("id"),
				    objNodeList[i].getAttribute("description")));
			}
		}

		return arr;
	}

	this.getIsPermanent = function(targetSetId)
	{
		var objNodeList = this.m_xml.selectNodes("configuration/filesets/fileset[@id='" + targetSetId + "']");
		if(objNodeList.length > 0)
			return EOIR.Utils.parseBool(objNodeList[0].getAttribute("permanent"));
		else
			return false;
	}
	/*	
	this.isSetEquivalent = function(strID, arrNewSet)
	{
	var arrOldSet = this.getTargetSetById(strID);
	    
	//check name
	if(arrOldSet.Description != arrNewSet.Description)
	return false;
	    
	//check confusion sets
	if(arrOldSet.ConfusionSets.length != arrNewSet.ConfusionSets.length)
	return false;
	for(var i = 0; i < arrOldSet.ConfusionSets.length; i++)
	{
	if(arrOldSet.ConfusionSets[i].length != arrNewSet.ConfusionSets[i].length)
	return false;
	for(var j = 0; j < arrOldSet.ConfusionSets[i].length; j++)
	{
	if(arrOldSet.ConfusionSets[i][j] != arrNewSet.ConfusionSets[i][j])
	return false;
	}
	}
	    
	//check test settings
	    
	//check other settings
	    
	return true;
	}
	*/

	this.addTargetSet = function(ts)
	{
		var objNodeList = this.m_xml.selectNodes("configuration/filesets");
		objNodeList[0].appendChild(ts.serialize(this.m_xml));

		this.saveConfigurationSets();
	}

	this.replaceTargetSet = function(ts)
	{
		var node = this.getTargetSetNode(ts.ID);
		if(node == null)
		{
			return false;
		}

		var tsnodeNew = ts.serialize(this.m_xml);
		node.parentNode.replaceChild(tsnodeNew, node);

		this.saveConfigurationSets();
		return true;
	}

	this.removeTargetSet = function(ts)
	{
		var node;
		if(typeof (ts) == "string")
		{
			node = this.getTargetSetNode(ts);
		}
		else
		{
			node = this.getTargetSetNode(ts.ID);
		}

		if(node != null)
		{
			node.parentNode.removeChild(node);
		}

		this.saveConfigurationSets();
	}

	this.saveConfigurationSets = function()
	{
		if(!EOIR.Utils.isSCORMCompliant())
		{
			if(EOIR.Utils.isWebBased())
			{
				EOIR.Config._executeConfigFunction("eval=config_replaceFilesets('" + this.getConfigCode() + "')&xml=" + EOIR.XML.serializeChildren(this.m_xml.selectSingleNode("configuration/filesets")));
			}
			else
			{
				EOIR.Utils.writeXMLFile(this.m_xml, EOIR.Config.getConfigFile(this.getConfigCode()));
			}
		}
	}

	this.setTargetSets = function(arrSets)
	{
		var objNodeList = this.m_xml.selectNodes("configuration/filesets");

		//find all hidden sets
		//var objHiddenSets = this.m_xml.selectNodes("configuration/filesets/fileset[@editable='false']");


		//save these attributes which would otherwise be lost; also store the original nodes in memory
		var objOriginalNodes = {};
		for(var i = 0; i < arrSets.length; i++)
		{
			objOriginalNodes[arrSets[i].ID] = this.getTargetSetNode(arrSets[i].ID);

			if(this.getIsPermanent(arrSets[i].ID))
				arrSets[i].permanent = true;
			else
				arrSets[i].permanent = false;
		}

		//remove all the previous sets
		var nextNode = objNodeList[0].firstChild;
		while(nextNode != null)
		{
			//move to the next node
			var curNode = nextNode;
			nextNode = curNode.nextSibling;

			//remove it if we are allowed to
			var editable = curNode.getAttribute("editable");
			if(editable == null || editable == "true")
				objNodeList[0].removeChild(curNode);
		}

		//we always stick the non-editable ones (SMCT in reality) at the end of the list; record where this is
		//   so we can use the insertBefore function
		var objFirstEditable = objNodeList[0].firstChild;

		//add the new ones
		for(var i = 0; i < arrSets.length; i++)
		{
			var fileset = arrSets[i].serialize(this.m_xml);

			if(objOriginalNodes[arrSets[i].ID])
			{
				var origModTime = objOriginalNodes[arrSets[i].ID].getAttribute("modtime");
				if(origModTime != null)
					fileset.setAttribute("modtime", origModTime);
				else
				{
					//alert("set missing a mod time!: " + arrSets[i].ID);
					fileset.setAttribute("modtime", (new Date()).getTime()); //in case the orig target set had no modtime			    
				}
			}

			//add these back in
			if(arrSets[i].permanent)
			{
				fileset.setAttribute("permanent", "true");
			}


			//do the final add
			if(objFirstEditable != null)
				objNodeList[0].insertBefore(fileset, objFirstEditable);
			else
				objNodeList[0].appendChild(fileset);
		}

		//add the hidden sets back in
		//for(var i = 0; i < objHiddenSets.length; i++)
		//{
		//	objNodeList[0].appendChild(objHiddenSets[i]);
		//}

		//save our changes
		if(!EOIR.Utils.isSCORMCompliant())
		{
			if(EOIR.Utils.isWebBased())
			{
				EOIR.Config._executeConfigFunction("eval=config_replaceFilesets('" + this.getConfigCode() + "')&xml=" + EOIR.XML.serializeChildren(this.m_xml.selectSingleNode("configuration/filesets")));
			}
			else
			{
				EOIR.Utils.writeXMLFile(this.m_xml, EOIR.Config.getConfigFile(this.getConfigCode()));
			}
		}
	}

	this.getTargetSetTargetList = function(strSetId)
	{
		return this.getTargetSetConfigNode(strSetId).getTargetList();
	};

	this.getCurrentTargetSet = function()
	{
		return this.getTargetSetById(EOIR.Config.getCurrentTargetSetId());
	}

	this.getTargetSetById = function(strId)
	{
		var nodeTS = this.getTargetSetNode(strId);
		if(nodeTS != null)
		{
			return new EOIR.TargetSet(nodeTS.getAttribute("id"), nodeTS.getAttribute("description"));
		}
	}

	this.getTargetSetNode = function(strId)
	{
		try
		{
			var nodes = this.m_xml.selectNodes("configuration/filesets/fileset[@id = '" + strId + "']");
			if(nodes != null && nodes.length > 0)
			{
				return nodes[0];
			}
		}
		catch(e)
		{
		}
		return null;
	}

	this.getTargetSetConfigNode = function(strId)
	{
		var node = this.getTargetSetNode(strId);
		return node == null ? null : new EOIR.TargetSetConfigNode(node);
	}

	this.setSetting = function(strSettingName, strSettingValue)
	{
		var nodeSettings = this.m_xml.selectSingleNode("configuration/settings");
		if(nodeSettings == null)
		{
			//			nodeSettings = createNodes(xml, "configuration/settings");
			return;
		}

		if(strSettingValue == null)
		{
			nodeSettings.removeAttribute(strSettingName);
		}
		else
		{
			nodeSettings.setAttribute(strSettingName, strSettingValue);
		}

		if(EOIR.Utils.isInBrowser() && EOIR.Utils.isWebBased() && !EOIR.Utils.isSCORMCompliant())
		{
			if(strSettingValue == null)
			{
				EOIR.Config._executeConfigFunction("eval=config_removesetting('" + this.getConfigCode() + "', '" + strSettingName + "')");
			}
			else
			{
				EOIR.Config._executeConfigFunction("eval=config_setsetting('" + this.getConfigCode() + "', '" + strSettingName + "', '" + strSettingValue + "')");
			}
		}
		else
		{
			this.saveConfigFile();
		}

		// Notify all windows that the configuration has changed.
		try
		{
			var wnd = window;
			while(wnd != window.top && wnd != null)
			{
				try
				{
					wnd.configUpdated();
				}
				catch(e)
				{
				}

				wnd = wnd.parent;
			}
		} catch(e) { }

		return true;
	}

	this.saveConfigFile = function()
	{
		//		writeXMLFile(xml, getConfigFile());
		//throw "Not implemented - saveConfigFile";

		EOIR.Utils.writeXMLFile(this.m_xml, EOIR.Config.getConfigFile(this.getConfigCode()));
	}

	this.getSetting = function(strSettingName)
	{
		return this.getSettingDefault(strSettingName, null);
	}

	this.getSettingDefaultInt = function(strSettingName, nDefault)
	{
		try
		{
			return parseInt(this.getSettingDefault(strSettingName, nDefault.toString()));
		}
		catch(e)
		{
			return nDefault;
		}
	}

	this.getSettingDefault = function(strSettingName, strDefault)
	{
		var nodeSettings = this.m_xml.selectSingleNode("configuration/settings");
		if(nodeSettings == null)
		{
			return strDefault;
		}

		var strProp = nodeSettings.getAttribute(strSettingName);
		if(strProp == null || strProp == "")
		{
			return strDefault;
		}
		else
		{
			return strProp;
		}
	}

	this.getRedMask = function()
	{
		return this.getTargetSetSetting(EOIR.Config.getCurrentTargetSetId(), "redmask", 0);

		//return this.getSettingDefaultInt("redMask", 0);
	}

	this.setRedMask = function(nRedMask)
	{
		return this.setTargetSetSetting(EOIR.Config.getCurrentTargetSetId(), "redmask", nRedMask);

		//this.setSetting("redMask", nRedMask);
	}

	this.getGreenMask = function()
	{
		return this.getTargetSetSetting(EOIR.Config.getCurrentTargetSetId(), "greenmask", 0);

		//return this.getSettingDefaultInt("greenMask", 0);
	}

	this.setGreenMask = function(nGreenMask)
	{
		return this.setTargetSetSetting(EOIR.Config.getCurrentTargetSetId(), "greenmask", nGreenMask);

		//this.setSetting("greenMask", nGreenMask);
	}

	this.getBlueMask = function()
	{
		return this.getTargetSetSetting(EOIR.Config.getCurrentTargetSetId(), "bluemask", 0);

		//return this.getSettingDefaultInt("blueMask", 0);
	}

	this.setBlueMask = function(nBlueMask)
	{
		return this.setTargetSetSetting(EOIR.Config.getCurrentTargetSetId(), "bluemask", nBlueMask);

		//this.setSetting("blueMask", nBlueMask);
	}

	this.getLoginVS = function()
	{
		var strLoginVS = this.getSettingDefault("loginvs", null);
		var vs = this.getTargetSetById(strLoginVS);
		if(vs == null)
		{
			return null;
		}
		else
		{
			return strLoginVS;
		}
	}

	this.setLoginVS = function(strNewLoginVS)
	{
		this.setSetting("loginvs", strNewLoginVS);
	}

	this.getDemoVS = function()
	{
		var strDemoVS = this.getSettingDefault("demovs", null);

		var vs = this.getTargetSetById(strDemoVS);
		if(vs == null)
		{
			return null;
		}
		else
		{
			return strDemoVS;
		}
	}

	this.setDemoVS = function(strNewDemoVS)
	{
		this.setSetting("demovs", strNewDemoVS);
	}

	this.getConfusionSetsFromTargetSet = function(ts)
	{
		return this.getConfusionSetsFromTargetSetId(ts.ID);
	}

	this._createConfusionSetFromNode = function(node)
	{
		var arrConfusionSet = [];
		var nodesTgts = node.selectNodes("target");

		for(var j = 0; j < nodesTgts.length; j++)
		{
			arrConfusionSet.push(nodesTgts[j].getAttribute("name"));
		}

		var arrValidated = EOIR.DB.validateTargets(arrConfusionSet);
		if(node.getAttribute("name") != null)
		{
			arrValidated.name = node.getAttribute("name");
		}
		return arrValidated;
	}

	this.getConfusionSetsFromTargetSetId = function(strId)
	{
		var arrConfusionSets = [];

		var nodes = this.m_xml.selectNodes("configuration/filesets/fileset[@id='" + strId + "']/confusionsets/confusionset");
		if(nodes == null || nodes.length == 0)
		{
			var tgtSet = this.getTargetSetById(strId);
			tgtSet.autogenerateConfusionSets(tgtSet.getTargetList());
			return tgtSet.ConfusionSets;
		}
		else
		{
			for(var i = 0; i < nodes.length; i++)
			{
				var cs = this._createConfusionSetFromNode(nodes[i]);
				arrConfusionSets.push(cs);
			}
		}

		return arrConfusionSets;
	}

	this.getOtherSettingsFromTargetSetId = function(strId)
	{
		var objSettings =
		{
			difficulty: "easy",
			passscore: "85",
			timedsigtime: "15",
			redmask: "255",
			greenmask: "255",
			bluemask: "255",
			preferredorientation: "none",
			vsquizquest: 10,
			vstestquest: 15
		};

		var nodes = this.m_xml.selectNodes("configuration/filesets/fileset[@id='" + strId + "']/settings/setting");

		for(var i = 0; i < nodes.length; i++)
		{
			var name = nodes[i].getAttribute("name");
			objSettings[name] = nodes[i].getAttribute("value");
		}
		return objSettings;
	}

	this.getTestSettingsFromTargetSetId = function(strId, isTherm, isPre)
	{
		// Default
		var objSettings =
		{
			generaterandom: true,
			numberquestions: 50,
			showtime: 10,
			additionaltime: 5,
			completionscore: 80,
			randomizeorder: true
		};

		var getAttributeDefault = function(node, strAttrib, defVal)
		{
			if(node == null)
			{
				return defVal;
			}

			var value = node.getAttribute(strAttrib);
			if(value == null || value == "")
			{
				return defVal;
			}
			return value;
		}

		var testTime = isPre ? "pretest" : "posttest";
		var nodes = this.m_xml.selectNodes("configuration/filesets/fileset[@id='" + strId + "']/tests/" + testTime);

		for(var i = 0; i < nodes.length; i++)
		{
			if((isTherm && nodes[i].getAttribute("type") == "thermal") ||
	            (!isTherm && nodes[i].getAttribute("type") != "thermal"))
			{

				objSettings =
				{
					generaterandom: getAttributeDefault(nodes[i], "generaterandom", true),
					numberquestions: getAttributeDefault(nodes[i], "numberquestions", 50),
					showtime: getAttributeDefault(nodes[i], "showtime", 10),
					additionaltime: getAttributeDefault(nodes[i], "additionaltime", 5),
					completionscore: getAttributeDefault(nodes[i], "completionscore", 80),
					randomizeorder: getAttributeDefault(nodes[i], "randomizeorder", true)
				}

				objSettings["Targets"] = [];
				//var tgts = nodes.selectNodes("target");

				var tgts = this.m_xml.selectNodes("configuration/filesets/fileset[@id='" + strId + "']/tests/" +
                    testTime + "[@type='" + (isTherm ? "thermal" : "visible") + "']/target");

				for(var j = 0; j < tgts.length; j++)
				{
					var objTgt =
					{
						tgt: tgts[j].getAttribute("shortname"),
						venue: tgts[j].getAttribute("variant"),
						variant: tgts[j].getAttribute("variant"),
						range: tgts[j].getAttribute("range"),
						tod: tgts[j].getAttribute("tod")
					};

					if(tgts[j].getAttribute("type") == "lwir")
						objTgt.band = "8-12";
					else if(tgts[j].getAttribute("type") == "mwir")
						objTgt.band = "3-5";
					else
						objTgt.band = "Vis";

					objTgt.aspect = tgts[j].getAttribute("aspect") + (tgts[j].getAttribute("dlangle") != "60" ? "" : "-DL");

					objSettings["Targets"].push(objTgt);
				} //for j
				break;
			} //if test is right
		} //for i
		return objSettings;
	}

	this.setSimPanelIcon = function(strPanelName, strIconFile)
	{
		var nodePanel = this.xml.selectSingleNode("configuration/simpanels/simpanel[@name='" + strPanelName + "']");
		if(nodePanel != null)
		{
			nodePanel.setAttribute("icon", strIconFile);
			/*    		
			if(isInBrowser() && isWebBased() && !isSCORMCompliant())
			{
			EOIR.Config._executeConfigFunction("eval=config_setsimpanelattribute('" + strPanelName + "', 'icon', '" + strIconFile + "')");
			}
			else
			{
			this.saveConfigFile();
			}
			*/
		}
	}

	this.setConfigVersionProperty = function(strProp, strValue)
	{
		var nodeVersion = this.m_xml.selectSingleNode("configuration/version");
		if(nodeVersion != null)
		{
			nodeVersion.setAttribute(strProp, strValue);
		}
	}

	this.preservePermanentSets = function(oldCfg)
	{
		var uneditable = oldCfg.m_xml.selectNodes("/configuration/filesets/fileset[@editable='false']");
		//var permanent = oldCfg.m_xml.selectNodes("/configuration/filesets/fileset[@permanent='true']");

		var oldSets = uneditable;

		for(var i = 0; i < oldSets.length; i++)
		{
			var newSet = this.m_xml.selectSingleNode("/configuration/filesets/fileset[@id='" + oldSets[i].getAttribute("id") + "']");

			//remove the uneditable set from the new config (if it exists), and then replace it with the one from the old file
			var parent = this.m_xml.selectSingleNode("/configuration/filesets");
			if(parent)
			{
				if(newSet)
					parent.removeChild(newSet);
				parent.appendChild(oldSets[i]);
			}
		}
	}

	this.consolidateVehicleNames = function()
	{
		//even indexes are the new vehicle names, while odd indexes are all the old names that map to it
		var arrConsolidatedVehicles = new Array
	    (
	        "T-X", new Array("T-1", "T-2", "T-3"),
	        "A-X", new Array("A-1", "A-2")
	    );


		var vehicleSets = this.m_xml.selectNodes("/configuration/filesets/fileset");
		for(var x = 0; x < vehicleSets.length; x++)
		{
			var cfSets = vehicleSets[x].selectNodes("confusionsets/confusionset");
			for(var y = 0; y < 1 + cfSets.length; y++)
			{
				var arrConsolidatedTargets = new Array(); //holds targets to add back in at the end

				var tgtNodes = null;
				if(y == 0)
					tgtNodes = vehicleSets[x].selectNodes("targetlist/target");
				else
					tgtNodes = cfSets[y - 1].selectNodes("target");

				for(var i = 0; i < tgtNodes.length; i++)
				{
					//get the name
					var name = tgtNodes[i].getAttribute("shortname");
					if(!name)
						name = tgtNodes[i].getAttribute("name");

					var bFound = false;
					for(var j = 1; j < arrConsolidatedVehicles.length && !bFound; j += 2)
					{
						for(var k = 0; k < arrConsolidatedVehicles[j].length && !bFound; k++)
						{
							if(name == arrConsolidatedVehicles[j][k])
							{
								//this vehicle is now obsolete! let's do some stuff to it

								//remove vehicle
								tgtNodes[i].parentNode.removeChild(tgtNodes[i]);

								//make a note to add the new parent vehicle
								arrConsolidatedTargets.push(arrConsolidatedVehicles[j - 1]);

								bFound = true;
							}
						}
					}
				}

				//let's trim out our list to avoid duplicates
				for(var i = 0; i < arrConsolidatedTargets.length; i++)
				{
					for(var j = i + 1; j < arrConsolidatedTargets.length; j++)
					{
						if(arrConsolidatedTargets[i] == arrConsolidatedTargets[j])
						{
							arrConsolidatedTargets.splice(j, 1);
							j--;
						}
					}
				}

				//now let's look at our list of consolidated targets to add back in
				for(var i = 0; i < arrConsolidatedTargets.length; i++)
				{
					var bFound = false;

					var j = 0;
					for(j = 0; j < tgtNodes.length; j++)
					{
						var name = tgtNodes[j].getAttribute("shortname");
						if(!name)
							name = tgtNodes[j].getAttribute("name");

						if(name == arrConsolidatedTargets[i])
						{
							bFound = true;
							break;
						}
					}

					if(!bFound)
					{
						//add the consolidated name to the node list		     
						var node = this.m_xml.createElement("target");
						var addPoint = null;
						if(y == 0)
						{
							node.setAttribute("shortname", arrConsolidatedTargets[i]);
							addPoint = vehicleSets[x].selectSingleNode("targetlist");
						}
						else
						{
							node.setAttribute("name", arrConsolidatedTargets[i]);
							addPoint = cfSets[y - 1];
						}

						addPoint.appendChild(node);
					}
				}
			}
		} //for each vehicle set
	}

	this.updateConfigFile = function(objROCVVersion, objNewVersion)
	{
		// The biggest change is addition of icon images to sim panels and minor changes to the settings.
		if(objNewVersion["number"] < 2.0)
		{
			//NONE OF THESE ARE ACTUALLY USED ANY MORE
			//setAllowUserTimeControl(true);
			//setAllowCIPSinPEs(false);
			//setAllowMultipleVenuesinPEs(false);
			//setMaxMovingIDQuestions(0);
			//setMovingIDTime(getMovingIDTime());

			if(objROCVVersion["name"] == "1stGen")
			{
				this.setSimPanelIcon("Bradley", "images/m2a2.jpg");
				this.setSimPanelIcon("Generic", "images/generic.jpg");
				this.setSimPanelIcon("LAV-25", "images/lav25.jpg");
				this.setSimPanelIcon("M1A1", "images/m1a1.jpg");
				this.setSimPanelIcon("M1A2", "images/m1a2.jpg");
			}
			else
			{
				this.setSimPanelIcon("M2A3-IBAS", "images/ibas.jpg");
				this.setSimPanelIcon("M2A3-CIV", "images/civ.jpg");
				this.setSimPanelIcon("LRAS3", "images/lras3.jpg");
				this.setSimPanelIcon("CITV", "images/citv.jpg");
				this.setSimPanelIcon("M1A2 SEP-GPS", "images/m1a2sep.jpg");
				this.setSimPanelIcon("Javelin", "images/javelin.jpg");
			}
		}

		//once we are here, we should be up to at least version 2.0
		if(objNewVersion["number"] < 10.0)
		{
			var oldNode = this.m_xml.selectSingleNode("configuration/settings");
			if(oldNode != null)
			{
				//handle per vehicle set settings
				var vehicleSets = this.getTargetSets();
				for(var i = 0; i < vehicleSets.length; i++)
				{
					var node = this.getTargetSetConfigNode(vehicleSets[i].ID);

					node.setSetting("preferredorientation", oldNode.getAttribute("preferdownlook"));
					node.setSetting("passscore", oldNode.getAttribute("passscore"));
					node.setSetting("redmask", oldNode.getAttribute("redMask"));
					node.setSetting("greenmask", oldNode.getAttribute("greenMask"));
					node.setSetting("bluemask", oldNode.getAttribute("blueMask"));
					node.setSetting("timedsigtime", oldNode.getAttribute("timedsigtime"));

					//handle the weird post test setting
					var therm = node.getTest("posttest", "thermal");
					var vis = node.getTest("posttest", "visible");

                    if(therm && vis)
                    {
					    therm.setCompletionScore(oldNode.getAttribute("completionscore"));
					    vis.setCompletionScore(oldNode.getAttribute("completionscore"));
					}
				}

				//remove all this stuff
				oldNode.removeAttribute("preferdownlook");
				oldNode.removeAttribute("passscore");
				oldNode.removeAttribute("completionscore");
				oldNode.removeAttribute("redMask");
				oldNode.removeAttribute("greenMask");
				oldNode.removeAttribute("blueMask");
				oldNode.removeAttribute("timedsigtime");
				oldNode.removeAttribute("filterVideo");
				oldNode.removeAttribute("curricranges");
				oldNode.removeAttribute("maxmovingidquestions");
				oldNode.removeAttribute("movingidtime");
				oldNode.removeAttribute("numoccl");
				oldNode.removeAttribute("allowusertimecontrol");
				oldNode.removeAttribute("initnumconf");
				oldNode.removeAttribute("allowcipsinpes");

			} //oldNode != null

			this._handleVehicleChanges();
		} //2.0 -> 10.0

		//whatever we started with, we should end at version 10
		this.setConfigVersionProperty("name", "Version-10");
		this.setConfigVersionProperty("number", 10.0);
	} //update config file

	this._handleVehicleChanges = function()
	{
		var tgtNodes = this.m_xml.selectNodes("//target");
		for(var i = 0; i < tgtNodes.length; i++)
		{
			//get the name
			var name = tgtNodes[i].getAttribute("shortname");
			if(!name)
				name = tgtNodes[i].getAttribute("name");

			var newName = name;

			//strip the _A or _G
			var last2 = name.slice(name.length - 2);
			if(last2 == "_A" || last2 == "_G")
				newName = name.slice(0, name.length - 2);

			//remove vehicles which don't exist anymore
			if(name.indexOf("OSV-") == 0)
			{
				tgtNodes[i].parentNode.removeChild(tgtNodes[i]);
				continue;
			}

			//see if it is one of our special changed names
			if(newName == "M60A")
				newName = "M60A3";
			else if(newName == "Toy-G" || newName == "Toy-M")
				newName = "Toy";
			else if(newName == "UR37")
				newName = "UR40";
			else if(newName == "WOLV")
				newName = "WOLVX";
			else if(newName == "ZIL1")
				newName = "ZIL1x";

			//finally, apply the new name if necessary   
			if(newName != name)
			{
				if(tgtNodes[i].getAttribute("shortname"))
					tgtNodes[i].setAttribute("shortname", newName);
				else if(tgtNodes[i].getAttribute("name"))
					tgtNodes[i].setAttribute("name", newName);
			}
		}
	}


	this.setActiveSimPanels = function(arrNames)
	{
		var nodePanels = this.m_xml.selectNodes("configuration/simpanels/simpanel");
		if(nodePanels != null)
		{
			for(var i = 0; i < nodePanels.length; i++)
			{
				nodePanels[i].setAttribute("active", "false");
				for(var j = 0; j < arrNames.length; j++)
				{
					if(nodePanels[i].getAttribute("name") == arrNames[j])
						nodePanels[i].setAttribute("active", "true");
				}
			}
		}
	}

	this.getActiveSimPanels = function()
	{
		var nodePanels = this.m_xml.selectNodes("configuration/simpanels/simpanel[not(@active) or @active != 'false']");
		if(nodePanels != null)
		{
			var arrSimPanels = new Array();
			for(var i = 0; i < nodePanels.length; i++)
			{
				arrSimPanels.push(new EOIR.SimPanel(nodePanels[i].getAttribute("name"), nodePanels[i].getAttribute("searchcmd"), nodePanels[i].getAttribute("searchcfg"), nodePanels[i].getAttribute("bccmd"), nodePanels[i].getAttribute("bccfg"), nodePanels[i].getAttribute("icon")));
			}

			return arrSimPanels.sort(EOIR.SimPanel._PanelSorter);
		}
	}

	this.getAllSimPanels = function()
	{
		var nodePanels = this.m_xml.selectNodes("configuration/simpanels/simpanel");
		if(nodePanels != null)
		{
			var arrSimPanels = new Array();
			for(var i = 0; i < nodePanels.length; i++)
			{
				arrSimPanels.push(new EOIR.SimPanel(nodePanels[i].getAttribute("name"), nodePanels[i].getAttribute("searchcmd"), nodePanels[i].getAttribute("bccmd")));
			}

			return arrSimPanels.sort(EOIR.SimPanel._PanelSorter);
		}
	}

	this.getVersion = function()
	{
		var obj = new Object();
		obj["name"] = "Unknown";
		obj["number"] = "1.0";

		var nodeVersion = this.m_xml.selectNodes("configuration/version");
		if(nodeVersion != null)
		{
			if(nodeVersion.length > 0)
			{
				obj["name"] = nodeVersion[0].getAttribute("name");
				obj["number"] = nodeVersion[0].getAttribute("number");
			}
		}
		return obj;
	}

	this.getTargetSetSetting = function(strSetId, settingName, defaultVal)
	{
		defaultVal = this.getSettingDefault(settingName, defaultVal);

		if(strSetId == null)
		{
			strSetId = EOIR.Config.getCurrentTargetSetId();
		}

		return this.getTargetSetConfigNode(strSetId).getSetting(settingName, defaultVal);
	}

	this.setTargetSetSetting = function(strSetId, settingName, settingValue)
	{
		if(strSetId == null)
		{
			strSetId = EOIR.Config.getCurrentTargetSetId();
		}

		return this.getTargetSetConfigNode(strSetId).setSetting(settingName, settingValue);
	}

	this.getCompletionPassScore = function(strSetId)
	{
		return parseInt(this.getTargetSetSetting(strSetId, "completionscore", 80));
	}

	this.setCompletionScore = function(strSetId, nNewScore)
	{
		this.setTargetSetSetting(strSetId, "completionscore", nNewScore);
	}

	this.getPassScore = function(strSetId)
	{
		return parseInt(this.getTargetSetSetting(strSetId, "passscore", 80));
	}

	this.setPassScore = function(strSetId, nNewScore)
	{
		this.setTargetSetSetting(strSetId, "passscore", nNewScore);
	}

	this.getDifficulty = function(strSetId)
	{
		return parseInt(this.getTargetSetSetting(strSetId, "difficulty", "easy"));
	}

	this.getTimedSigTime = function(strSetId)
	{
		return parseInt(this.getTargetSetSetting(strSetId, "timedsigtime", 15));
	}

	this.getPreferredOrientation = function(strSetId)
	{
		return parseInt(this.getTargetSetSetting(strSetId, "preferredorientation", -1));
	}

	// May return the current Config object or the one from the main EOIR window.
	return this._load(strConfigCode, fnLoaded, strConfigFile);
}

EOIR.Config.get = function(fnLoaded, strConfigCode, strConfigFile)
{
	return new EOIR.Config(fnLoaded, strConfigCode, strConfigFile);
}

EOIR.Config.getCurrent = function(fnLoaded)
{
	return EOIR.Config.get(fnLoaded, EOIR.Utils.getProperty("cfgcode"));
}

EOIR.Config._executeConfigFunction = function(strPostData, fnLoaded, params)
{
	try
	{
		var req = new XMLHttpRequest();
		req.open("POST", EOIR.Utils.getAbsolutePath("/server_side/config.php"), false);
		req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		req.send(strPostData);

		if(req.status == 200)
		{
			return req.responseXML;
		}
	}
	catch(e)
	{
		// This is just in case the XMLHttpRequest object doesn't work.
		return EOIR.XML.load(EOIR.Utils.getAbsolutePath("/server_side/config.php?" + strPostData), false);
	}
};

EOIR.Config.getConfigFilenameFromCode = function(strCode)
{
/*	if(strCode == null)
	{
		strCode = EOIR.Utils.getProperty("cfgcode");
	}

*/	if(strCode == null || strCode == "" || strCode.toLowerCase() == "default")
	{
		return "config.xml";
	}
	else
	{
		return "config-" + strCode.toLowerCase() + ".xml";
	}
}

EOIR.Config.getConfigFile = function(strCode)
{
	try
	{
		if(!EOIR.Utils.isInROCBrowser())
		{
			return EOIR.Utils.getAbsolutePath("/config/" + EOIR.Config.getConfigFilenameFromCode(strCode));
		}
		else
		{
			var strConfigFile = EOIR.Utils.getPropertySetEvalDefault("ConfigFile", "EOIR.External.get().ConfigurationFilename");
			if(strConfigFile != null)
			{
				return strConfigFile;
			}
		}
	}
	catch(e)
	{
		alert("getConfigFile error: " + e.description);
	}

	return EOIR.Utils.getAbsolutePath("/config/config.xml");
}

EOIR.Config.getConfigurationParameter = function (strParamName, defaultValue)
{
    // First, try to read the program configuration (the .rocx file).
    // Note, for this to work, external.js needs to be included.
    try
    {
        return EOIR.External.getProgramParameter(strParamName, defaultValue);
    }
    catch (e)
    {
    }

    // Then read the default values.
    try
    {
    	var strXML = EOIR.Utils.getProperty("InfoStr", null);
    	var xml;
		if(strXML != null)
		{
			xml = EOIR.XML.loadFromString(strXML);
		}
    	else
		{
			xml = EOIR.XML.load(EOIR.Utils.getAbsolutePath('/config/info.xml'), false);
			EOIR.Utils.setProperty("InfoStr", EOIR.XML.serialize(xml));
		}

		if(xml != null)
        {
			var node = xml.selectSingleNode("/configuration/settings/param[@name='" + strParamName + "']");
            if (node != null)
            {
                return node.getAttribute("value");
            }
        }
    }
    catch (e)
    {
        try
        {
            var xmlConfig = EOIR.XML.load(EOIR.Utils.getAbsolutePath('/config/info.xml'));

            var node = xmlConfig.selectSingleNode("/configuration/settings/param[@name='" + strParamName + "']");
            if (node != null)
            {
                return node.getAttribute("value");
            }
        }
        catch (e2)
        {
            alert("EOIR.Config.getConfigurationParameter error (" + strParamName + "): " + e2.description);
        }
    }

    return defaultValue;
}

EOIR.Config.getConfusionSets = function(cfg)
{
	if(cfg == null)
	{
		cfg = EOIR.Config.get();
	}

	cfg.getConfusionSetsFromTargetSet(this.getCurrentTargetSet());
}

EOIR.Config.setCurrentTargetSet = function(strTgtSet)
{
	return EOIR.Utils.setProperty("selectedTargetSet", strTgtSet);
}

EOIR.Config.getCurrentTargetSetId = function()
{
	return EOIR.Utils.getPropertyDefault("selectedTargetSet", "all");
}


EOIR.Config.getSimulationLocation = function()
{
	try
	{
		var strSimLoc = EOIR.Utils.getPropertySetEvalDefault("SimLocation", "EOIR.External.get().SimulationLocation");
		if(strSimLoc != null)
		{
			return strSimLoc;
		}
	}
	catch(e)
	{
	}

	return "C:\\Development\\Projects\\EOIR\\v10\\sims";
}

EOIR.Config.getSearchFilesLocation = function()
{
    try
    {
	    var strSearchFilesLoc = EOIR.Utils.getPropertySetEvalDefault("SearchFilesLoc", "EOIR.External.get().SearchFilesLocation");
	    if(strSearchFilesLoc != null)
	    {
		    return strSearchFilesLoc;
	    }
    }
    catch(e)
    {
    }

    return "C:\\Development\\Projects\\EOIR\\v10\\sims\\imagery";
}

EOIR.Config.getBCFilesLocation = function()
{
	try
	{
		var strBCFilesLoc = EOIR.Utils.getPropertySetEvalDefault("BCFilesLoc", "EOIR.External.get().BCFilesLocation");
		if(strBCFilesLoc != null)
		{
			return strBCFilesLoc;
		}
	}
	catch(e)
	{
	}

	return "C:\\Development\\Projects\\EOIR\\v10\\sims\\imagery";
}

EOIR.TargetSet = function(strID, strDescription)
{
	this.ID = strID;
	this.Description = strDescription;

	this.Other =
	{
		difficulty: "easy",
		passscore: 85,
		timedsigtime: 15,
		vsquizquest: 10,
		vstestquest: 15,
		preferredorientation: "none",
		redmask: 255,
		greenmask: 255,
		bluemask: 255
	};

	this.Tests = []; //0=pre-therm; 1=post-therm; 2=pre-vis; 3=post-vis;
	for(var i = 0; i < 4; i++)
	{
		this.Tests[i] =
		{
			enabled: true,
			generaterandom: true,
			numberquestions: 50,
			showtime: 10,
			additionaltime: 0,
			completionscore: 85
		};
	}

	this.getTargetList = function(cfg)
	{
		if(cfg == null) cfg = EOIR.Config.getCurrent();
		return cfg.getTargetSetTargetList(this.ID);
	};

	this.autogenerateConfusionSets = function(arr)
	{
		var htType = [];
		var tgtInfo = EOIR.DB.getTgtInfo();
		for(var i = 0; i < arr.length; i++)
		{
			var info = EOIR.DB._getBasicTargetInfo(tgtInfo, arr[i]);
			var arrType = htType[info.type];
			if(arrType == null)
			{
				arrType = htType[info.type] = [];
			}

			arrType.push(info);
		}

		var arrSets = [];
		for(var key in htType)
		{
			var arrType = htType[key];
			arrType.sort(function(a, b)
			{
				if(a.origin == b.origin)
				{
					return EOIR.Utils.strCmpLogical(a.name, b.name);
				}
				else
				{
					if(a.origin == "US")
					{
						return -1;
					}
					else if(b.origin == "US")
					{
						return 1;
					}
					else
					{
						if(a.origin < b.origin)
						{
							return -1;
						}
						else if(a.origin > b.origin)
						{
							return 1;
						}
						return 0;
					}
				}
			});

			var arrTypeShortNames = [];
			for(var i = 0; i < arrType.length; i++)
			{
				arrTypeShortNames.push(arrType[i].shortname);
			}
			arrTypeShortNames.name = key + " (Auto)";
			arrSets.push(arrTypeShortNames);
		}

		var arrDesired = ["Tracked", "Wheeled Armored", "Rotary Wing", "Wheeled Unarmored", "Non-Military"];
		arrSets.sort(function(a, b)
		{
			if(a.name == b.name)
			{
				return 0;
			}
			else
			{
				var aLower = a.name.toLowerCase();
				var bLower = b.name.toLowerCase();

				var aIndex, bIndex;
				for(var i = 0; i < arrDesired.length && (aIndex == null || bIndex == null); i++)
				{
					var desired = arrDesired[i].toLowerCase();
					if(aIndex == null)
					{
						if(desired == aLower.substr(0, desired.length))
						{
							aIndex = i;
						}
					}
					if(bIndex == null)
					{
						if(desired == bLower.substr(0, desired.length))
						{
							bIndex = i;
						}
					}
				}

				if(aIndex != null && bIndex != null)
				{
					if(aIndex < bIndex)
					{
						return -1;
					}
					else if(aIndex > bIndex)
					{
						return 1;
					}
					else
					{
						return 0;
					}
				}
				else if(aIndex != null)
				{
					return -1;
				}
				else if(bIndex != null)
				{
					return 1;
				}
				else
				{
					if(aLower < bLower)
					{
						return -1;
					}
					else if(aLower > bLower)
					{
						return 1;
					}
					else
					{
						return 0;
					}
				}
			}
		});

		var arrSetNames = [];
		for(var i = 0; i < arrSets.length; i++)
		{
			arrSetNames.push(arrSets[i].name);
		}

		this.ConfusionSets = arrSets;
	}

	this.serialize = function(xml)
	{
		var fileset = xml.createElement("fileset");
		fileset.setAttribute("id", this.ID);
		fileset.setAttribute("description", this.Description);

		//build our target list on the way
		var targetlist = xml.createElement("targetlist");

		var htTgts = [];
		if(this.ConfusionSets && this.ConfusionSets.length > 0)
		{
			var confsets = xml.createElement("confusionsets");
			for(var j = 0; j < this.ConfusionSets.length; j++)
			{
				var confset = xml.createElement("confusionset");
				if(this.ConfusionSets[j].name != null)
				{
					confset.setAttribute("name", this.ConfusionSets[j].name);
				}
				for(var k = 0; k < this.ConfusionSets[j].length; k++)
				{
					//handle confusion set entry
					var target = xml.createElement("target");
					target.setAttribute("name", this.ConfusionSets[j][k]);
					confset.appendChild(target);

					htTgts[this.ConfusionSets[j][k]] = 1;
				}

				confsets.appendChild(confset);
			}
			fileset.appendChild(targetlist);
			fileset.appendChild(confsets);

		} //if there are confusion sets

		for(var tgt in htTgts)
		{
			var target = xml.createElement("target");
			target.setAttribute("shortname", tgt);
			targetlist.appendChild(target);
		}

		//now, handle the tests
		var tests = xml.createElement("tests");

		var arrTest = [];
		for(var testCount = 0; testCount < 4; testCount++)
		{
			switch(testCount)
			{
				case 0:
					arrTest[testCount] = xml.createElement("pretest");
					arrTest[testCount].setAttribute("type", "thermal");
					break;
				case 1:
					arrTest[testCount] = xml.createElement("posttest");
					arrTest[testCount].setAttribute("type", "thermal");
					arrTest[testCount].setAttribute("completionscore", this.Tests[testCount].completionscore); //only in posttest
					break;
				case 2:
					arrTest[testCount] = xml.createElement("pretest");
					arrTest[testCount].setAttribute("type", "visible");
					break;
				case 3:
					arrTest[testCount] = xml.createElement("posttest");
					arrTest[testCount].setAttribute("type", "visible");
					arrTest[testCount].setAttribute("completionscore", this.Tests[testCount].completionscore); //only in posttest
					break;
			}
			arrTest[testCount].setAttribute("enabled", this.Tests[testCount].hasOwnProperty("enabled") ? this.Tests[testCount].enabled : true);
			arrTest[testCount].setAttribute("generaterandom", this.Tests[testCount].generaterandom);
			arrTest[testCount].setAttribute("numberquestions", this.Tests[testCount].numberquestions);
			arrTest[testCount].setAttribute("showtime", this.Tests[testCount].showtime);
			arrTest[testCount].setAttribute("additionaltime", this.Tests[testCount].additionaltime);
			if(this.Tests[testCount].generaterandom == "0")
			{
				arrTest[testCount].setAttribute("randomizeorder", this.Tests[testCount].randomizeorder);
				if(this.Tests[testCount].Targets)
				{
					for(var j = 0; j < this.Tests[testCount].Targets.length; j++)
					{
						var tgtvar = xml.createElement("target");
						tgtvar.setAttribute("shortname", this.Tests[testCount].Targets[j].tgt);
						tgtvar.setAttribute("venue", this.Tests[testCount].Targets[j].venue);
						tgtvar.setAttribute("variant", this.Tests[testCount].Targets[j].variant);
						//tgtvar.setAttribute("polarity", this.Tests[testCount].Targets[j].pol);
						tgtvar.setAttribute("range", this.Tests[testCount].Targets[j].range);
						tgtvar.setAttribute("tod", this.Tests[testCount].Targets[j].tod);

						if(this.Tests[testCount].Targets[j].band == "8-12")
							tgtvar.setAttribute("type", "lwir");
						else if(this.Tests[testCount].Targets[j].band == "3-5")
							tgtvar.setAttribute("type", "mwir");
						else
							tgtvar.setAttribute("type", "vis");

						var arrAspect = this.Tests[testCount].Targets[j].aspect.split("-");
						tgtvar.setAttribute("aspect", arrAspect[0]);
						tgtvar.setAttribute("dlangle", (arrAspect[1] == "DL") ? "60" : "0");

						arrTest[testCount].appendChild(tgtvar);
					}

				}
			}
			tests.appendChild(arrTest[testCount]);
		}

		fileset.appendChild(tests);

		//do other settings
		if(this.Other)
		{
			var settings = xml.createElement("settings");
			for(var key in this.Other)
			{
				var setting = xml.createElement("setting");
				setting.setAttribute("name", key);
				setting.setAttribute("value", this.Other[key]);
				settings.appendChild(setting);
			}

			fileset.appendChild(settings);
		}

		fileset.setAttribute("modtime", new Date().getTime());

		return fileset;
	}

	this.toString = function()
	{
		return this.Description;
	};
}

EOIR.TargetSetConfigNode = function(node)
{
	this._node = node;

	this.getSetting = function(strSetting, defaultVal)
	{
		if(this._node == null)
		{
			return defaultVal;
		}

		var nodeSetting = this._node.selectSingleNode("settings/setting[@name='" + strSetting + "']");
		if(nodeSetting == null)
		{
			return defaultVal;
		}

		var val = nodeSetting.getAttribute("value");
		return (val == null) ? defaultVal : val;
	}

	this.setSetting = function(strSetting, val)
	{
		if(this._node == null)
		{
			// Not sure what to do here... The target set itself must not exist.
			return;
		}

		var nodeSetting = this._node.selectSingleNode("settings/setting[@name='" + strSetting + "']");
		if(nodeSetting == null)
		{
			var nodeSettings = this._node.selectSingleNode("settings");
			if(nodeSettings == null)
			{
				nodeSettings = this._node.ownerDocument.createElement("settings");
				this._node.appendChild(nodeSettings);
			}

			nodeSetting = this._node.ownerDocument.createElement("setting");
			nodeSetting.setAttribute("name", strSetting);
			nodeSetting.setAttribute("value", val);

			nodeSettings.appendChild(nodeSetting);
		}
		else
		{
			node.setAttribute("value", val);
		}
	}

	this.getTargetList = function()
	{
		if(this._node == null)
		{
			return null;
		}

		var objNodeList = this._node.selectNodes("targetlist/target");

		var htTgts = [];
		for(var i = 0; i < objNodeList.length; i++)
		{
			var strShortName = objNodeList[i].getAttribute("shortname");
			if(strShortName == "*")
			{
				return EOIR.DB.getTargetShortNames();
			}
			else
			{
				htTgts[strShortName] = 1;
			}
		}

		var arrTgt = [];
		for(var key in htTgts)
		{
			arrTgt.push(key);
		}

		return EOIR.DB.validateTargets(arrTgt);
	}

	this.getTest = function(strTestType, strTargetType)
	{
		var nodeTest;
		if(this._node != null)
		{
			nodeTest = this._node.selectSingleNode("tests/" + strTestType + "[@type='" + strTargetType + "']")
		}
		return nodeTest != null ? new EOIR.TargetSetTest(nodeTest) : null;
	}

	this.getNode = function()
	{
		return this._node;
	}
}

EOIR.TargetSetTest = function(node)
{
	this._node = node;

	this.isEnabled = function()
	{
		var enabledAttr = this._node.getAttribute("enabled");
		if(enabledAttr == null)
		{
			enabledAttr = true;
		}
		var bEnabled = EOIR.Utils.parseBool(enabledAttr);
		if(bEnabled)
		{
			bEnabled = this.getNumQuestions() > 0;
		}
		return bEnabled;
	}

	this.isRandom = function()
	{
		return parseInt(this._node.getAttribute("generaterandom")) != 0;
	}

	this.getNumQuestions = function()
	{
		// This is only the number of "random" questions.
		if(this.isRandom())
		{
			var nNumQuestionsRand = parseInt(this._node.getAttribute("numberquestions"));
			return isNaN(nNumQuestionsRand) ? 0 : nNumQuestionsRand;
		}
		else
		{
			try
			{
				return this.selectNodes("target").length;
			}
			catch(e)
			{
				return 0;
			}
		}
	}

	this.selectNodes = function(strSelect)
	{
		return this._node.selectNodes(strSelect);
	}

	this.getShowTime = function()
	{
		return parseInt(this._node.getAttribute("showtime"));
	}

	this.getAdditionalTime = function()
	{
		return parseInt(this._node.getAttribute("additionaltime"));
	}

	this.getCompletionScore = function()
	{
		var score = parseFloat(this._node.getAttribute("completionscore"));
		return isNaN(score) ? 85 : score;
	}

	this.getRandomizeOrder = function()
	{
		return EOIR.Utils.parseBool(this._node.getAttribute("randomizeorder"));
	}

	this.setCompletionScore = function(strScore)
	{
		this._node.setAttribute("completionscore", strScore);
	}
}

EOIR.SimPanel = function(strName, strSearch, strSearchConfig, strBC, strBCConfig, strIcon)
{
	this.Name = strName;
	this.SearchCmd = strSearch;
	this.SearchConfig = strSearchConfig;
	this.BCCmd = strBC;
	this.BCConfig = strBCConfig;
	this.Icon = strIcon;
}

EOIR.SimPanel._PanelSorter = function(a, b)
{
	return EOIR.Utils.strCmpLogical(a.Name, b.Name);
}
