var HTTP_STATUS_OK = 200;
var READYSTATE_COMPLETED = 4;
var NODE_TYPE_ELEMENT = 1;


/**
 * Cette class sert comme "workaround" pour le mauvais
 * support de Javascript pour les arrays par association.
 **/
function _RCHashtable()
{
   this.data = new Object();
   this.keys = new Array();
}


function _RCHashtable_getKey(raw)
{
   return '__'+ raw +'__';
}


function _RCHashtable_get(nam)
{
   var key = this.getKey(nam);
   var val = (this.data[key]) ? this.data[key] : null;
   return val;
}


function _RCHashtable_put(nam, val)
{
   if (!nam) return false;
   
   var key = this.getKey(nam);
   
   var exists = true;
   if (!this.data[key])
   {
      exists = false;
      this.keys[this.keys.length] = key;
   }
   
   var oldval = exists ? this.data[key] : null;
   
   this.data[key] = val;
    
   return oldval;
}


function _RCHashtable_keys()
{
   return keys.slice(0);
}


function _RCHashtable_containsKey(nam)
{
   return (this.get(nam) != null);
}

_RCHashtable.prototype.getKey = _RCHashtable_getKey;
_RCHashtable.prototype.get = _RCHashtable_get;
_RCHashtable.prototype.put = _RCHashtable_put;
_RCHashtable.prototype.keys = _RCHashtable_keys;
_RCHashtable.prototype.containsKey = _RCHashtable_containsKey;





/**
 * Cette class s'occupe des appel HTTP à partir de la composante XMLHttpRequest
 */
function RemoteConnection(recurseOnChildren)
{
   this.aRequests = new Array();
   this.aRequests[0] = null;

   this.hRespHandlers = new _RCHashtable();

   this.isWildcardSet = false;

   this.recurseOnChildren = recurseOnChildren ? true : false;
   
    
   this.request = function(url, method, requestxml)
      {
         if (!method) method = "GET";
         if (!requestxml) requestxml = null;
         
         var req = null;
         
         var openIndex = this.aRequests.length;

         for (var i=0; i<this.aRequests.length; i++)
         {
            if (this.aRequests[i] == null)
            {
               openIndex = i;
               break;
            }
         }
         
         if (window.XMLHttpRequest)
         {
            var self = this;
            req = new XMLHttpRequest();
            req.onreadystatechange = 
               function() {self.handle()};

            this.aRequests[openIndex] = req;
            req.open(method, url, true);
            req.send(requestxml);
         }
         else if (window.ActiveXObject)
         {
            req = new ActiveXObject("Microsoft.XMLHTTP");
            if (req)
            {
               var self = this;
               req.onreadystatechange = 
                  function() {self.handle()};

               this.aRequests[openIndex] = req;
               req.open(method, url, true);
               req.send(requestxml);
            }
            else
            {
                return false;
            }
         }
         else
         {
            return false;
         }
            
         return true;
      };
    
    
   this.handle = function()
      {
         for (var i=0; i<this.aRequests.length; i++)
         {
            if (this.aRequests[i] != null 
               && this.aRequests[i].readyState ==
                  READYSTATE_COMPLETED)
            {
               if (this.aRequests[i].status == 
                  HTTP_STATUS_OK)
               {
                  this.parseResponse(
                     this.aRequests[i].responseXML);
                  this.aRequests[i] = null;
               }
            }
         }
      };
    
    
   this.setRespHandler = 
      function(sElementName, funcHandler)
      {
         if (sElementName == '*')
            this.isWildcardSet = true;
         return this.hRespHandlers.put(
            sElementName, funcHandler);
      };
    
    
   this.parseResponse = function(oNode)
      {
         if (!oNode) return;
         if (!oNode.hasChildNodes()) return;
         
         var children = oNode.childNodes;
         
         for (var i=0; i<children.length; i++)
         {
             if (children[i].nodeType == 
                NODE_TYPE_ELEMENT)
             {
                var elementName = children[i].nodeName;
                if ( this.hRespHandlers.containsKey(
                   elementName) )
                {
                   var funcHandler = 
                     this.hRespHandlers.get(elementName);
                   funcHandler(children[i]);
                           
                   if (this.recurseOnChildren) 
                      this.parseResponse(children[i]);
                }
                else if (this.isWildcardSet)
                {
                   var funcHandler = 
                      this.hRespHandlers.get('*');
                   funcHandler(children[i]);
                   
                   if (this.recurseOnChildren) 
                      this.parseResponse(children[i]);
                }
                else
                {
                   this.parseResponse(children[i]);
                }
                
             }
         }
      };
}