/* ------------[LAST UPDATE 2005/02/24 22:51]--------------------
   Remote Scripting library using javascript only.
   Replacement for xmlhttp, which doesn't like NT4.
   I don't like NT4 for that, but hey, a lot of people
   still (have to) use it. No iframes, no MsJava.
   You'll need a ASP/CGI/any server side program
   returning javascript, the last statement being
   the return function. 
   Tested in Firefox 1.0/IE/Opera (7.5, 8 beta). All 
   working. 
   
   You may use this code as you need it, but do leave 
   the authors name somewhere in it please. Thanks.
   (c) 2005-3010 Renzo Kooi/NICon
   -------------------------------------------------------------*/
RSL          = RSL;
gbAppend     = false;
defStat      = RSL_setStat;

remoteApp    = '';

//** set allowHTML to true if you want to use HTML
allowHTML    = false;

//** set noStatChange to true if you don't want to allow
//   changing the status bar
noStatChange = false;

/*? goRS is the default RS-object
    you can rename this, but always return the result in 
    this object from the server side with statement
    => goRS.result=[your result]
    To call the remote script, you renew goRS with
    the object constructor RSL (see next for details).
    Results are alway returned escaped.
    Be sure to unescape them.
!*/

goRS         = new Object();

function RSL()
{
/*? RSL is the actual object constructor.
    It processes parameters dynamically:
    The last parameter points to the exit function,
    being the function you want to run after
    the remote script finished and returned it's
    results. It may be omitted.
    The first parameter reflects the call to the
    server. Parameters are passed as one object
    in the form:
    {call:[remote function to call],
     param1:param1str,
     param2:param2str,
     callback:[exit function]}
    The parameters inbetween reflect the
    request variables you send in the form

    ** Examples **
    1. minimal, just call a remote function
       => goRS = new RSL({call:'nwFunction'})
    2. with reference to exit function
       => goRS = new RSL({call:'nwFunction',
                          callback:AllDone})
    3. with key/value combinations and reference
       to exit function
       => goRS = new RSL({call:'nwFunction',
                          name:'Pete',
                          age:43,
                          callback:AllDone)
!*/

  if (arguments.length<1)
  { this.result = 'ERROR: no query string provided!';
    alert(this.result);
    return false
  }

  if (!remoteApp || remoteApp == '')
  { this.result = 'ERROR: remote app unknown!\n'
                  +'Please supply the path of the remote\n'
                  +'application this object should use\n'
                  +'either in this object file or in the\n'
                  +'additional client scripting';
    alert(this.result);
    return false
  }

/*? Prepare the Querystring:
    the Querystring is composed out of the first argument
    sent to this object. In it the +-sign is replaced and 
    the string itself is escaped. Furthermore all
    occuring linebreaks (from a textarea) in the
    querystring are replaced by <br /> and if the
    global bool allowHTML is false, html markup is
    disabled using &lt;/&gt;
!*/
   
   this.oQ           = arguments[0];

   //** test if exit function is defined and assign it if so
   var oExTest       = this.oQ.callback;
    if (!String(oExTest).match(/undef|null/))
     if ( (String(typeof oExTest).match(/funct|obj/i)))
      this.exit      = oExTest;
    else
     this.exit       = function() {return true};

   var sQNow         = new RSL_ComposeQuery(this.oQ);
   this.sSrc         = remoteApp+'?'+sQNow.sQ;
   this.initScr      = RSL_setScript;

/*? The [dispatch] method doesn't really belong here. It is 
    my solution to a mozilla bug described in:
    => https://bugzilla.mozilla.org/show_bug.cgi?id=124032
    if you want to use it edit the calling html with the lines
    you'll find at the bottom of this file. I'll automate
    this later, but for now this is sufficient.
    append as the last statement in the return values
    after the exit function, like
    => goRS.dispatch()  or
    => goRS.dispatch([statusString])
    if you want to change the statusMessage (this can be
    used in IE also) and if you allow it via
    noStatChange being false  
!*/
   this.dispatch     = RSL_dispatchMOZ;
}

function RSL_setScript()
{
   var tScript    = document.createElement('script');
   tScript.id     = 'remotejs';
   tScript.defer  = true;
   tScript.onload = function(){return true};

   tScript.setAttribute('src',this.sSrc);

   if (!gbAppend)
   {
    //** first time loading, creating a container for the script
    //** and appending the script element to it
    var oRemote = document.createElement('div');
    oRemote.id  = 'remote';
    document.body.appendChild(oRemote);
    document.getElementById('remote').appendChild(tScript);
    gbAppend    = true;
   }
   else
   { //** let's not create a cloud of scripts here
     var oRDiv = document.getElementById('remote');
     oRDiv.removeChild(oRDiv.firstChild);
     //** re-append the just renewed script
     oRDiv.appendChild(tScript);
   }
 }

function RSL_ComposeQuery(oArgs)
{
  var aWrk  = new Array();
  var sT = '';
  for (var i in oArgs)
   if (i != 'callback')
   { var sArg = oArgs[i].replace(/\+/g,'&#43;');
     if (!allowHTML)
     {
       sArg = sArg.replace(/</g,'&lt;');
       sArg = sArg.replace(/>/g,'&gt;');
     }
    aWrk.push(i+'='+escape(sArg))
   }

  this.sQ = aWrk.join('&');
}

function RSL_dispatchMOZ(sStat)
{ 
  if (String(navigator.userAgent).match(/gecko/i))
  {
   var oDisp = document.getElementById('Moz_Dispatcher');
   if (sStat && !noStatChange)
    oDisp.onload=function(){top.defStat(sStat)}
   oDisp.src=''; return
  }
  else if (sStat && !noStatChange)
   defStat(sStat);

 return
}

function RSL_setStat(sTxt)
{
  window.defaultStatus = sTxt;
} 

/*? TO USE THE DISPATCHER, put this in your HTML (anywhere in the body)
    the onLoad handler restores the default window status bar (if there
    is one), see [setStat()] in this file.
    (Or cook up some DHTML to produce this Iframe. Will do it later)

    <iFrame id="Moz_Dispatcher" style="display:none;
     visibility:hidden;position:absolute;top:0px;width:0px;height:0px" 
     width="0" height="0" src="" onLoad="defStat(window.defaultStatus)">
    </iframe>
!*/