/* author: eduard gode <eduard.gode@gode.de> 
 * rights: you may not use (execute, cite, ...) this code,
 *         except as whole code without any changes in functions
 *         header and documentation
 *         
 *
 * 
 * usage: WDSS.requestXmlDocument( url, callback )
 *
 * url                is the url of the document to load.
 *                    it must be a url in the domain of the current document.
 * callback(node,url) is a function which will be called when the file at url
 *                    was successfully loaded. Parameters when called are:
 *                    node    the root node in the loaded document (document.firstChild)
 *                    url     the url of the loaded document
 *                    The method node.getElementById(id) to access deeper nodes by id.
 *                    The method node.getScriptCode( optId) to access all scripts below node or below node having id="optId".
 * 
 *
 * 
 * usage: WDSS.parseXML( xmlString, callback )
 *
 * xmlString          is a string containing xml code
 * callback(node,url) is a function which will be called when xmlString
 *                    was successfully loaded. Parameters when called are:
 *                    node    the root node in the loaded document (document.firstChild)
 *                    url     the url of the loaded document
 *                    The method node.getElementById(id) to access deeper nodes by id.
 *                    The method node.getScriptCode( optId) to access all scripts below node or below node having id="optId".
 *
 * 
 * 
 * usage: xmlString = WDSS.xmlEncode(node)
 *
 * node               is a DOM node
 *
 * the function returns a xmlString representing the node tree beginning by node
 *
 *
 * 
 * usage: jsCode = WDSS.getXmlScriptCode( node )
 *
 * node               is a DOM node
 *
 * the function returns the script code in the script node or the script ancestors below node
 *
 *
 *
 * usage: WDSS.importNodeIntoDocument( node, doc )
 *
 * node               is a DOM node object
 * doc                is a DOM document
 *
 * returns a copy of node imported into the specified document. If document is null, import into this document.
 *
 *
 *
 * usage: WDSS.replaceNodeChilds( destNode, sourceNode )
 *
 * destNode           is a DOM node object
 * sourceNode         is a DOM node object
 *
 * replaces all childs of destNode by all childs of sourceNode;
 *
 */
if(null==window.WDSS)window.WDSS={module:{},requireModule:function(m){if(!this.module[m]){this.module[m]=1;document.write('<script type="text/javascript" src="/js-pool/wdss/'+m+'.js"></script>');}}};
// HEADER END

WDSS.module.file = '$Revision: 1.14 $';


if ( null == WDSS.deprecated ) WDSS.deprecated = function (name) {};


if ( null == WDSS.file ) {

  WDSS.file = {};


  WDSS._newActiveXObject = function ( version ) {
    for ( var i = 0; i < version.length; i++ ) {
      try {
	//alert( version[i] );
	var xmlDoc = new ActiveXObject( version[i] );
	return xmlDoc;
      } catch ( e ) {
	// do nothing
      }
    }
    return null;
    //throw new Error( 'can not create ajax doc (MSXML is not installed)' );
  };


  WDSS._getNodeAttributeNode = function ( node, name ) {
    if ( null == node.attributes ) return null;

    for ( var i = 0; i < node.attributes.length; i++ ) {
      var attr = node.attributes[i];
      if ( attr.nodeName == name ) return attr;
    }

    return null;
  };


  WDSS._getNodeAttribute = function ( node, name ) {
    var attr = WDSS._getNodeAttributeNode( node, name );
    return ( null != attr ) ? attr.nodeValue : null;
  }


  WDSS.getXmlElementById = function ( node, id ) {
    if ( null == node ) return null;

    if ( null != node.attributes ) {
      // mozilla #text nodes do not have node.getAttribute
      // IE does not like to check null == node.getAttribute
      var eId = node.getAttribute( 'id' );
      //var eId = WDSS._getNodeAttribute( node, 'id' );
      if ( null != eId && eId == id ) return node;
    }

    for ( var n = node.firstChild; n != null; n = n.nextSibling ) {
      var idNode = WDSS.getXmlElementById(n,id);
      if ( null != idNode ) return idNode;
    }

    return null;
  };


  WDSS.getXmlScriptCode = function ( node ) {
    if ( null == node ) return null;
    var scripts = ( null != node.nodeName && 'script' == node.nodeName ) ? [ node ] : node.getElementsByTagName( 'script' );
    var code = '';
    if ( null != scripts ) {
      for ( var i = 0; i < scripts.length; i++ ) {
        for ( var n = scripts[i].firstChild; n != null; n = n.nextSibling ) {
          code += n.nodeValue;
        }
      }
    }
    return code;
  };


  WDSS._createXMLHttpRequest = function () {
    var xmlHttp = null;
    // Mozilla, Opera, Safari sowie Internet Explorer 7
    // 
    // former implementation:
    // var myDoc = document.implementation.createDocument("", "", null);
    // myDoc.onload = myCustomOnloadHandler;
    // myDoc.load('mydocument.xml');
    if ( typeof(XMLHttpRequest) != 'undefined' ) {
      xmlHttp = new XMLHttpRequest();
      //xmlHttp.overrideMimeType('text/xml');
    }
    if ( !xmlHttp ) {
      // Internet Explorer 6 und aelter
      var version = [ 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP' ]; //, 'Microsoft.XMLDOM' ];
      xmlHttp = WDSS._newActiveXObject(version);
    }

    return xmlHttp;
  };


  WDSS.xmlDoc = function ( node ) {
    this.node = node;
    this._sync();
  };
  { var prototype = WDSS.xmlDoc.prototype;

    prototype._sync = function () {
      var node = this.node;
      this.nodeType   = node.nodeType;  
      this.nodeName   = node.nodeName;
      this.nodeValue  = node.nodeValue;
      this.data       = node.data;
      this.attributes = node.attributes;
      this.firstChild = node.firstChild;
      this.lastChild  = node.lastChild;
      this.childNodes = node.childNodes;
      // parentNode, nextSibling, previousSibling are null
    };
    prototype.getElementById       = function ( id   ) { return WDSS.getXmlElementById( this, id );       };
    prototype.getAttribute         = function ( name ) { return WDSS._getNodeAttribute( this, name );     };
    prototype.getAttributeNode     = function ( name ) { return WDSS._getNodeAttributeNode( this, name ); };
    //prototype.removeAttribute
    //prototype.removeAttributeNode
    //prototype.setAttribute
    //prototype.setAttributeNode
    prototype.getElementsByTagName = function ( name ) { return this.node.getElementsByTagName( name );       };
    prototype.appendChild          = function ( node ) { this._sync(); return this.node.appendChild( child ); };
    prototype.removeChild          = function ( n    ) { this._sync(); return this.node.removeChild( n    );  };
    prototype.replaceChild         = function ( n, c ) { this._sync(); return this.node.replaceChild( n, c ); };
    prototype.insertBefore         = function ( n, b ) { this._sync(); return this.node.insertBefore( n, b ); };
    prototype.appendData           = function ( data ) { this._sync(); return this.node.appendData( data );   };
    prototype.deleteData           = function ( p, c ) { this._sync(); return this.node.deleteData( p, c );   };
    prototype.insertData           = function ( p, d ) { this._sync(); return this.node.insertData( p, d );   };
    prototype.replaceData          = function ( p,c,d) { this._sync(); return this.node.replaceData(p,c,d);   };
    prototype.cloneNode            = function ( bool ) { return new WDSS.xmlDoc(this.node.cloneNode( bool )); };
    prototype.hasChildNodes        = function (      ) { return this.node.hasChildNodes(); };
    prototype.getScriptCode        = function ( id   ) {
      var root = this;
      if ( id != null ) root = this.getElementById( id );
      return WDSS.getXmlScriptCode( root );
      var scripts = root.getElementsByTagName( 'script' );
      if ( null != scripts ) {
        var script = '';
        for ( var i = 0; i < scripts.length; i++ ) {
          script += WDSS.getXmlScriptCode( scripts[i] );
        }
      }
      return script;
    };
  }


  WDSS.requestXmlDocument = function ( url, callback, args ) {
    if ( null == args ) args = {};
    var params = args.parameters;
    var method = 'get'; // args.method; if ( null != method ) method = args.method.match( /^get$/i ) ? 'get' : 'post';

    // make url absolute
    var resUrl; var resLoc;
    if ( (resUrl = /^\/+(.*)$/.exec(url)) && (resLoc = /^(\w+:\/\/[^\/]*\/)/.exec(document.location.href)) ) {
      url = resLoc[1] + resUrl[1]; // handle url starting by '/'
    }

    if ( null != params && 'get' == method ) {
      var cgi = [];
      for ( var name in params ) {
        var value = params[name];
        if ( null == value || 'string' == typeof(value) ) value = [ value ];
        for ( var i = 0; i < value.length; i++ ) {
          if ( null != value[i] ) cgi.push( escape(name)+'='+escape(value[i]) );
        }
      }
      url += (url.match(/\?/) ? '&' : '?' )+cgi.join('&');
    }


    var xmlHttp = WDSS._createXMLHttpRequest();

    if ( !xmlHttp ) {
      //alert('Browser can not handle ajax ( could not create XMLHttp instance)');
      return false;
    }

    xmlHttp.onreadystatechange = function () {
      if ( xmlHttp.readyState == 4 ) {
	//if ( http_request.status != 200 ) alert('There was a problem with the ajax request.');
	//var text = xmlHttp.responseText;
	var root = xmlHttp.responseXML;
	if ( null != xmlHttp.responseXML ) root = xmlHttp.responseXML.firstChild;
	if ( null != root && 'xml' == root.nodeName ) root = root.nextSibling; // IE makes xml document type tag to document root; skip it!

	//if ( null != root && null == root.getElementById )
	//  root.getElementById = function (id) { return WDSS.getXmlElementById( this, id ); };
	// IE does not like to set: root.getElementById = function ...
	// so root is constructed as syntetic node
	if ( null != root ) root = new WDSS.xmlDoc(root);

	if ( null != callback ) callback( root, xmlHttp );
      }
    };

    try {  
      xmlHttp.open( method, url, true );
      if ( 'get' == method ) {
        xmlHttp.send( null );
      } else {
        //xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
        //xmlHttp.send(getFormElements(frm)); // getFormElements might be function(form){ str=''; foreach(form.elements)(str+=_.name+'='+_.value+'&')}
        //xmlHttp.send(null);
      }
    } catch(e) {
      if ( null != callback ) callback(null,xmlHttp);
      return false;
    }

    return true;
  };


  WDSS.parseXML = function ( xmlString, callback ) {
    var xmlDoc;
    if ( null != window.DOMParser ) {
      // code for Mozilla, Firefox, Opera, etc.
      var parser = new DOMParser();
      xmlDoc = parser.parseFromString( xmlString, 'text/xml' );
    } else {
      // code for IE
      var version = [ 'MSXML2.DOMDocument.5.0', 'MSXML2.DOMDocument.4.0',
		      'MSXML2.DOMDocument.3.0', 'MSXML.DOMDocument',
		      'Microsoft.XMLDOM',
		      ];
      xmlDoc = WDSS._newActiveXObject(version);
      xmlDoc.async = 'false';
      xmlDoc.loadXML( xmlString );
    }

    // documentElement always represents the root node
    var root = ( null == xmlDoc ) ? null : xmlDoc.documentElement;
    //var root = ( null == xmlDoc ) ? null : xmlDoc.firstChild;

    //if ( null != root && null == root.getElementById )
    //  root.getElementById = function (id) { return WDSS.getXmlElementById( root, id ); };
    // IE does not like to set: root.getElementById = function ...
    // so root is constructed as syntetic node
    if ( null != root ) root = new WDSS.xmlDoc(root);

    if ( null != callback ) callback( root, xmlDoc );

    return root;
  };


  WDSS._xmlQuote = function ( str ) {
    if ( null == str ) return '';
    str = str.replace(/&/g, '&amp;');
    str = str.replace(/</g, '&lt;');
    str = str.replace(/>/g, '&gt;');
    str = str.replace(/"/g, '&quot;');
    return str;
  };


  WDSS.xmlEncode = function ( node ) {
    if ( null == node ) return 'null';
    //if ( '#text' == node.nodeName ) return 'TEXT';
    var attrs = '';
    //attrs += ' nodeType="'+node.nodeType+'"';
    if ( null != node.attributes ) {
      for ( var i = 0; i < node.attributes.length; i++ ) {
        var a = node.attributes[i];
        attrs += ' '+a.nodeName+'="'+WDSS._xmlQuote(a.nodeValue)+'"';
      }
    }
    var childs = '';
    for ( var n = node.firstChild; n != null; n = n.nextSibling ) {
      childs += WDSS.xmlEncode(n);
    }
    if ( null != node.nodeValue ) {
      childs += ( '#cdata-section' == node.nodeName ) ? node.nodeValue : WDSS._xmlQuote(node.nodeValue);
    }
    if ( '#text'          == node.nodeName ) return childs;
    if ( '#comment'       == node.nodeName ) return '<!--'+childs+'-->';
    if ( '#cdata-section' == node.nodeName ) return '<![CDATA['+childs+']]>';
    var str = '<'+node.nodeName+attrs+'>'+childs+'</'+node.nodeName+'>';
    return str;
  };


  WDSS.importNodeIntoDocument = function ( node, doc ) {
    if ( null == doc ) doc = window.document;
    var dummy = doc.createElement( 'span' );
    dummy.innerHTML = WDSS.xmlEncode( node );
    return dummy.getElementsByTagName( node.nodeName )[0];
  };


  WDSS.replaceNodeChilds = function ( destNode, sourceNode ) {
    // store selection
    var selected = null;
    //alert( destNode.type );
    if ( 'select-multiple' == destNode.type || 'select-one' == destNode.type ) {
      selected = {};
      for ( var i = 0; i < destNode.options.length; i++ ) {
        if ( destNode.options[i].selected ) {
          var value = destNode.options[i].value;
          if ( null != value ) selected[value] = true;
          //alert( "value='"+value+"'");
        }
      }
    }

    if ( 1 ) {
      var oldLength = destNode.childNodes.length;
      var newLength = sourceNode.childNodes.length;
      var i;
      for ( i = 0; i < newLength; i++ ) {
        var newChild = sourceNode.removeChild(sourceNode.firstChild);
        if ( i < oldLength ) {
          destNode.replaceChild( newChild, destNode.childNodes[i]); 
        } else {
          destNode.appendChild( newChild );
        }
      }
      while ( i < oldLength ) { destNode.removeChild(destNode.childNodes[i]); i++ }
    } else {
      var clone = destNode.cloneNode( false );
      for ( var c = 0; c < sourceNode.childNodes.length; c++ )
        clone.appendChild( sourceNode.childNodes[c].cloneNode(true) );
      destNode.parentNode.replaceChild( clone, destNode );
    }

    // restore selection
    if ( null != selected ) {
      if ( 'select-one' == destNode.type ) destNode.selectedIndex = -1;
      for ( i = 0; i < destNode.options.length; i++ ) {
        var option = destNode.options[i];
        option.selected = selected[option.value] ? true : false;
      }
    }
  };


  WDSS._getDocumentOfFrame = function ( frame ) {
    var doc = frame.document;
    if ( !doc ) doc = frame.contentDocument; // MOZILLA
    if ( !doc ) alert( 'no doc = ' + doc );
    return doc;
  }


  WDSS.requestHttpDocument = function( url, args ) {
    var params = args.parameters;
    var target = args.target; 
    var method = args.method; if ( null != method ) method = args.method.match( /^get$/i ) ? 'get' : 'post';

    if ( null == method ) method = ( null == params ) ? 'get' : 'post';

    //alert('doHttpRequest(\''+url+'\',  \''+target+'\', \''+method+'\')');

    var doc;
    var frame;
    if ( null == target || '_blank' == target ) {
      frame = document.createElement('iframe');
      frame.style.border  = '0';
      frame.style.width   = '1px';
      frame.style.height  = '1px';
      //frame.style.display = 'none';
      document.getElementsByTagName('body')[0].appendChild(frame);
      var doc = WDSS._getDocumentOfFrame( frame );
      doc.open();
      doc.write('<html><head><title>wdss request frame</title></head><body></body></html>');
      doc.close();
      var callback = args.callback;
      if ( null != callback ) frame.onload = function () { var d = WDSS._getDocumentOfFrame( frame ); callback( d ); };
    } else if ( '_self' ) {
      doc = window.document;
      target = null;
      if ( null != callback ) alert( 'callback must be null when requesting new docuement for current frame' );
    }
    
    var body = doc.getElementsByTagName('body')[0];

    // create form with hidden parameter fields
    var form = doc.createElement('form');
    if ( null != url    ) form.setAttribute( 'action', url    );
    if ( null != target ) form.setAttribute( 'target', target );
    form.setAttribute( 'method',  method                );
    if ( 'post' == method ) form.setAttribute( 'enctype', 'multipart/form-data' );
    for ( var name in params ) {
      var value = params[name];
      if ( 'string' == typeof(value) ) value = [ value ];
      for ( var i = 0; i < value.length; i++ ) {
        var node = doc.createElement('input');
        node.setAttribute( 'type',  'hidden' );
        node.setAttribute( 'name',  name     );
        node.setAttribute( 'value', value[i] );
        form.appendChild(node);
      }
    }

    body.appendChild(form); 
    form.submit();
    if ( null != frame ) frame.style.display = 'none';
  };

};



// deprecated wrapper functions:
function wdss_getXmlElementById( node, id )   { WDSS.deprecated('wdss_getXmlElementById');  return WDSS.getXmlElementById( node, id );   }
function wdss_getXmlScriptCode( node )        { WDSS.deprecated('wdss_getXmlScriptCode');   return WDSS.getXmlScriptCode( node );        }
function wdss_parseXML( xmlString, callback ) { WDSS.deprecated('wdss_parseXML');           return WDSS.parseXML( xmlString, callback ); }
function wdss_xmlEncode(node)                 { WDSS.deprecated('wdss_xmlEncode');          return WDSS.xmlEncode( node );               }
function wdss_documentImportNode( node )      { WDSS.deprecated('wdss_documentImportNode'); return WDSS.importNodeIntoDocument( node );  }

function wdss_loadFile( url, callback, args )           { WDSS.deprecated('wdss_loadFile');          WDSS.requestXmlDocument( url, callback, args ); }
function wdss_replaceNodeChilds( destNode, sourceNode ) { WDSS.deprecated('wdss_replaceNodeChilds'); WDSS.replaceNodeChilds( destNode, sourceNode ); }

function wdss_requestFile( url, params )                { WDSS.deprecated('wdss_requestFile');       WDSS.requestHttpDocument( url, { parameters: params,
                                                                                                                                      target:     '_blank',
                                                                                                                                      method:     post
                                                                                                                                    } ); }

// compatibility to older code:
function _wdss_loadFile(url,callback,args) { WDSS.deprecated('_wdss_loadFile'); WDSS.requestXmlDocument(url,callback,args); }


// debug code may be removed in future versions
function __dumpOne (object) {
  if ( null == object ) return 'null';
  var str = typeof( object )+'\n';
  for ( var n in object ) {
    var v;
    try {
      v = object[n];
    } catch (e) {
      v = 'Error: '+e;
    }
    str += '\n'+n+': '+v;
  }
  return str;
}
