/*
Summary:  BjaxXlstEngine is a library of Bjax functions.
          For use when needing initiating cross browser XSLT transformations.
Remarks:  Bjax is Ajax plus XSLT, including XPATH, functions
          initiated from browser script.
Version:  0.1
Author:   John Bentley (www.softmake.com.au)

*/

/*
Summary: Static utility functions for manipulating and displaying
         XML documents and DOM nodes in HTML pages. */
function Domer() {}

// Static Members

/*
Summary: appends a node aquired that comes from an XML DOM into a node
          in an HTML DOM.
Based On:
  Newsgroups: microsoft.public.windows.inetexplorer.ie55.programming.dhtml.scripting, microsoft.public.xml
  From: Martin Honnen
  Date: Sat, 21 Dec 2002 13:35:51 +0100
  Subject: Re: How to append a XML node collection to a HTML node collection?
  http://groups.google.com/group/microsoft.public.windows.inetexplorer.ie55.programming.dhtml.scripting/browse_thread/thread/e0e9f31c9b312f9d/81a4f5997a4fb176?lnk=st&q=insert+XML+DOM+node+into+DHTML+DOM&rnum=1&hl=en#81a4f5997a4fb176 */
Domer.appendXmlNode = function (xmlDomDoc, xmlElementName, htmlDomNodeId) {
  var xmlDomNode = null;

  if (typeof xmlDomDoc.selectSingleNode != "undefined") {
    xmlDomNode = xmlDomDoc.selectSingleNode("//*[local-name()='" + xmlElementName + "']");
  } else {
    xmlDomNode = xmlDomDoc.getElementsByTagName(xmlElementName)[0];
  }

  if (xmlDomNode === null) {
    throw new Error("Could not find " + xmlElementName + " in xmlDomDoc" );
  }
  var htmlDomNode = document.getElementById(htmlDomNodeId);

  if (htmlDomNode.ownerDocument && htmlDomNode.ownerDocument.importNode) {
    // htmlDomNode.innerHTML = "";
    htmlDomNode.appendChild(Domer.importNode(document, xmlDomNode));
    // W3C. (This doesn't work when applying CSS to "Displaying Dom".)
    //htmlDomNode.appendChild(htmlDomNode.ownerDocument.importNode(xmlDomNode, true));
  } else {
    // IE
    // The text way:
    htmlDomNode.innerHTML += xmlDomNode.xml;

    // The DOM way ... (This doesn't work when applying CSS to "Displaying Dom".)
    // htmlDomNode.appendChild(Domer.importNode(document, xmlDomNode));
  }
};

/*
Returns: an XML DOM node as an HTML DOM node.
Based On:
  Newsgroups: microsoft.public.windows.inetexplorer.ie55.programming.dhtml.scripting, microsoft.public.xml
  From: Martin Honnen
  Date: Sat, 21 Dec 2002 13:35:51 +0100
  Subject: Re: How to append a XML node collection to a HTML node collection?
  http://groups.google.com/group/microsoft.public.windows.inetexplorer.ie55.programming.dhtml.scripting/browse_thread/thread/e0e9f31c9b312f9d/81a4f5997a4fb176?lnk=st&q=insert+XML+DOM+node+into+DHTML+DOM&rnum=1&hl=en#81a4f5997a4fb176 */
Domer.importNode = function (htmlDomDocument, xmlDomNode) {
  var nodeTypeElement = 1;
  var nodeTypeText = 3;

  switch (xmlDomNode.nodeType) {
    case nodeTypeElement:
      var element = htmlDomDocument.createElement(xmlDomNode.nodeName);
      for (var i = 0; i < xmlDomNode.attributes.length; i++) {
        element.setAttribute(xmlDomNode.attributes[i].nodeName, xmlDomNode.attributes[i].nodeValue);
      }
      for (i = 0; i < xmlDomNode.childNodes.length; i++) {
        element.appendChild(Domer.importNode(htmlDomDocument, xmlDomNode.childNodes[i]));
      }
      return element;
      //break;
    case nodeTypeText:
      var textNode = htmlDomDocument.createTextNode(xmlDomNode.nodeValue);
      return textNode;
      //break;
    /* add other nodes here */
    default:
      throw new Error("importNode: Node type not implemented ~ :" + xmlDomNode.nodeType);
  }
  
  return true;
};

/* Summary: Takes an XmlDoc (uri string or xmlDOMDocument object),
            transforms it into an XHTML representation, and inserts this
            representation into the XHTML Node identified by xhtmlDomNodeId
  Remarks: You could copy and paste this code into your app if you want to
           have control over the asynchronous process.
  Params:  xmlUriOrDoc
                A string uri of the xml source, eg "books.xml"
           xhtmlDomNodeId
                A string id of a node in your document where you want to
                insert the result. eg "myOutput"
           onTransformed (Optional)
                A function to be called back after the transformation has taken place.
  Usage Example:
                  function onTransformed () {
                    alert("Transformed");
                  }
                  Domer.outputXmlAsXhtml(XmlDoc, "domOut", onTransformed);            */
Domer.outputXmlAsXhtml =  function (xmlUriOrDoc, xhtmlDomNodeId, onTransformedCallback) {
  var BjaxDomDisplay = new Bjaxer();

  // Asynchronous Callback.
  var domerOnPrepComplete = function () {
    var resultXmlDomDoc = BjaxDomDisplay.getTransformedXmlDomDoc();
    Domer.appendXmlNode(resultXmlDomDoc, "div", xhtmlDomNodeId);
    if (onTransformedCallback != null) {onTransformedCallback();}
  };
  
  var xsltNamespaces = 'xmlns:xsl="http://www.w3.org/1999/XSL/Transform"' +
                       ' xmlns:msxsl="urn:schemas-microsoft-com:xslt"';
  BjaxDomDisplay.prepareTransform(xmlUriOrDoc, "xmlDisplay.xslt", domerOnPrepComplete, xsltNamespaces);
};
