var g_rcAjax=new _rcAjax();
g_rcAjax._start();

function _rcAjax(){
  var _self=this;
  this._initialized=false;
  this._objXmlHttpRequest=null;
  this._queue=new Array();
  this._request=null;

  // Constructor
  this._start=function(){
    try{
        this._objXmlHttpRequest=new XMLHttpRequest();
    }
    catch( e ){
        try{
            this._objXmlHttpRequest=new ActiveXObject( 'Microsoft.XMLHTTP' );
        }
        catch( e ){
            this._objXmlHttpRequest=null;
        }
    }
    if( this._objXmlHttpRequest!=null ){
      this._initialized=true;
      this._processQueue();
    }
  }

  /*
  * Inicio de métodos
  */

  // envía un array de elementos al url especificado, la respuesta es asincrónica
  this.sendRequest=function( url, elements, callback ){
    if( !this._initialized ) return;

    var key, params='';
    for( key in elements ){
      var element=(elements[ key ] + '').escapeURL();
      
      if( params=='' )
        params=key + '=' + element;
      else
        params=params + '&' + key + '=' + element;
    }
    var request={ 'url': url, 'params': params, 'callback': callback, 'elements': elements };
    this._queue.push( request );
  }

  // procesa la cola
  this._processQueue=function(){
    if( !this._initialized ) return;
    
    var request=this._queue.shift();
    if( request==undefined ){
      setTimeout( function(){ _self._processQueue(); }, 200 );
    }
    else{
      this._request=request;
      this._objXmlHttpRequest.open( 'POST', request.url, true );
      this._objXmlHttpRequest.onreadystatechange=this._senderStatusChecker;
      this._objXmlHttpRequest.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
      this._objXmlHttpRequest.send( request.params );
    }
  }

  // recepciona respuesta asincrónica de sendRequest()
  this._senderStatusChecker=function(){
    if( !_self._initialized ) return;

    if( _self._objXmlHttpRequest.readyState==4 ){
      if( _self._request!=null ){
        var e;
        try{
          // status 200 es OK
          _self._request.callback(
                                  _self._objXmlHttpRequest.status,
                                  _self._objXmlHttpRequest.responseText,
                                  _self._objXmlHttpRequest.responseXML,
                                  _self._request
                                 );
        }
        catch( e ){ alert( '_senderStatusChecker: ' + e ); }
        _self._request=null;
      }
      _self._objXmlHttpRequest.onreadystatechange=new Function; //IE memory leak
      setTimeout( function(){ _self._processQueue(); }, 200 );
    }
  }

}