/*------------------------------------------------------------------------------
 * JavaScript rbmXML Library
 * Version 1.07.0002
 * by Bernd Rudolf, http://www.rbm.de
 * Copyright (c) 2007 Bernd Rudolf. All Rights reserved.
 *
 * partially based on zXml Library
 * by Nicholas C. Zakas, http://www.nczonline.net/
 * Copyright (c) 2004-2006 Nicholas C. Zakas. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * Changes:
 * 23.05.2007: createXMLHttp(xmlhttp) param removed since unused
 * 24.05.2007: createXMLHttp(XMLeval) returns a MSXML2.XMLhttp.3.0 if false 
 * 				due to encoding trouble of responseText with 4.0 and higher
 * 16.08.2007: IE7 supports XMLHttpRequest-Object... Line 85 changed
 *
 * v1.03.0001
 * 05.09.2007: Error Numbers implemented
 *
 * v1.05.0001
 * 21.09.2007: added checkboxes and radiobuttons to getFormData 
 *
 * v1.06.0001
 * 23.09.2007: functions XMLencode and postEncode added
 * 		
 * v1.06.0002
 * 28.12.2007: bug in selectNodes gefixed	
 * 		
 * v1.07.0001
 * 06.02.2008: MSXML 5.0 stuff removed!
 *
 * v1.07.0002
 * 23.04.2008	ResolveExternals eingefügt
 *------------------------------------------------------------------------------
 * Error-Numbers:
 * 30 = Your browser doesn't support an XML HTTP Request.
 * 31 = Could not create XML HTTP Request.
 * 40 = Your browser doesn't support an XML DOM document.
 * 41 = Could not create XML DOM document.
 * 50 = No XPath engine found.
 */  


var rbmXML = {
    buseActiveX: (typeof ActiveXObject != "undefined"),
    buseDom: document.implementation && document.implementation.createDocument,
    buseXMLHttp: (typeof XMLHttpRequest != "undefined")
};

rbmXML.XMLHttp_VERS = ["MSXML2.XmlHttp.6.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.3.0"];

rbmXML.DOM_VERS = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0"];

rbmXML.getFormData = function(element)	{
				var strPost = ""

					var myInput = element.getElementsByTagName("input");

					for (i = 0; i < myInput.length; i++)	{
						//alert(i + ": " + myInput[i].id + " " + myInput[i].type);
						switch (myInput[i].type)	{
						case "checkbox":	
							if (strPost != "")
								strPost += "&";
							if (myInput[i].checked == true)	{
								strPost += myInput[i].name + "=1";
							}
							else	{
								strPost += myInput[i].name + "=0";
							}
							break;
						
						case "radio":	

							var thisName = myInput[i].name;
							while(thisName == myInput[i].name)	{
								if(myInput[i].checked)	{
									if (strPost != "")
										 strPost += "&"
									strPost += myInput[i].name + "=" + myInput[i].value;
								}
								i++;
							}
							i--;
							break;
							
						case "button":							
							break;
						
						default:	
							if (myInput[i].value) 	{
								if (strPost != "")
									 strPost += "&"
								strPost += myInput[i].name + "=" + myInput[i].value;
							}
							break;
						}

						

					}
					var myInput = element.getElementsByTagName("select");
					for (i = 0; i < myInput.length; i++)	{
						if (strPost != "")
							 strPost += "&"
						strPost += myInput[i].name + "=" + myInput[i].value;
					}

					var myInput = element.getElementsByTagName("textarea");
					for (i = 0; i < myInput.length; i++)	{
						if (strPost != "")
							 strPost += "&"
						strPost += myInput[i].name + "=" + myInput[i].innerHTML;
					}

					
					var strEnc = rbmXML.urlEncode(strPost)
					
					return strEnc;
				};


rbmXML.postEncode = function (strPost)	{	//encoding Formdata for XML
	
					var strEnc = "";
					for (i = 0; i < strPost.length; i++)	{
						
						c = strPost.charCodeAt(i);
						switch(c)	{
/*						case 60:
							strEnc += "%60";
							break;
*/
						case 61:	//=
							strEnc += "%61";
							break;
/*							
						case 62:
							strEnc += "%62";
							break;
							
						case 39:
							strEnc += "%39;";
							break;
							
						case 63:	//?
							strEnc += "%62";
							break;
*/
						case 38:	//&
							strEnc += "%38";
							break;
/*							
						case 34:
							strEnc += "%34;";
							break;
							
						case 36:
							strEnc += "%36";
							break;
*/
						case 37:	//%
							strEnc += "%37";
							break;
						
						default:
							strEnc += strPost.charAt(i);
							break;
						}
					}
					
					return strEnc

				};

rbmXML.urlEncode = function (strPost)	{
					var strEnc = "";
					for (i = 0; i < strPost.length; i++)	{
						
						c = strPost.charCodeAt(i);
						if ((c < 48 || c > 122) && c != 38)	{
							strEnc += "%" + c.toString(16);
						}
						else	{
							strEnc += strPost.charAt(i);
						}
					}
					return strEnc
				};


rbmXML.XMLencode = function (strPost)	{	//encoding Formdata for XML
	
					var strEnc = "";
					for (i = 0; i < strPost.length; i++)	{
						
						c = strPost.charAt(i);
						switch(c)	{
						case "<":
							strEnc += "&lt;";
							break;

						case ">":
							strEnc += "&gt;";
							break;
							
						case "'":
							strEnc += "&#39;";
							break;
							
						case "&":
							strEnc += "&#38;";
							break;
							
						case "\"":
							strEnc += "&#34;";
							break;
							
						case "$":
							strEnc += "&#36;";
							break;
						
						default:
							strEnc += strPost.charAt(i);
						}
					}
					return strEnc
				};
 
rbmXML.createXMLHttp = function (XMLeval)	{
	
		   var xmlhttp;
	
		   if (rbmXML.buseXMLHttp && !rbmXML.buseActiveX) {	//otherwise IE7 returns XMLHttpRequest
		        return new XMLHttpRequest();
		    } 
		    else if (rbmXML.buseActiveX) { //IE < 7.0 = use ActiveX
		  
		        if (!rbmXML.XMLHttp_V || !XMLeval) {	//alway use the routine for 
		            if(!XMLeval)	{	//try to get MSXML2.XMLHttp.3.0 first!! Due to encoding issue with 4.0 and higher
			            for (var i=rbmXML.XMLHttp_VERS.length - 1; i >= 0; i--) {
			                try {
			                    new ActiveXObject(rbmXML.XMLHttp_VERS[i]);
			                    sVersion= rbmXML.XMLHttp_VERS[i];
			                    break;
			                } 
			                catch (oError) {                
			            	}
			         	}
			         
		            }
		            else	{
			            for (var i=0; i < rbmXML.XMLHttp_VERS.length; i++) {
			                try {
			                    new ActiveXObject(rbmXML.XMLHttp_VERS[i]);
			                    rbmXML.XMLHttp_V  = rbmXML.XMLHttp_VERS[i];		//do not store for further use!!
			                    break;
			                } 
			                catch (oError) {                
			            	}
			         	}	
			         	sVersion = rbmXML.XMLHttp_V;
		            }
		        }
		        
		        if (sVersion) {
		            return new ActiveXObject(sVersion);
		        } else {
		            throw new Error(31, "Could not create XML HTTP Request.");
		        }
		    } 
		    else {
		        throw new Error(30, "Your browser doesn't support an XML HTTP Request.");
		    }
		
	};


rbmXML.createDoc = function ()	{
    if (!rbmXML.buseActiveX) {

        var oXmlDom = document.implementation.createDocument("","",null);

        oXmlDom.parseError = {
            valueOf: function () { return this.errorCode; },
            toString: function () { return this.errorCode.toString() }
        };
        return oXmlDom;        
        
    } else if (rbmXML.buseActiveX) {
        if (!rbmXML.DOM_VER) {
            for (var i=0; i < rbmXML.DOM_VERS.length; i++) {
                try {
                    new ActiveXObject(rbmXML.DOM_VERS[i]);
                    rbmXML.DOM_VER = rbmXML.DOM_VERS[i];
                    break;
                } catch (oError) {  
                	//alert("CreateDoc: " + oError.description + " - " + rbmXML.DOM_VERS[i]);              
                }
            }
        }
//    alert(rbmXML.DOM_VER);
        if (rbmXML.DOM_VER) {
        		var retObj = new ActiveXObject(rbmXML.DOM_VER);
        		if(rbmXML.DOM_VER == "MSXML2.DOMDocument.3.0")	{
        			//default QueryLanguage in 3.0 is XSLPatterns so change it!
	        		retObj.setProperty("SelectionLanguage", "XPath");
        		}
//        		retObj.setProperty("resolveExternals", true);
        		retObj.resolveExternals = true;
            
            return retObj;
        } else {
            throw new Error(41, "Could not create XML DOM document.");
        }
    } else {
        throw new Error(40, "Your browser doesn't support an XML DOM document.");
    }
};

rbmXML.renderToDoc = function (objXML, objXSL, element, bappend)		{
							
//			alert(objXML.xml);
//			alert(objXSL.xml);
//	 		alert("Render to: " + element);

			if ( rbmXML.buseActiveX )	{										
				var strOut = objXML.transformNode(objXSL);
				var objElement = document.getElementById(element);
				objElement.innerHTML = strOut;
//				alert(strOut);
			}
			else	{
				var xsltProcessor = new XSLTProcessor();
				xsltProcessor.importStylesheet(objXSL);
				var objOut = xsltProcessor.transformToFragment(objXML, document);
				var objElement = document.getElementById(element);

				alert(objElement.hasChildNodes());
				if (!bappend && objElement.hasChildNodes())	{
					while (objElement.hasChildNodes())	{
						objElement.removeChild(objElement.firstChild);
					}
				}
					
				objElement.appendChild(objOut);
				
			}
					
	};	


rbmXML.serXML = function (objXML)	{	/*nur Firefox */
					var oSer = new XMLSerializer();
					return oSer.serializeToString(objXML);	
				};										
			
rbmXML.showXML = function (objXML)	{
					if (rbmXML.buseActiveX)
						return objXML.xml
					else
						return rbmXML.serXML(objXML)
				};


rbmXML.displayParseError = function(objErr)	{
			strErr = objErr.reason + "(" + objErr.line + ", " + objErr.linepos + ") in \n" + objErr.url
			alert(strErr);					
				};

/**
 * Selects the nodes matching a given XPath expression.
 * @param oRefNode The node from which to evaluate the expression.
 * @param sXPath The XPath expression.
 * @param oXmlNs An object containing the namespaces used in the expression. Optional.
 * @return An XML node matching the expression or null if no matches found.
 */
rbmXML.selectNodes = function (oRefNode /*:Node*/, sXPath /*:String*/, oXmlNs /*:Object*/) {
    if (typeof XPathEvaluator != "undefined") {
    
        oXmlNs = oXmlNs || {};
        
        var nsResolver = function (sPrefix) {
    			  return oXmlNs[sPrefix];
        };
		
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, oRefNode, nsResolver, 
                                          XPathResult.ORDERED_NODE_ITERATOR_TYPE, 
                                          null);

        var aNodes = new Array;
        
        if (oResult != null) {
            var oElement = oResult.iterateNext();
            while(oElement) {
                aNodes.push(oElement);
                oElement = oResult.iterateNext();
            }
        }
        
        return aNodes;
        
    } else if (rbmXML.buseActiveX) {
    		if (oXmlNs) {
            var sXmlNs = "";
            for (var sProp in oXmlNs) {
                sXmlNs += "xmlns:" + sProp + "=\'" + oXmlNs[sProp] + "\' ";
            }
    			  oRefNode.ownerDocument.setProperty("SelectionNamespaces", sXmlNs);
    		}  		
        return oRefNode.selectNodes(sXPath);
    } else {
        throw new Error(50, "No XPath engine found.");
    }

};

/**
 * Selects the first node matching a given XPath expression.
 * @param oRefNode The node from which to evaluate the expression.
 * @param sXPath The XPath expression.
 * @param oXmlNs An object containing the namespaces used in the expression.
 * @return An XML node matching the expression or null if no matches found.
 */
rbmXML.selectSingleNode = function (oRefNode /*:Node*/, sXPath /*:String*/, oXmlNs /*:Object*/) {
    if (typeof XPathEvaluator != "undefined") {            
	
        oXmlNs = oXmlNs || {};
        
        var nsResolver = function (sPrefix) {
    			  return oXmlNs[sPrefix];
        };
    
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, oRefNode, nsResolver,
                                          XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    
        if (oResult != null) {
            return oResult.singleNodeValue;
        } else {
            return null;
        }              
    
    } else if (rbmXML.buseActiveX) {
    		if (oXmlNs) {
            var sXmlNs = "";
            for (var sProp in oXmlNs) {
                sXmlNs += "xmlns:" + sProp + "=\'" + oXmlNs[sProp] + "\' ";
            }
//XXX    			  oRefNode.ownerDocument.setProperty("SelectionNamespaces", sXmlNs);
    		}    
        return oRefNode.selectSingleNode(sXPath);
    } else {
        throw new Error(50, "No XPath engine found.")
    }

};



/**
 * Serializes the given XML node into an XML string.
 * @param oNode The XML node to serialize.
 * @return An XML string.
 */
rbmXML.serializeToString = function (oNode ) {

    var sXml = "";
    
    switch (oNode.nodeType) {
        case 1: //element
            sXml = "<" + oNode.tagName;
            
            for (var i=0; i < oNode.attributes.length; i++) {
                sXml += " " + oNode.attributes[i].name + "=\"" + oNode.attributes[i].value + "\"";
            }
            
            sXml += ">";
            
            for (var i=0; i < oNode.childNodes.length; i++){
                sXml += this.serializeToString(oNode.childNodes[i]);
            }
            
            sXml += "</" + oNode.tagName + ">";
            break;
            
        case 3: //text node
            sXml = oNode.nodeValue;
            break;
        case 4: //cdata
            sXml = "<![CDATA[" + oNode.nodeValue + "]]>";
            break;
        case 7: //processing instruction
            sXml = "<?" + oNode.nodevalue + "?>";
            break;
        case 8: //comment
            sXml = "<!--" + oNode.nodevalue + "-->";
            break;
        case 9: //document
            for (var i=0; i < oNode.childNodes.length; i++){
                sXml += this.serializeToString(oNode.childNodes[i]);
            }
            break;
            
    }  
    
    return sXml;
};	


// check for XPath implementationif( document.implementation.hasFeature("XPath", "3.0") ){  // prototying the XMLDocument  XMLDocument.prototype.selectNodes = function(cXPathString, xNode)  {     if( !xNode ) { xNode = this; }      var oNSResolver = this.createNSResolver(this.documentElement)     var aItems = this.evaluate(cXPathString, xNode, oNSResolver,                   XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)     var aResult = [];     for( var i = 0; i < aItems.snapshotLength; i++)     {        aResult[i] =  aItems.snapshotItem(i);     }     return aResult;  }  // prototying the Element  Element.prototype.selectNodes = function(cXPathString)  {     if(this.ownerDocument.selectNodes)     {        return this.ownerDocument.selectNodes(cXPathString, this);     }     else{throw "For XML Elements Only";}  }}