/* Cette notice ne doit en aucun cas être modifiée ou effacée

JS Remote Scripting - Librairie Client v. 0.1b
La dernière version est disponible sur :
http://ns3686.ovh.net/~nwn/JSRS/

Copyright (c) 2005-2006 Blaise de Carné - Tous droits réservés
Dernière modification : 06. 06. 2005

//DESCRIPTION

LICENSE: LGPL

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

For more details on the GNU Lesser General Public License,
see http://www.gnu.org/copyleft/lesser.html
*/


/* ---------- CLASSE : JSRSSerializer ---------- 
For more details on the GNU Lesser General Public License,
see http://www.gnu.org/copyleft/lesser.html
*/

/* ----------------
* Constructeur
*/
function JSRSSerializer() { }

/* ----------------
* serialize_data
*/
JSRSSerializer.prototype.serialize_data = function(data, force_type) 
{
  var type = (typeof data);
  if(force_type) 
    type = force_type;
  switch(type)
  {
    case "object":
            if( data == null )
              return this.serialize_data(data,"null");
            else if( data.constructor == Array )
        return this.serialize_data(data,"array");
      else
        return this.serialize_object(data);
    break;
    // ---
    case "string": return this.serialize_string(data); break;
    // ---
    case "array": return this.serialize_array(data); break;
    // ---
    case "null": return "N;";  break;
    // ---
  }
  return false;
};

/* ----------------
* serialize_string
*/
JSRSSerializer.prototype.serialize_string = function(data) 
{
  data = "s:" + data.length + ":\"" + data + "\";";
  return data;
};

/* ----------------
* serialize_string
*/
JSRSSerializer.prototype.serialize_array = function(data) 
{
  var string = "a:" + data.length + ":{";
  for(i=0; i<data.length;i++)
    string += "i:" + i + ";" + this.serialize_data(data[i]);
  string += "}";  
  return string;
};

/* ----------------
* serialize_object
*/
JSRSSerializer.prototype.serialize_object = function(data) 
{
  var nbProp = 0; 
  for(var i in data) 
    nbProp++;
  var string = "O:8:\"stdClass\":" + nbProp + ":{";
  for(var i in data)
    string += this.serialize_data(i) + this.serialize_data(data[i]);
  string += "}";  
  return string;
};


/* ---------- CLASSE : JSRSClient ---------- 
For more details on the GNU Lesser General Public License,
see http://www.gnu.org/copyleft/lesser.html
*/

/* ----------------
*    Constructeur
*/
function JSRSClient(server, method, debug) 
{
  if(!method) method    = "POST";
    this.server       = server;
  this.method       = method;
  this.debug        = debug;
  this.XHR        = this.create_xhr_object();
  if(!this.XHR) 
    return false;
  return true;
}

/* ----------------
* init_xhr_object
* initialise l'objet XMLHTTP
*/
JSRSClient.prototype.create_xhr_object = function() 
{ 
  if(window.XMLHttpRequest) // Firefox 
    return new XMLHttpRequest(); 
  else if(window.ActiveXObject) // Internet Explorer 
    return new ActiveXObject("Microsoft.XMLHTTP"); 
  else { 
    this.error("Votre navigateur ne supporte pas les objets XMLHTTPRequest"); 
    return false; 
  } 
};

/* ----------------
*    call
*/
JSRSClient.prototype.call = function(fonction, params, callback, asynchrone) 
{ 
  if(!params)   params    = new Array();
    if(!callback)   callback  = null;
  if(!asynchrone) asynchrone = false;
  
  if(!this.XHR) return false;
  if(this.XHR.readyState > 0 && this.XHR.readyState < 4)
    this.XHR.readyState.abort();
  
  var url_to_call = this.server;
  var data_to_send = this.make_arguments(fonction, params);
  
  if(this.method == "GET" ) 
  { 
    url_to_call += (url_to_call.indexOf("?")<0 ? "?" : "&") + data_to_send; 
    data_to_send = null; 
  } 
  
  this.XHR.open(this.method, url_to_call, asynchrone); 

  if(asynchrone) 
    this.XHR.onreadystatechange = function() { this.response(callback); return true; } 
  
  if(this.method == "POST") 
    this.XHR.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 

  try {
    this.XHR.send(data_to_send);
  }
  catch(err) {
//    alert("Fel på sidan!\nFel: "+err.description);
  }   

  if(!asynchrone) 
    return this.response(callback); 
};

/* ----------------
*  response
*  Intercepte la réponse du serveur
*/
JSRSClient.prototype.response = function(callback_fct) 
{
  if(typeof callback_fct == "string") 
      eval("var callback_fct = " + callback_fct);
  var jsrs_object = this;
  var final_callback = function() {
    try {
      eval("var _r = " + unescape(jsrs_object.XHR.responseText)); 
      if(callback_fct) 
        callback_fct(_r); 
      return _r; 
    } 
    catch(e) { return jsrs_object.error(jsrs_object.XHR.responseText); }
  }
  if(this.XHR.readyState == 4)
    return final_callback();
  return false;
};

/* ----------------
*  make_arguments
*/
JSRSClient.prototype.make_arguments = function(function_name, params) 
{
  params_array = new Array();
  for(i=0; i<params.length; i++)
    params_array.push(params[i]);
    
  PARAMS = new Object();
  PARAMS["function"] = function_name;
  PARAMS["args"] = params_array;
  
  var serializer = new JSRSSerializer();
  var args = "_JSRS=" + escape(serializer.serialize_data(PARAMS));
  return args;
};

/* ----------------
* define
* A FAIRE
* Défini une function Javascript pour l'appel d'une fonction distante
*/
JSRSClient.prototype.define = function(function_name, function_to_call, callback, asynchrone) 
{
  if(!callback)   callback  = null;
  if(!asynchrone) asynchrone = false;
  if(!function_to_call) function_to_call = function_name;
  var _obj = this;
  var _f = function() { return _obj.call(function_to_call,arguments,callback,asynchrone); }
  eval( function_name + " = _f; ");
  return true;
};


/* ----------------
*    error
*/
JSRSClient.prototype.error = function(msg) 
{
  if(this.debug) alert("Erreur JSRS : \n" + msg);
  return false;
};


