//
// JavaScript code for the management of Ajax calls, for the OrdinaSoft library.
//
// Author:  OrdinaSoft
//          Patrick Lanz
//          Lausanne
//          info@ordinasoft.ch
//
// First version: May 10, 2007
//
// (c) 2007, OrdinaSoft, all rights reserved

//-----------------------------------------------------------------------------------------------
// Namespace initialization.

if (typeof OrdinaSoft == 'undefined')
  OrdinaSoft = new Object ();
if (typeof OrdinaSoft.Ajax == 'undefined') {
  OrdinaSoft.Ajax = new Object ();
  OrdinaSoft.Ajax._RequestList = [];
}  // typeof OrdinaSoft.Ajax == 'undefined'

//-----------------------------------------------------------------------------------------------
// Request class.

// Creates an Ajax request, without sending it.
//  - URL is the URL of the request.

OrdinaSoft.Ajax.Request = function (URL) {

  this.Init (URL);

  this.NoAjaxSupportFunc = function () {
      alert ('Ajax not available!');
      return true;
    };

  this.SuccessFunc = function (Request) {
      alert (Request.Req.responseText);
      return true;
    };

  this.ErrorFunc = function (StatusCode) {
      alert ('Ajax error ' + StatusCode.toString ()) + '!';
      return true;
    };

  return true;
} // OrdinaSoft.Ajax.Request



// Initialization of the request.
//  - URL is the URL of the request.

OrdinaSoft.Ajax.Request.prototype.Init = function (URL) {

  this.URL = URL;
  this.PostParams = '';
  return true;
} // OrdinaSoft.Ajax.prototype.Init



// Adds a POST parameter to the request.
//  - Name is the name of the parameter.
//  - Value is the value of the parameter.

OrdinaSoft.Ajax.Request.prototype.AddPostParam = function (Name, Value) {

  if (this.PostParams != '')
    this.PostParams = this.PostParams + '&';
  this.PostParams = this.PostParams + Name + '=' + encodeURIComponent (Value);
  return true;
} // OrdinaSoft.Ajax.Request.prototype.AddPostParam



// Makes an asynchronous Ajax call. When the call is finished, the SuccessFunc function will be
// called in case of success, in case of error, the ErrorFunc function will be called.
//  - The result will be true if the call has been made and false otherwise.

OrdinaSoft.Ajax.Request.prototype.AsyncCall = function () {

  if (OrdinaSoft.Ajax.FirstRequest () == 0)
    OrdinaSoft.Ajax.FirstRequest ();
  this.ID = OrdinaSoft.Ajax._RequestList.length;
  OrdinaSoft.Ajax._RequestList [OrdinaSoft.Ajax._RequestList.length] = this;

  // Get the requester
  this.Req = OrdinaSoft.Ajax.GetRequester ();
  if (this.Req == null) {
    this.NoAjaxSupportFunc ();
    return false;
  } // this.Req == null

  // Initializes the requester
  try {
    this.Req.open ((this.PostParams == '') ? 'GET' : 'POST', this.URL, true);
    if (this.PostParams != '') {
      this.Req.setRequestHeader ('Content-Length', this.PostParams.length.toString ());
      this.Req.setRequestHeader ('Content-Type',
                                 'application/x-www-form-urlencoded; charset=UTF-8');
    } // we have post parameters
  }
  catch (e) {return false;}

  // Define the status change function
  var Obj = this;
  this.Req.onreadystatechange = function () {
      if (Obj.Req.readyState == 4) {  // request completed
        try {
          var Status = Obj.Req.status;
          if ((Status == 200) || (Status == 304))  // request successful
            Obj.SuccessFunc (Obj);
          else Obj.ErrorFunc (Status);
        }
        finally {
          OrdinaSoft.Ajax._RequestList [Obj.ID] = null;
          if (OrdinaSoft.Ajax.GetNbActiveCalls () == 0)
            OrdinaSoft.Ajax.LastRequest ();
          Obj.RequestCompleted ();
          Obj.Req = null;
        }
      }  // this.Req.readyState == 4
    } // this.Req.onreadystatechange

  // Makes the call
  this.Req.send (this.PostParams == '' ? null : this.PostParams);
  return true;

} // OrdinaSoft.Ajax.prototype.AsyncCall



// Called when the Ajax request has completed.

OrdinaSoft.Ajax.Request.prototype.RequestCompleted = function () {

  return true;
} // OrdinaSoft.Ajax.Request.prototype.RequestCompleted

//-----------------------------------------------------------------------------------------------
// Reading XML content.

// Returns the text inside the specified XML element.
//  - Elmt is the XML element to process.

OrdinaSoft.Ajax.GetXmlText = function (Elmt) {

  try {
    return Elmt.firstChild.nodeValue;
  }
  catch (e) {}
  return '';
} // OrdinaSoft.Ajax.GetXmlText



// Returns the integer value inside the specified XML element.
//  - Elmt is the XML element to process.

OrdinaSoft.Ajax.GetXmlInt = function (Elmt) {

  try {
    Elmt = OrdinaSoft.Ajax.GetXmlText (Elmt);
    return (Elmt == null) ? 0 : parseInt (Elmt, 10);
  }
  catch (e) {}
  return 0;
} // OrdinaSoft.Ajax.GetXmlText



// Returns the text inside the specified attribute of the specified XML element.
//  - Elmt is the XML element to process.
//  - AttrName is the name of the attribute.

OrdinaSoft.Ajax.GetXmlAttrText = function (Elmt, AttrName) {

  Elmt = Elmt.attributes;
  if (Elmt == null)
    return '';
  Elmt = Elmt.getNamedItem (AttrName);
  return (Elmt == null) ? '' : Elmt.value;
} // OrdinaSoft.Ajax.GetXmlAttrText



// Returns the integer value inside the specified attribute of the specified XML element.
//  - Elmt is the XML element to process.
//  - AttrName is the name of the attribute.

OrdinaSoft.Ajax.GetXmlAttrInt = function (Elmt, AttrName) {
  Elmt = OrdinaSoft.Ajax.GetXmlAttrText (Elmt, AttrName);
  return (Elmt == '') ? 0 : parseInt (Elmt, 10);
} // OrdinaSoft.Ajax.GetXmlAttrInt

//-----------------------------------------------------------------------------------------------
// Tools.

// Gets the number of active Ajax calls.

OrdinaSoft.Ajax.GetNbActiveCalls = function () {

  var Nb = 0;
  for (var i = 0; i < OrdinaSoft.Ajax._RequestList.length; i++)
    if (OrdinaSoft.Ajax._RequestList [i] != null)
      Nb++;
  return Nb;
} // OrdinaSoft.Ajax.GetNbActiveCalls



// Called when we have the first Ajax call in a raw.

OrdinaSoft.Ajax.FirstRequest = function () {

  return true;
} // OrdinaSoft.Ajax.FirstRequest



// Called when we have the last Ajax call in a raw.

OrdinaSoft.Ajax.LastRequest = function () {

  return true;
} // OrdinaSoft.Ajax.LastRequest



// Returns a requester that can be used to make Ajax calls. If no requester can be created, the
// result will be null.

OrdinaSoft.Ajax.GetRequester = function () {

  // Native request
  try {
    return new XMLHttpRequest ();
  }
  catch (e) {}

  // Internet Explorer
  try {
    return new ActiveXObject ('Microsoft.XMLHTTP');
  }
  catch (e) {}

  // Error case
  return null;

} // OrdinaSoft.Ajax.GetRequester

//-----------------------------------------------------------------------------------------------

OrdinaSoft_Ajax_Initialized = true;  // indicates that the library is initialized
