/**
 *  object to execute AJAX requests
 *  
 *  @author   Tobias Hettinger
 *  @version  $Id: ajax.js 121 2011-09-15 13:20:37Z tobias $
 */


/**
 *  constructor of the ajax manager
 *  
 *  @param string url  url of the script that is called when an AJAX request is to be performed
 */
var WATAjax = function(url)
{
  //  set the properties
  this.method = 'post'; 
  this.url = url;
  
  //  member objects
  this.xmlHttpRequest = null;  
  this.onResponseXML = null;
  this.onResponseText = null;
  this.onStartRequest = null;
  this.onRequestWait = null;
  this.onFinishRequest = null;
  this.onFinishRequestOnce = null;
  this.onSuccess = null;
  this.onSuccessOnce = null;
  this.onError = null;  
  
  //  debugging
  this.enableDebug = false;  
  var location = window.location.toString();
  if (location.match(/http:\/\/dev/i) || location.match(/http:\/\/test/i)) this.enableDebug = true;
}

/**
 *  function to create the xmlHttpRequest object
 */
WATAjax.prototype.Create = function()
{
  //  try to instantiate a new XMLHttpRequest object
  try
  {
    //  try to load the native XMLHttpRequest object
    if (window.XMLHttpRequest)
      this.xmlHttpRequest = new XMLHttpRequest();
    else
    {
      //  the Microsoft Internet Explorer has to load the XMLHttpRequester
      //  as an ActiveXObject. Note that this will not work if the execution
      //  of ActiveXObjects is disabled
      if (window.ActiveXObject)
      {
        for (var i=5; i>=3; i--)
        {
          //  try to load the newest version of the XMLHttpRequest object first
          try
          {
            this.xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP." + i + ".0");
            break;
          }
          catch (excNotLoadable)
          {
            this.xmlHttpRequest = null;
          }
        }
      }
    }
  }
  catch (excNotLoadable)
  {
    this.xmlHttpRequest = null;
    if (obj.onError) obj.onError(obj, -1);
  }
}

/**
 *  function to check if the class is ready for an ajax request
 *  
 *  @return bool  the function returns true if an AJAX request can be performed or false if no request is possible
 */
WATAjax.prototype.IsReady = function()
{
  return (this.xmlHttpRequest == null || this.xmlHttpRequest.readyState == 4) ? true : false;
}

/**
 *  function to perform an AJAX request
 *  
 *  @param string data  parameter string for the AJAX request
 *  
 *  @return bool  the function returns true if the request was sent or false in case of an error
 */
WATAjax.prototype.Request = function(data)
{
  var obj = this;
  
  //  the request is not possible if no url is specified
  if (!this.url)
  {
    //  show an error message if the class is in debug mode
    if (this.enableDebug) alert('no url specified for the ajax request\n\n' + data);
    return false;
  }

  //  event handler of the xmlHttpRequest status change event
  function __OnReadyStateChange()
  {
    //  check if the request was finished
    if (obj.xmlHttpRequest.readyState == 4)
    {
      //  evaluate the status code
      switch (obj.xmlHttpRequest.status)
      {
        //  the request succeeded
        case 200 :
          var ajaxResponse = null;
          if (obj.xmlHttpRequest.responseXML) ajaxResponse = obj.xmlHttpRequest.responseXML.documentElement;
          if (ajaxResponse && ajaxResponse.nodeName.toLowerCase() != 'parsererror')
          {
            //  an XML response has been received
            if (obj.onResponseXML) obj.onResponseXML(obj, ajaxResponse);
      
            //  the AJAX request succeeded
            WAT.HideMessage(1, window.location.hostname);
            WAT.HideMessage(2, obj.url);
            
            //  send an onSuccess event
            if (obj.onSuccess) obj.onSuccess(obj);
            if (obj.onSuccessOnce) obj.onSuccessOnce(obj);
            obj.onSuccessOnce = null;            
          }
          else
          {
            //  a text has been received 
            if (obj.onResponseText) obj.onResponseText(obj, obj.xmlHttpRequest.responseText);
            
            //  the request did not succeed because all WAT requests expect an XML response
            if (obj.onError) obj.onError(obj, obj.xmlHttpRequest.status);            
            
            //  'Internet Explorer liefert Status 200 und ein leeres Ergebnis zurück wenn der Server nicht
            //   erreichbar ist. Andere Browser liefern Status 0 zurück' 
            if (obj.xmlHttpRequest.responseText.length == 0)
              WAT.ShowMessage(1, window.location.hostname, watAjaxStr['no_response']);
            else
              //  show the text but only if the class is in debug mode. In production
              //  environments, a text result is an invalid response
              if (obj.enableDebug)
              {
                var message = obj.xmlHttpRequest.responseText;
                message = message.replace(/</gi, '&lt;');
                message = message.replace(/>/gi, '&gt;');
                message = message.replace(/\n/gi, '<br>');
                WAT.ShowMessage(3, null, message);
              }
          }
          break;
          
        //  the document was not found
        case 404 :
          //  the request did not succeed
          if (obj.onError) obj.onError(obj, obj.xmlHttpRequest.status); 
          //  show an error
          WAT.ShowMessage(2, obj.url, watAjaxStr['not_found'] + (obj.enableDebug ? (': ' + obj.url) : ''));        
          break;
          
        //  the server does not react
        case 0 :
          //  the request did not succeed
          if (obj.onError) obj.onError(obj, obj.xmlHttpRequest.status);          
          //  show a message
          WAT.ShowMessage(1, window.location.hostname, watAjaxStr['no_response']); 
          break;
          
        //  default error
        default :
          //  the request did not succeed
          if (obj.onError) obj.onError(obj, obj.xmlHttpRequest.status);
          //  show an error
          WAT.ShowMessage(1, window.location.hostname, watAjaxStr['no_response'] +
                         (obj.enableDebug ? (': ' + obj.url + ', status: ' + obj.xmlHttpRequest.status) : ''));       
          break;
      }
      
      //  send a finish request event
      if (obj.onFinishRequest) obj.onFinishRequest(obj);
      if (obj.onFinishRequestOnce) obj.onFinishRequestOnce(obj);
      obj.onFinishRequestOnce = null;
    }
  }
  
  //  function to trigger a wait event if the request could not be finished within a certain period of time
  function __OnRequestWait()
  {
    //  trigger a requestWait event if the request is not finished yet
    if (obj.xmlHttpRequest.readyState != 4)
      if (obj.onRequestWait) obj.onRequestWait(obj);
  }
  
  //  prepare the query string
  data = data.replace(/&amp;/g, '&');
  if (this.method != 'head' && (data && (data.substr(0,1)=='&' || data.substr(0,1)=='?')))
    data = data.substr(1, data.length);
  if (data) data += '&ax=1'; else data = 'ax=1';

  //  create the request class if it does not yet exist
  if (this.xmlHttpRequest == null) this.Create();
  if (this.xmlHttpRequest)
  {  
    switch(this.method)
    {
      //  XML
      case 'xml' :
        //  open the connection
        var sourceFile = this.url + (data ? '?' + data : '');
        this.xmlHttpRequest.open('GET', sourceFile, true);
        this.xmlHttpRequest.setRequestHeader('Content-Type', 'text/xml');
        data = null;
        break;
        
      //  POST
      case 'post' :
        //  open the connection
        this.xmlHttpRequest.open('POST', this.url, true);
        this.xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        this.xmlHttpRequest.setRequestHeader('Content-Length', data.length);
        break;
        
      //  HEAD
      case 'head' :
        //  open the connection
        this.xmlHttpRequest.open('HEAD', this.url, true);
        data = null;
        break;
        
      //  GET
      default :
        //  open the connection
        var sourceFile = this.url + (data ? '?' + data : '');
      this.xmlHttpRequest.open('GET', sourceFile, true);
        data = null;
        break;
    }
    
    //  set the data event handler
    this.xmlHttpRequest.onreadystatechange = __OnReadyStateChange;
    //  send the data of the request
    this.xmlHttpRequest.send(data);
    //  send a startRequest event
    if (this.onStartRequest) this.onStartRequest(this);
    //  trigger a wait event if the request could not be finished within a certain period of time
    setTimeout(__OnRequestWait, 500);
    return true;
  }
  
  //  there must have been an error
  return false;
}

//  the file must be included in the head section of the document, do not call the ScriptIncluded function

