///////////////////////////////////////////////////////////////////
//
// XML Interface
//
////////////////////////////////////////////////////////////////////

function HttpXMLRequest( successHandler, timeoutHandler )
{
  var self = this ;
  var success_handler = successHandler ;
  var timeout_handler = timeoutHandler ;
  var timer = null ;
  var req = null ;
  var reqData = null ;
  var status = 0 ;
  var readyState = 0 ;
  
  if ( window.XMLHttpRequest ) {
    try {
      request = new XMLHttpRequest();
    } 
    catch(e) {
      request = null ;
    }
    // branch for IE/Windows ActiveX version
  } 
  else if ( window.ActiveXObject ) {
    try {
      request = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e) {
      try {
        request = new ActiveXObject("Microsoft.XMLHTTP");
      } 
      catch(e) {
        request = null ;
      }
    }
  }
  req = request ;

  this.responseText = function()
  {
     return request.responseText ;
  } ;
   
  this.abort = function() 
  {
    req.abort() ;
    self.clearTimer() ;
    self.readyState = 0 ;
  } ;

  this.getStatus = function()
  {
    return self.status ;
  }

  this.getReadyState = function()
  {
    return self.readyState ;
  }

  this.setTimer = function( ms )
  {
     timer = window.setTimeout( self.timeout, ms ) ;
  } ;

  this.clearTimer = function( ms )
  {
    if ( timer != null ) {
      window.clearTimeout( timer ) ;
      timer = null ;
    }
  } ;

  this.timeout = function()
  {
    self.abort() ;
    if ( timeout_handler != "" ) {
      eval( timeout_handler + '()' );
    }
  } ;

   this.change = function() 
   {
     self.readyState = req.readyState ;

     if ( req.readyState == 4 ) {

       //alert ( "STATUS = "+req.status ) ;

       self.clearTimer() ;
       self.status = req.status ;
       self.readyState = 0 ;

       if ( req.status == 200 ) {

         //alert ( req.responseText ) ;  

         if ( success_handler != "" ) {
           eval( success_handler + '( req )' );
         }

       }	
     }
  };

  this.loadXMLDocAsync = function( verb,url,data,ms )
  {
    if ( ms != 0 ) this.setTimer ( ms ) ;

    var url_rand = url + ((url.indexOf("?") == -1) ? "?" : "&" ) + 
    	"rand=" + parseInt(Math.random()*99999999);

    req.open(verb, url_rand, true);

    req.onreadystatechange = self.change ;

    if ( verb == "POST" ) req.setRequestHeader("Content-Type", "text/xml") ;
    req.setRequestHeader ( "Pragma", "no-cache" ) ;
    req.setRequestHeader ( "Cache-Control", "no-cache" ) ;

    self.reqData = data ;
    self.readyState = 0 ;
    self.status = 0 ;

    req.send( self.reqData ) ;

  } ;

  this.loadXMLDocSync = function ( verb,url,data,ms )
  {
    if ( ms != 0 ) this.setTimer ( ms ) ;

    var url_rand = url + ((url.indexOf("?") == -1) ? "?" : "&" ) + 
	"rand=" + parseInt(Math.random()*99999999);

    req.open( verb, url_rand, false );

    if ( verb == "POST" ) req.setRequestHeader("Content-Type", "text/xml") ;
    req.setRequestHeader ( "Pragma", "no-cache" ) ;
    req.setRequestHeader ( "Cache-Control", "no-cache" ) ;

    self.reqData = data ;
    req.send( self.reqData ) ;

    self.change() ;
  } ;

  return ;
}

// retrieve text of an XML document element, including
// elements using namespaces
function getElementTextNS(prefix, local, parentElem, index) 
{
  var result = "";
  if (prefix && isIE) {
    // IE/Windows way of handling namespaces
    result = parentElem.getElementsByTagName(prefix + ":" + local)[index];
  } 
  else {
    // the namespace versions of this method 
    // (getElementsByTagNameNS()) operate
    // differently in Safari and Mozilla, but both
    // return value with just local name, provided 
    // there aren't conflicts with non-namespace element
    // names
    result = parentElem.getElementsByTagName(local)[index];
  }
  if (result) {
    // get text, accounting for possible
    // whitespace (carriage return) text nodes 
    if (result.childNodes.length > 1) {
      return result.childNodes[1].nodeValue;
    } 
    else {
      return result.firstChild.nodeValue;    		
    }
  }
  else {
    return "n/a";
  }
}
