var xmlHttp = false;

// constants
var REQUEST_GET   = 0;
var REQUEST_POST  = 1;
var REQUEST_HEAD  = 2;

/**
 * sends a http request to server
 * @param strSource, String, datasource on server, e.g. data.php
 * @param strData, String, data to send to server, optionally
 * @param intType, Integer,request type, possible values: REQUEST_GET, REQUEST_POST, REQUEST_HEAD default REQUEST_GET
 * @param intID, Integer, ID of this request, will be given to registered event handler onreadystatechange, optionally
 *
 * @return String, request data or data source
 */
function sendRequest( strSource, strData, intType, intID ) {
  if( !strData ) strData = '';
// default type (0 = GET, 1 = POST )
  if( isNaN( intType ) ) intType = 0; // GET
// previous request not finished yet, abort it before sending a new request
  if( xmlHttp && xmlHttp.readyState ) {
    xmlHttp.abort( );
    xmlHttp = false;
  }        
// create a new instance of xmlhttprequest object
// if it fails, return
  if( !xmlHttp ) {
    xmlHttp = getXMLRequester( );
    if( !xmlHttp ) return;
  }
// parse query string
  if( intType != 1 && ( strData && strData.substr( 0, 1 ) == '&' || strData.substr( 0, 1 ) == '?' ) ) strData = strData.substring( 1, strData.length );
// data to send using POST
  var dataReturn = strData ? strData : strSource;
  switch( intType ) {
    case 1: // POST
//  alert("intType1");
// open the connection 
      xmlHttp.open( "POST", strSource, true );
      xmlHttp.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
      xmlHttp.setRequestHeader( 'Content-length', strData.length );
      break;
    case 2: // HEAD
//  alert("intType2");
// open the connection 
      xmlHttp.open( "HEAD", strSource, true );
      strData = null;
      break;
    default: // GET
//  alert("intType3");
// open the connection 
      var strDataFile = strSource + (strData ? '?' + strData : '' );
//alert("1");
//alert("url="+strDataFile);
      xmlHttp.open( "GET", strDataFile, true );
      strData = null;
  }
//alert("2");
// set onload data event-handler
  xmlHttp.onreadystatechange = new Function( "", "processResponse(" + intID + ", '" + strSource + "')" );
// send request to server
  xmlHttp.send( strData );    // param = POST data
//  alert("2222");
  return dataReturn;
}

/**
 * instantiates a new xmlhttprequest object
 *
 * @return xmlhttprequest object or false
 */
function getXMLRequester( ) {
  xmlHttp = false;
  try {
// Internet Explorer
    if( window.ActiveXObject )  {
      for( var i = 5; i; i-- ) {
        try {
// loading of a newer version of msxml dll (msxml3 - msxml5) failed
// use fallback solution
// old style msxml version independent, deprecated
          if( i == 2 ) {
            xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP" );    
          } else {
// try to use the latest msxml dll                      
            xmlHttp = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" );
          }
          break;
        } catch( excNotLoadable ) {                        
          xmlHttp = false;
        }
      }
    } else if( window.XMLHttpRequest ) {
// Mozilla, Opera und Safari
      xmlHttp = new XMLHttpRequest();
    }
  } catch( excNotLoadable ) {
// loading of xmlhttp object failed
    xmlHttp = false;
  }
  return xmlHttp ;
}

/**
 * process the response data from server
 *
 * @param intID, Integer, ID of this response
 */
function processResponse( intID, strSource ) {
// status 0 UNINITIALIZED open() has not been called yet.
// status 1 LOADING send() has not been called yet.
// status 2 LOADED send() has been called, headers and status are available.
// status 3 INTERACTIVE Downloading, responseText holds the partial data.
// status 4 COMPLETED Finished with all operations.
  switch( xmlHttp.readyState ) {
    case 0: // uninitialized
    case 1: // loading      
    case 2: // loaded
    case 3: // interactive
      break;
    case 4: // complete    
// check http status
      if( xmlHttp.status == 200 ) {    // success
        processData( xmlHttp, intID );
      } else {
// loading not successfull, e.g. page not available
        if( window.handleAJAXError )  handleAJAXError( xmlHttp, intID, strSource );
        else alert( " AJAX-ERROR\n HTTP status = " + xmlHttp.status + "\n " + xmlHttp.statusText + "\n " + strSource) ;
      }
  }
}

// process data from server
function processData( xmlHttp, intID, strSource ) {
// process text data
  updatePage(xmlHttp );
}

// handle response errors
function handleAJAXError( xmlHttp, intID, strSource ) {
  alert(" AJAX-ERROR\n HTTP status = " + xmlHttp.status + "\n " + xmlHttp.statusText + "\n " + strSource );
}