// File: /include/js/Shared/XML/XML.js
// Desc: XML parsing
// $Revision: 26$
// $Date: 5/14/2007 12:10:37 PM$
// $Author: Donnie Tognazzini$
// $NoKeywords$

/******************************************************************************
  XML_InitializeMembersFromXML

    Iterates over a single-level DOM tree and initializes properties of an
    object if the property already exists on the object.

    [in]     xmlDOMTree
    [in/out] obj
    [in]     requiredTopMostTagName

    Exceptions:
        XML_EX_InitializeMembersFromXMLElementFailed

 ******************************************************************************/
function XML_InitializeMembersFromXML( xmlDOMTree, obj, requiredTopMostTagName )
{
    var element;
    if ( xmlDOMTree.firstChild.nodeName.toLowerCase( ) == 'xml' )
    {
        element = xmlDOMTree.firstChild.nextSibling;
    }
    else
    {
        // the Yahoo parser does not have the xml tag in the DOM tree
        element = xmlDOMTree.firstChild;
    }

    XML_InitializeMembersFromXMLElement( element, obj, requiredTopMostTagName );
}

/******************************************************************************
  XML_InitializeMembersFromXMLElement

    Iterates over a single-level DOM tree and initializes properties of an
    object if the property already exists on the object.

    [in]     xmlDOMTree
    [in/out] obj
    [in]     requiredTopMostTagName

    Exceptions:
        XML_EX_InitializeMembersFromXMLElementFailed

 ******************************************************************************/
function XML_InitializeMembersFromXMLElement( xmlDOMElement, obj, requiredTopMostTagName )
{
    var ELEMENT_NODE_TYPE = 1;

    var elementNodeName = '';
    var elementValue    = '';

    try
    {
        // find the first element tag
        var element = null;
        for ( element = xmlDOMElement; element.nodeType != ELEMENT_NODE_TYPE; element = element.nextSibling )
        { /* eating up leading spaces or comments */
        }

        if ( element.nodeName != requiredTopMostTagName )
        {
            throw new XML_EX_UnexpectedXMLTag( element.nodeName, requiredTopMostTagName );
        }

        element = element.firstChild;
        for ( ; element != null; element = element.nextSibling )
        {
            if ( element.nodeType != ELEMENT_NODE_TYPE )
            {
                // skip non-element node types
                continue;
            }

            elementNodeName = element.nodeName ? element.nodeName : '';
            if ( typeof obj['m_' + elementNodeName] == 'undefined' )
            {
                // TBD : nodeName undefined for this object. Should throw an exception here?
                // TODO/HMM - Why do we want to skip values?  Allowing them gives us the ability
                //            to dynamically create anything we want from a chunk of XML.
                //          - Maybe add another param that would skip this check.  But wait
                //            until we find that something that that is useful.
                continue;
            }


            elementValue = '';
            if ( element.nodeValue && element.nodeValue.length != 0 )
            {
                elementValue = element.nodeValue;
            }
            else if ( element.firstChild && element.firstChild.data )
            {
                elementValue = element.firstChild.data;
            }

            switch ( elementNodeName ) {
                case 'fwdCodes':
                    obj.m_fwdCodes = new TYPE_ForwardCodeList( element );
                    break;
                case 'carriers':
                    obj.m_carriers = new TYPE_CarrierList( element );
                    break;
                case 'calls':
                    obj.m_calls = new CL_CallList( element );
                    break;
                case 'cid':
                    obj.m_cid = new CL_CallId( element );
                    break;
                default:
                    try {
                        // TODO -- figure out why we add and remove the encoding.
                        //         also why not just decode...( encode...( val ) ); ?
                        // add encoding
                        obj['m_' + elementNodeName] = encodeURIComponent( elementValue );
                        // remove the encoding
                        obj['m_' + elementNodeName] = decodeURIComponent( obj['m_' + elementNodeName] );
                    }
                    catch ( e ) {
                        throw new XML_EX_InitializeMembersFromXMLElementFailed( e, elementNodeName, elementValue, requiredTopMostTagName );
                    }
                    break;
            }
        }
    }
    catch ( e )
    {
        throw new XML_EX_InitializeMembersFromXMLElementFailed( e, elementNodeName, elementValue, requiredTopMostTagName );
    }
}

function loadXMLDoc( filename )
{
    var xmlDoc;
    // code for IE
    if ( window.ActiveXObject )
    {
        xmlDoc = new ActiveXObject( 'Microsoft.XMLDOM' );
    }
    // code for Mozilla, Firefox, Opera, etc.
    else if ( document.implementation && document.implementation.createDocument )
    {
        xmlDoc = document.implementation.createDocument('','',null);
    }
    else
    {
        throw new XML_EX_UnableToCreateDOMDOC( );
    }
    xmlDoc.async = false;
    xmlDoc.load( filename );
    return( xmlDoc );
}


/******************************************************************************
  XML_parse

    Parses a XML in the passed text and returns the resulting XML DOM element.

    [in]     text
    [returns] XML DOM
 ******************************************************************************/

function XML_parse(text) {
    if (typeof DOMParser != 'undefined') {
        // Mizilla, Firefox, and related...
        return (new DOMParser()).parseFromString(text, 'application/xml');
    }
    else if (typeof ActiveXObject != 'undefined') {
        // IE
        var doc = new ActiveXObject( 'Microsoft.XMLDOM' );
        doc.loadXML(text);
        return doc;
    }
    else {
        // supposed safari support using logic from Sarissa (sarissa.sourceforge.net).
        var url = 'data:text/xml;charset=utf-8,' + encodeUriComponent(text);
        var req = new XMLHttpRequest();
        req.open('GET', url, false);
        req.send(null);
        return req.responseXML;
    }
}
