// =============================================================================
// object providing various XML related capabilities
// It supports the following methods:
// 
// .createXMLDocument(strRootElementName) - returns a cross browser
//      XMLDOMDocument object or false if the object could not be created. 
//      The parameter is the name of the root xml element.
//
// .parseXML(strXML) - returns a cross browser XMLDOMDocument object based
//      on the xml string passed in as a parameter. Returns false if a document
//      cannot be created.
//
// .createXMLHTTP() - returns a cross browser XMLHTTP object, or false if
//      the object could not be created.
//
// .sendXMLHTTPPost(strURL, strParams) - sends an xmlhttp post request to the specified
//      url containing the specified parameters. Returns an XMLDOMDocument containing
//      the response.
//
function hbcXML() {

// TODO: modify methods that return XMLDOM objects so that, when an error occurs
// they return an XMLDOM document describing the error rather than false as at 
// present.

  // methods
  this.createXMLDocument = hbcXML_CreateXMLDocument;
  this.parseXML = hbcXML_ParseXML;
  this.createXMLHTTP = hbcXML_CreateXMLHTTP;
  this.sendXMLHTTPPost = hbxXML_sendXMLHTTPPost;

  
  // ========================================================
  // Create an XMLDOMDocument object
  function hbcXML_CreateXMLDocument(strRootElementName) {
    if (arguments.length==0) {
      // no argument was passed so we use a default name for the root element
      strRootElementName="HBCXML";
    }
    var xmlDoc;
    if (document.implementation && document.implementation.createDocument) {
      // document.implementation is used by DOM 2 compliant browsers, e.g. gecko based
      // browsers (firefox, mozilla) and opera.
      //
      // note that opera insists you specify the root element during document creation
      // as it does not allow you to add a root element later, unlike gecko.
      
      // create a document type
      xmlDoc = document.implementation.createDocument("http://www.w3.org/2001/XMLSchema-instance", strRootElementTagName, null);
      xmlDoc.insertBefore(xmlDoc.createProcessingInstruction("xml", "version=\"1.0\""), xmlDoc.documentElement);
    } else if (window.ActiveXObject) {
      // IE does not support document.implementation, instead it uses an ActiveX object
      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
      xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
      var xmlRoot = xmlDoc.createElement(strRootElementTagName);
      xmlDoc.appendChild(xmlRoot);
    } else {
      xmlDoc = false;
    }
    return xmlDoc;
  }
  // ========================================================
  
  
  // ========================================================
  // Create an XML document from an xml string
  function hbcXML_ParseXML(strXML) {
    var xmlDoc;
    //if (document.implementation && document.implementation.createDocument) {
    if (window.DOMParser) {
      // DOMParser is used by gecko based browsers (firefox, mozilla) and opera.
      // The W3C Spec actually defines LSParser as part of the DOM 3 Load & Save spec
      // but browsers don't seem to support this yet. DOMParser seems to have been
      // modelled on the DOMParser that is part of a couple of XML libraries (e.g. Xerces)
      var parser = new DOMParser(); 
      // wrap the next line in a try...catch because invalid xml may cause an exception
      try {
        xmlDoc = parser.parseFromString(strXML, "text/xml");
      } catch(e) {
        return false;
      }       
    } else if (window.ActiveXObject) {
      // IE does not support DOMParser, instead it uses an ActiveX object
      xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
      try {
        xmlDoc.loadXML(strXML);
      } catch(e) {
        return false;
      }
    } else {
      xmlDoc = false;
    }
    return xmlDoc;
  }
  // ========================================================
  
  // ========================================================
  // Create an XMLHTTPRequest object
  function hbcXML_CreateXMLHTTP() {
    var xmlhttp;
    if(window.XMLHttpRequest) {
      try {
  		  xmlhttp = new XMLHttpRequest();
      } catch(e) {
  			xmlhttp = false;
      }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
      try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
      } catch(e) {
       	try {
      		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
       	} catch(e) {
       		xmlhttp = false;
        }
  	  }
    }
    return xmlhttp;
  }
  // ========================================================
  
  
  // ========================================================
  // Send an xmlhttp post request
  function hbxXML_sendXMLHTTPPost(strURL, strParams) {
    var myXMLHTTP = hbcXML_CreateXMLHTTP();
    
    if (myXMLHTTP) {
    
      myXMLHTTP.open("POST", strURL, false);

      myXMLHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
      myXMLHTTP.send(strParams);
      // return the resultant xml as an XMLDOM object or false
      if (myXMLHTTP.status == 200) {
        // we have a 200 OK response from the server
        //alert(typeof(myXMLHTTP.responseXML.xml));
        
        if (myXMLHTTP.responseXML.xml == "") {
          // ArcIMS does not set the correct mimetype
  		    // So the correct xml response might not actually be in responseXML
  		    // Therefore we need to test for the presence of xml in responseText too
  		    var re = new RegExp("\<\?.*xml","ig");
  		    if (re.exec(myXMLHTTP.responseText)) {
  		      // responseText appears to contain some xml
  		      // So we will try to put it into an XMLDOM object and return that
  		      return hbcXML_ParseXML(myXMLHTTP.responseText);
  		    }
  		  } else {
  		    
  		    return myXMLHTTP.responseXML;
  		  }
  		} else {
  		  // server returned a 404 or 500 response
  		  
  		  return false;
  		}
	  } else {
      return false;
	  }
  }
  // ========================================================
  
} // == END OF OBJECT =======================================

