// XML DOM object definition
function XmlDom() {
	if (window.ActiveXObject) {
		var arrSignatures = ["MSXML2.DOMDocument.7.0", "MSXML2.DOMDocument.6.0",
						"MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0",
						"MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument",
						"Microsoft.XmlDom"];
		for (var i=0; i < arrSignatures.length; i++) {
			try {
				var oXmlDom = new ActiveXObject(arrSignatures[i]);
				msXmlVersion = arrSignatures[i];

				oXmlDom.async = false;
				try {
					oXmlDom.setProperty("AllowXsltScript", true);
					oXmlDom.setProperty("AllowDocumentFunction", true);
					oXmlDom.resolveExternals = true;
				} catch(err) {}

				return oXmlDom;
			} catch (oError) {
				//ignore
				
			}
		}
		// "MSXML is not installed on your system."
		throw new Error();
		

	} else {
		// "Your browser does not support an XML DOM object."
		//throw new Error();
		//for firefox, opera, etc...
		
		 oXmlDom= document.implementation.createDocument("","",null)
		 oXmlDom.async = false;
				try {
					oXmlDom.setProperty("AllowXsltScript", true);
					oXmlDom.setProperty("AllowDocumentFunction", true);
					oXmlDom.resolveExternals = true;
				} catch(err) {}

				return oXmlDom;
				alert("doesn't support");

	}
}

if (!document.importNode) {
	// add the importNode functionality to IE so that XML DOM elements can be appended to HTML DOM elements
	document.importNode = function(oNode, bImportChildren) {
		var oNew;

		// if the node is an element node
		if (oNode.nodeType == 1) {

			// Radio Buttons ONLY - don't work in IE (breaks FF).
			if (oNode.nodeName.toLowerCase() == "input" && oNode.getAttribute("type").toLowerCase() == "radio") {

				// Construct a string
				var radioButtonString = "<input ";
				for (var i = 0; i < oNode.attributes.length; i++) {
					radioButtonString += oNode.attributes[i].name.toLowerCase() + "=\"" + oNode.attributes[i].value + "\" ";
				}
				radioButtonString += "/>";

//				var radioButtonString = oNode.xml;

				// Specialized create element for radio buttons only.
				oNew = document.createElement(radioButtonString);

			} else {

				// create a new element based in the current document with the same name
				oNew = document.createElement(oNode.nodeName);
				// run through the attributes and clone them within this element
				for (var i = 0; i < oNode.attributes.length; i++) {
	//				if (oNode.attributes[i].value != null && oNode.attributes[i].value != '') {
						// If the attribute is an event handler, recreate the function tied to the event handler.
						if (oNode.attributes[i].name.toLowerCase().slice(0,2) == "on") {
							oNew[oNode.attributes[i].name.toLowerCase()] = new Function(oNode.attributes[i].value);
						// this fixes the ie bug of overlapping a javascript reserved word
						} else if (oNode.attributes[i].name == "class") {
							oNew.setAttribute("className", oNode.attributes[i].value);
						} else {
							oNew.setAttribute(oNode.attributes[i].name, oNode.attributes[i].value);
						}
	//				}
				}
				//oNew.style.cssText = oNode.style.cssText; - look into this - buggie

			}

		if (typeof oNew.attributes["frameborder"] != "undefined") {
			alert(oNew.getAttribute("frameborder"));
		}

		// if the node is a text node, create it and copy its value all in one operation
		} else if (oNode.nodeType == 3) {
			oNew = document.createTextNode(oNode.nodeValue);
		} else if (oNode.nodeType == 8) {
		// if the node is a comment node, create it and copy its value all in one operation
			oNew = document.createComment(oNode.nodeValue);
		}

		// if this function has been called with deep (importChildren) set to true, recursively call on children nodes
		if (bImportChildren && oNode.hasChildNodes()) {
			// recursively call this function for all children and append these children to the document tree
			for (var oChild = oNode.firstChild; oChild != null; oChild = oChild.nextSibling) {
				oNew.appendChild(document.importNode(oChild, true));
			}
		}
		return oNew;
	}
}

// peel through an HTML DOM and force flash objects to load if they aren't loaded yet
function refreshFlash(oNode) {
	// load all flash objects if they aren't loaded
	for (var x = 0; x < oNode.getElementsByTagName('object').length; x++) {
		// if the object is a flash object (if it has the LoadMovie function)
		if (typeof oNode.getElementsByTagName('object')[x].LoadMovie != "undefined") {
			// if the flash object is not loaded (on frame -1)
			if (oNode.getElementsByTagName('object')[x].frameNum == -1) {
				oNode.getElementsByTagName('object')[x].LoadMovie(0, oNode.getElementsByTagName('object')[x].getAttribute('data'));
			}
		}
	}
}

// peel through an HTML DOM and force flash objects to load if they aren't loaded yet
function reloadAllFlashNodes(oNode, bRefreshContentWheel) {

	if (typeof(bRefreshContentWheel) == "undefined") {
		bRefreshContentWheel = false;
	}

	// peel through all the object nodes in oNode
	for (var x = 0; x < oNode.getElementsByTagName('object').length; x++) {
		// if the object is a flash object
		if (oNode.getElementsByTagName('object')[x].getAttribute("type") == "application/x-shockwave-flash") {

			if (oNode.getElementsByTagName('object')[x].getAttribute("id") == "contentWheel" && bRefreshContentWheel == false) {
				return false;
			} else {
				// return the string of the currently selected object node
				var xmlString = xmlStringFromDocDom(oNode.getElementsByTagName('object')[x]);

				// do an innerHTML replacement of the contents of the Flash object's parent div
				oNode.getElementsByTagName('object')[x].parentNode.innerHTML = xmlString;
			}
		}
	}
	// If this method is directed to update the content wheel, then do so.
	if (bRefreshContentWheel == true) {
		updateContentWheel(bRefreshContentWheel);
	}
}

// peel through an HTML DOM and reload all elements with ECMAScript events using innerHTML.
function reloadAllEventNodes(oNode, bRefreshContentWheel) {
	// peel through all the object nodes in oNode
	for (var x = 0; x < oNode.getElementsByTagName('object').length; x++) {
		// if the object is a flash object
		if (oNode.getElementsByTagName('object')[x].getAttribute("type") == "application/x-shockwave-flash") {

			if (oNode.getElementsByTagName('object')[x].getAttribute("id") == "contentWheel" && bRefreshContentWheel == false) {
				return false;
			} else {
				// return the string of the currently selected object node
				var xmlString = xmlStringFromDocDom(oNode.getElementsByTagName('object')[x]);

				// do an innerHTML replacement of the contents of the Flash object's parent div
				oNode.getElementsByTagName('object')[x].parentNode.innerHTML = xmlString;
			}
		}
	}
}

// return the URI of the first xml-stylesheet processing instruction found in the XML DOM
function getXslt(xmlDom) {
	// extract the path to the first xml-stylesheet found within the xml doc
	for (var x = 0; x < xmlDom.childNodes.length; x++) {
		if (xmlDom.childNodes.item(x).nodeName == "xml-stylesheet") {
			// return the entire value string of the xml-stylesheet processing instruction
			var styleSheetValue = xmlDom.childNodes.item(x).nodeValue;
			// a regex pattern that matches the href attribute and value
			var reHref = /(?:href=".*")/i;
			var pMatch = styleSheetValue.match(reHref);
			// strip off the regex pattern and return the bare URI
			return pMatch[0].slice(6, -1);
		}
	}
	// no xml-stylesheet processing instruction was found
	return false;
}

// remove empty whitespace nodes from DOM (newlines and tabs within original document)
var notWhitespace = new RegExp(/\S/)
function cleanWhitespace(node) {
	// if node is undefined, make the default argument the current document's documentElement
	for (var x = 0; x < node.childNodes.length; x++) {
		var childNode = node.childNodes[x];
		if ((childNode.nodeType == 3) && (!notWhitespace.test(childNode.nodeValue))) {
			// that is, if it's a whitespace text node
			node.removeChild(node.childNodes[x]);
			x--;
		}
		if (childNode.nodeType == 1) {
			// elements can have text child nodes of their own
			cleanWhitespace(childNode);
		}
	}
}

// return an xml string that corresponds to the entered document fragment XML DOM
function xmlStringFromDocDom(oDocDom, encodeSingleSpaceTextNodes) {
	var xmlString = new String();

	// if the node is an element node
	if (oDocDom.nodeType == 1 && oDocDom.nodeName.slice(0,1) != "/") {
		// define the beginning of the root element and that element's name
		xmlString = "<" + oDocDom.nodeName.toLowerCase();

		// loop through all qualified attributes and enter them into the root element
		for (var x = 0; x < oDocDom.attributes.length; x++) {
			if (oDocDom.attributes[x].specified == true || oDocDom.attributes[x].name == "value") {	// IE wrongly puts unspecified attributes in here
				//if (oDocDom.attributes[x].name == "class") {
				//	xmlString += ' class="' + oNode.attributes[x].value + '"';
				//} else {

				// If this is not an input, then add the attribute is "input", then skip this.
				if (oDocDom.nodeName.toLowerCase() != "input" && oDocDom.attributes[x].name == "value" && oDocDom.attributes[x].specified == false) {

				// If this is an img element.
				} else if (oDocDom.nodeName.toLowerCase() == "img" && oDocDom.attributes[x].name == "width" ||
					oDocDom.nodeName.toLowerCase() == "img" && oDocDom.attributes[x].name == "height") {

				} else {

					xmlString += ' ' + oDocDom.attributes[x].name + '="' + oDocDom.attributes[x].value + '"';
				}
				//}
			}
		}

		// if the xml object doesn't have children, then represent it as a closed tag
//		if (oDocDom.childNodes.length == 0) {
//			xmlString += "/>"

//		} else {

		// if it does have children, then close the root tag
		xmlString += ">";
		// then peel through the children and apply recursively
		for (var i = 0; i < oDocDom.childNodes.length; i++) {
			xmlString += xmlStringFromDocDom(oDocDom.childNodes.item(i), encodeSingleSpaceTextNodes);
		}
		// add the final closing tag
		xmlString += "</" + oDocDom.nodeName.toLowerCase() + ">";
//		}

		return xmlString;

	} else if (oDocDom.nodeType == 3) {
		// return the text node value
		if (oDocDom.nodeValue == " " && encodeSingleSpaceTextNodes == true) {
			return "#160;";
		} else {
			return oDocDom.nodeValue;
		}
	} else {
		return "";
	}
}

// String representation of XML DOM.
function xmlString(xmlDom) {
	// During .xml IE turns single space whitespace nodes into \r\n\t{1,200}.
	var xmlDomString = xmlDom.xml;
	xmlDomString = xmlDomString.replace(/\r\n\t{1,200}/g, " ");
	xmlDomString = xmlDomString.replace(/#160;/g, " ");
	return xmlDomString;
}

// String representation of XML DOM.
function encodeSingleWhitespaceNodes(xmlDom) {
	// During .xml IE turns single space whitespace nodes into \r\n\t{1,200}.
	var xmlDomString = xmlDom.xml;
	xmlDomString = xmlDomString.replace(/\r\n\t{1,200}/g, "#160;");
	var encodedXml = new XmlDom();
	encodedXml.loadXML(xmlDomString);
	// Make sure not to lose xmlDom.url (which is used to determine absolute path for the document function in msxml3 xslt).
	xmlDom.replaceChild(encodedXml.documentElement, xmlDom.documentElement);
}