﻿// Browser
function Browser() {
}
Browser.Agent=navigator.userAgent.toLowerCase();
Browser.Version=Browser.Agent.match(/msie ([^;]+);/);

Browser.IE=Browser.Agent.indexOf("msie")!=-1;
Browser.Moz=Browser.Agent.indexOf("gecko")!=-1;
Browser.Other=Browser.Agent.search(/(msie|mozilla)/i)==-1;
Browser.Version=Browser.Version && Browser.Version.length ? +Browser.Version[1] : null,

Browser.XML=function () {
}
Browser.XML.Prefix=function () {
	// in case this function ran, we have the prefix under Browser.XML.Prefix.Prefix.
	if (Browser.XML.Prefix.Prefix) return Browser.XML.Prefix.Prefix;

	var prefixes=["MSXML2","Microsoft","MSXML","MSXML3"],
		xd,xh;

	for (var i=0;i<prefixes.length;i++) {
		try {
			xd=new ActiveXObject(prefixes[i]+".XMLDOM");
			xh=new ActiveXObject(prefixes[i]+".XMLHTTP");
			Browser.XML.Prefix.Prefix=prefixes[i];
		}
		catch (oErr) {}
		finally {
			xd=xh=null;
		}
		if (Browser.XML.Prefix.Prefix) return Browser.XML.Prefix.Prefix=prefixes[i];
	}

	return null;
}
Browser.XML.Create=function (suffix) {
	return new ActiveXObject(this.Prefix()+"."+suffix);
}
Browser.XML.DOM=function () {
	if (window.ActiveXObject) return this.Create("XMLDOM");
	else if (document.implementation && document.implementation.createDocument) {
		var xd=document.implementation.createDocument("","",null);

		if (xd.readyState==null) {
			xd.readyState=1;
			xd.addEventListener("load",mozXMLOnLoad,false);
		}

		return xd;
	}
}
Browser.XML.HTTP=function () {
	if (window.ActiveXObject) return this.Create("XMLHTTP");
	else if (window.XMLHttpRequest) {
		var xh=new XMLHttpRequest();

		if (xh.readyState==null) {
			xh.readyState=1;
			xh.addEventListener("load",mozXMLOnLoad,false);
		}

		return xh;
	}
}

/* Moz Implementation by webfx.eae.net */

if (Browser.Moz) {
	Window.prototype.attachEvent=Document.prototype.attachEvent=HTMLElement.prototype.attachEvent=function (sType,fHandler) {
		this.addEventListener(
			sType.replace(/on/,""),
			function (oEvent) {
				window.event=oEvent;
				return fHandler(oEvent);
			},
			false
		);
	}

	Event.prototype.__defineGetter__(
		"srcElement",
		function () {
			return this.target.nodeType==Node.ELEMENT_NODE ? this.target : this.target.parentNode;
		}
	);

	Event.prototype.__defineGetter__(
		"fromElement",
		function () {
			return this.type=="mouseover" ? this.relatedTarget : this.type=="mouseout" ? this.srcElement : null;
		}
	);

	Event.prototype.__defineGetter__(
		"toElement",
		function () {
			return this.type=="mouseout" ? this.relatedTarget : this.type=="mouseover" ? this.srcElement : null;
		}
	);

	// dom

	Document.prototype.createStyleSheet=function (sURL) {
		var oXH=Browser.xmlhttp();
		oXH.open("GET",sURL,true);

		oXH.onreadystatechange=function () {
			 if (oXH.readyState==4) {
				oStyle=DOM.create("link");
				oStyle.rel="stylesheet";
				oStyle.href="data:text/css,"+escape(oXH.responseText);
				DOM.doc.getElementsByTagName("head")[0].appendChild(oStyle);
			 }
		}

		oXH.send(null);
	}

	Document.prototype.mozCreateElement=function (tag) {
		var el;
		if (tag.indexOf("<")!=-1 && new RegExp("<(\\w*?)( |>)").test(tag)) {
			el=this.createElement(RegExp.$1);

			var attr=new RegExp(" ([\\w-\\.:]*?)=(\"|')(.*?)(\"|')","g");

			while (match=attr.exec(tag)) el.setAttribute(match[1],match[3]);
		}
		else el=this.createElement(tag);

		return el;
	}

	Object.prototype.removeNode=Node.prototype.removeNode=function (bRemoveChildren) {
		if (Boolean(bRemoveChildren)) return this.parentNode.removeChild(this);
		else {
			var oRange=document.createRange();
			oRange.selectNodeContents(this);
			return this.parentNode.replaceChild(oRange.extractContents(),this);
		}
	}

	HTMLElement.prototype.__defineGetter__(
		"innerText",
		function () {
			var oRange=this.ownerDocument.createRange();
			oRange.selectNodeContents(this);
			return oRange.toString();
		}
	);
	HTMLElement.prototype.__defineSetter__(
		"innerText",
		function (sText) {
			this.innerHTML=(""+sText).replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
		}
	);
	HTMLElement.prototype.__defineGetter__(
		"outerHTML",
		function () {
			var sHTML="<"+this.nodeName;

			for (var iAtt=0;iAtt<this.attributes.length;iAtt++) {
				if (this.attributes.item(iAtt).nodeValue!=null) {
					sHTML+=" "+this.attributes.item(iAtt).nodeName+"=\""+this.attributes.item(iAtt).nodeValue+"\"";
				}
			}

			sHTML+=this.childNodes.length==0 && ["img","input","br","col","hr"].indexOf(this.nodeName.toLowerCase())==-1 ? ">" : ">"+this.innerHTML+"</"+this.nodeName+">";

			return sHTML;
		}
	);
	HTMLElement.prototype.contains=function (oEl) {
	   if (oEl==this) return true;
	   if (oEl==null) return false;
	   return this.contains(oEl.parentNode);		
	};
	HTMLElement.prototype.__defineSetter__(
		"unselectable",
		function (sVal) {
			this.style.MozUserSelect=sVal=="on" ? "none" : "text";
		}
	);
	HTMLElement.prototype.__defineGetter__(
		"currentStyle",
		function () {
			return this.ownerDocument.defaultView.getComputedStyle(this,null);
		}
	);

	// xml
	Array.prototype.item=function (iItem) {
		return this[iItem];
	}

	Document.prototype.loadXML=function (sXML) {
	   var oXMLParser=new DOMParser().parseFromString(sXML,"text/xml");
		  
	   while (this.hasChildNodes()) this.removeChild(this.lastChild);

	   for (var iNode=0; iNode<oXMLParser.childNodes.length;iNode++) this.appendChild(this.importNode(oXMLParser.childNodes[iNode],true));
	}

	Document.prototype.__defineGetter__(
		"xml",
		function () {
			return new XMLSerializer().serializeToString(this);
		}
	);

	Document.prototype.transformNodeToObject=function (oXSL,oResult) {
		var oXSLProcessor=new XSLTProcessor();

		try {
			oXSLProcessor.transformDocument(this,oXSL,oResult,null);
		}
		catch (oErr) { alert("Error: transformNodeToObject\n"+oErr); }
	}

	Document.prototype.transformNode=function (oXSL) {
		var oDoc=document.implementation.createDocument("","",null);

		this.transformNodeToObject(oXSL,oDoc);
		var oSerializer=new XMLSerializer();

		try {
			return oSerializer.serializeToString(oDoc);
		}
		catch (oErr) { alert("Error: transformNode"); }
	}

	XMLDocument.prototype.__defineGetter__(
		"xml",
		function () {
			return new XMLSerializer().serializeToString(this);
		}
	);

	Node.prototype.__defineGetter__(
		"xml",
		function () {
			return new XMLSerializer().serializeToString(this);
		}
	);

	Array.prototype.expr="";

	XMLDocument.prototype.setProperty=function (x,y) {
	}

	XMLDocument.prototype.selectNodes=function (sExpr,oContextNode) {
		var oResult=this.evaluate(sExpr,oContextNode ? oContextNode : this,this.createNSResolver(this.documentElement),XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),
			oNodes=new Array(oResult.snapshotLength);

		oNodes.expr=sExpr;

		for (var iNode=0;iNode<oNodes.length;iNode++) oNodes[iNode]=oResult.snapshotItem(iNode);

		return oNodes;
	}

	Element.prototype.selectNodes=function (sExpr) {
		var oDoc=this.ownerDocument;
		if (oDoc.selectNodes) return oDoc.selectNodes(sExpr, this);
		else throw "Method selectNodes is only supported by XML Nodes";
	}

	XMLDocument.prototype.selectSingleNode=function (sExpr,oContextNode) {
		var oContextNode=oContextNode || null;

		sExpr+="[1]";

		var oNodes=this.selectNodes(sExpr,oContextNode);
		
		return oNodes.length>0 ? oNodes[0] : null;
	}

	Element.prototype.selectSingleNode=function (sExpr) {
		var oDoc=this.ownerDocument;
		if(oDoc.selectSingleNode) return oDoc.selectSingleNode(sExpr, this);
		else throw "Method selectSingleNode is only supported by XML Nodes. (original exception: "+e+")";
	}

	if (!window.ActiveXObject) ActiveXObject=function (classId) {
		classId=""+classId;
		var cond,
			func,
			suffix=classId.substr(classId.indexOf(".")+1).toUpperCase();

		switch (suffix) {
			case "XMLHTTP":
				cond=document.implementation && document.implementation.createDocument;
				func=function () {
					return new XMLHttpRequest();
				}
				break;

			case "XMLDOM":
				cond=window.XMLHttpRequest;
				func=function () {
					return document.implementation.createDocument("","",null);
				}
				break;

			default:
				return null;
		}

		try {
			if (cond) {
				var x=func();

				if (x.readyState==null) {
					x.readyState=1;
					x.addEventListener(
						"load",
						function () {
							x.readyState=4;
							if (typeof x.onreadystatechange=="function") x.onreadystatechange();
						},
						false
					);
				}

				return x;
			}
		}
		catch (oErr) {}

		return null;
	}

	function mozXMLOnLoad() {
		xh.readyState=4;
		if (typeof xh.onreadystatechange=="function") xh.onreadystatechange();
	}
}