//
//  jsrsClient.js - javascript remote scripting client include
//  
//  Author:  Brent Ashley [jsrs@megahuge.com]
//
//  make asynchronous remote calls to server without client page refresh
//
//  see license.txt for copyright and license information

/*
see history.txt for full history
2.0  26 Jul 2001 - added POST capability for IE/MOZ
*/

// callback pool needs global scope
var jsrsContextPoolSize = 0;
var jsrsContextMaxPool = 10;
var jsrsContextPool = new Array();
var jsrsBrowser = jsrsBrowserSniff();
var jsrsPOST = true;

// constructor for context object
function jsrsContextObj( contextID ){
  
  // properties
  this.id = contextID;
  this.busy = true;
  this.callback = null;
  this.container = contextCreateContainer( contextID );
  
  // methods
  //this.GET = contextGET;
  this.POST = contextPOST;
  this.getPayload = contextGetPayload;
  this.setVisibility = contextSetVisibility;
}

//  method functions are not privately scoped 
//  because Netscape's debugger chokes on private functions
function contextCreateContainer( containerName ){
  // creates hidden container to receive server data 
  var container;


  switch( jsrsBrowser ) {
    case 'NS':
      container = new Layer(100);
      container.name = containerName;
      container.visibility = 'hidden';
      container.clip.width = 100;
      container.clip.height = 100;
      break;
    
    case 'IE':
      document.body.insertAdjacentHTML( "afterBegin", '<span id="SPAN' + containerName + '"></span>' );
	  var span = document.all( "SPAN" + containerName );
	  var html = '<iframe name="' + containerName + '" style="width:0px; height:0px; border: 0px" src="blank.html"></iframe>';
	  span.innerHTML = html;
	  span.style.display = 'none';
	  if (document.frames) {		
		  container = document.frames[containerName];
	  }
	  else {
		  container = window.frames[containerName];
	  }      
      break;
      
    case 'MOZ':  
      var span = document.createElement('SPAN');
      span.id = "SPAN" + containerName;
      document.body.appendChild( span );
      var iframe = document.createElement('IFRAME');
      iframe.name = containerName;
	  iframe.id = containerName;
	  iframe.src="blank.html";
      span.appendChild( iframe );
      container = iframe;
      break;
  }
  return container;
}

var the_rspage, the_func, the_parms, the_contextObj;
function ThePost(){
	the_contextObj.POST( the_rspage, the_func, the_parms );
}

function contextPOST( rsPage, func, parms ){
  var d = new Date();
  var unique = d.getTime() + '' + Math.floor(1000 * Math.random());
  var doc = (this.container.contentDocument) ? this.container.contentDocument : this.container.document;
  //if (document.getElementById) doc = document.getElementById(this.container.id).contentDocument;
  //alert(this.container.id);
  //doc = document.getElementById(this.container.id).contentDocument;
  //var contenuto = '';
  //for (var i in doc ) contenuto+= i + '----\n';	  
  //alert(contenuto);
  /*if (contenuto=='') {
	the_rspage = rsPage;
	the_func = func;
	the_parms = parms;
	the_contextObj = this;
	setTimeout("ThePost()",100);
  }*/

  doc.open();
  doc.write('<html><body>');
  doc.write('<form name="jsrsForm" method="post" target="" ');
  doc.write(' action="' + rsPage + '?U=' + unique + '">');
  doc.write('<input type="hidden" name="C" value="' + this.id + '">');
  
  // func and parms are optional
  if (func != null){
  doc.write('<input type="hidden" name="F" value="' + func + '">');

	if (parms != null){
	  if (typeof(parms) == "string"){
		// single parameter
		doc.write( '<input type="hidden" name="P0" ' + 'value="[' + jsrsEscapeQQ(parms) + ']">');
	  } else {
		// assume parms is array of strings
		for( var i=0; i < parms.length; i++ ){
		  doc.write( '<input type="hidden" name="P' + i + '" ' + 'value="[' + jsrsEscapeQQ(parms[i]) + ']">');
		}
	  } // parm type
	} // parms
  } // func

  doc.write('</form></body></html>');
  doc.close();
  //alert(doc.body.innerHTML);
  doc.forms['jsrsForm'].submit();
 
}

/*
function contextGET( rsPage, func, parms ){
	
  // build URL to call
  var URL = rsPage;
  
  // always send context
  URL += "?C=" + this.id;

  // func and parms are optional
  if (func != null){
    URL += "&F=" + escape(func);

    if (parms != null){
      if (typeof(parms) == "string"){
        // single parameter
        URL += "&P0=[" + escape(parms+'') + "]";
      } else {
        // assume parms is array of strings
        for( var i=0; i < parms.length; i++ ){
          URL += "&P" + i + "=[" + escape(parms[i]+'') + "]";
        }
      } // parm type
    } // parms
  } // func

  // unique string to defeat cache
  var d = new Date();
  URL += "&U=" + d.getTime();
  //alert(URL);
  // make the call
  switch( jsrsBrowser ) {
    case 'NS':
      this.container.src = URL;
      break;
    case 'IE':
      this.container.document.location.replace(URL);
      break;
    case 'MOZ':
      this.container.src = '';
      this.container.src = URL; 
      break;
  }  
  
}
*/

function contextGetPayload(){
  switch( jsrsBrowser ) {
    case 'NS':
      return this.container.document.forms['jsrs_Form'].elements['jsrs_Payload'].value;
    case 'IE':
      return this.container.document.forms['jsrs_Form']['jsrs_Payload'].value;
    case 'MOZ':
      return window.frames[this.container.name].document.forms['jsrs_Form']['jsrs_Payload'].value; 
  }  
}

function contextSetVisibility( vis ){
  switch( jsrsBrowser ) {
    case 'NS':
      this.container.visibility = (vis)? 'show' : 'hidden';
      break;
    case 'IE':
      document.all("SPAN" + this.id ).style.display = (vis)? '' : 'none';
      break;
    case 'MOZ':
      document.getElementById("SPAN" + this.id).style.visibility = (vis)? '' : 'hidden';
      this.container.width = (vis)? 250 : 0;
      this.container.height = (vis)? 100 : 0;
      break;
  }  
}

// end of context constructor

function jsrsGetContextID(){
  var contextObj;
  for (var i = 1; i <= jsrsContextPoolSize; i++){
    contextObj = jsrsContextPool[ 'jsrs' + i ];
    if ( !contextObj.busy ){
      contextObj.busy = true;      
      return contextObj.id;
    }
  }
  // if we got here, there are no existing free contexts
  if ( jsrsContextPoolSize <= jsrsContextMaxPool ){
    // create new context
    var contextID = "jsrs" + (jsrsContextPoolSize + 1);
    jsrsContextPool[ contextID ] = new jsrsContextObj( contextID );
    jsrsContextPoolSize++;
    return contextID;
  } else {
    alert( "jsrs Error:  context pool full" );
    return null;
  }
}

function jsrsExecute( rspage, callback, func, parms, visibility ){
  // call a server routine from client code
  //
  // rspage      - href to asp file
  // callback    - function to call on return 
  //               or null if no return needed
  //               (passes returned string to callback)
  // func        - sub or function name  to call
  // parm        - string parameter to function
  //               or array of string parameters if more than one
  // visibility  - optional boolean to make container visible for debugging
  
  // get context
  var contextObj = jsrsContextPool[ jsrsGetContextID() ];
  contextObj.callback = callback;

  var vis = (visibility == null)? false : visibility;
  contextObj.setVisibility( vis );

  if ( jsrsPOST )
  {

	 switch( jsrsBrowser ) {
		case 'NS':
		 jsrsError( contextObj.id, "FUNZIONALITA' NON SUPPORTATA!" )
		 //contextObj.GET( rspage, func, parms );
		 break;
		case 'IE':		
		  contextObj.POST( rspage, func, parms );
		  break;
		case 'MOZ':
		 the_rspage = rspage;
		 the_func = func;
		 the_parms = parms;
		 the_contextObj = contextObj;
		 setTimeout("ThePost()",100);
		 break;
		default :
		 jsrsError( contextObj.id, "FUNZIONALITA' NON SUPPORTATA!" )
		 //contextObj.GET( rspage, func, parms );
		break;
	  } 

	  return contextObj.id;
  }
  else {
	//contextObj.GET( rspage, func, parms );
	jsrsError( contextObj.id, "FUNZIONALITA' NON SUPPORTATA!" )
  }
  
  //return contextObj.id;
}

function jsrsLoaded( contextID ){
  // get context object and invoke callback
  var contextObj = jsrsContextPool[ contextID ];
  if( contextObj.callback != null){
    contextObj.callback( jsrsUnescape( contextObj.getPayload() ), contextID );
  }
  // clean up and return context to pool
  contextObj.callback = null;
  contextObj.busy = false;

  if ( (contextObj.debug != true) && (jsrsBrowser == 'IE') )
	 contextObj.container.location = 'about:blank';

}

function jsrsError( contextID, str ){
  alert( unescape(str) );
  jsrsContextPool[ contextID ].busy = false
}

function jsrsEscapeQQ( thing ){
	//thing = thing.replace(/\&/g, "&amp;amp;");
	//thing = thing.replace(/\-/g, "&amp;ndash;");
	//thing = thing.replace(/\-/g, "&amp;mdash;");
	thing = thing.replace(/\¡/g, "&amp;iexcl;");
	thing = thing.replace(/\¢/g, "&amp;cent;");
	thing = thing.replace(/\£/g, "&amp;pound;");
	thing = thing.replace(/\¤/g, "&amp;curren;");
	thing = thing.replace(/\¥/g, "&amp;yen;");
	//thing = thing.replace(/\¦/g, "&amp;brvbar;");
	thing = thing.replace(/\§/g, "&amp;sect;");
	thing = thing.replace(/\¨/g, "&amp;uml;");
	thing = thing.replace(/\©/g, "&amp;copy;");
	thing = thing.replace(/\ª/g, "&amp;ordf;");
	thing = thing.replace(/\¬/g, "&amp;not;");
	//thing = thing.replace(/\­/g, "&amp;shy;");
	thing = thing.replace(/\®/g, "&amp;reg;");
	//thing = thing.replace(/\¯/g, "&amp;macr;");
	thing = thing.replace(/\°/g, "&amp;deg;");
	thing = thing.replace(/\±/g, "&amp;plusmn;");
	thing = thing.replace(/\¹/g, "&amp;sup1;");
	thing = thing.replace(/\²/g, "&amp;sup2;");
	thing = thing.replace(/\³/g, "&amp;sup3;");
	thing = thing.replace(/\¼/g, "&amp;frac14;");
	thing = thing.replace(/\½/g, "&amp;frac12;");
	thing = thing.replace(/\¾/g, "&amp;frac34;"); 
	//thing = thing.replace(/\´/g, "&amp;acute;");
	thing = thing.replace(/\µ/g, "&amp;micro;");
	thing = thing.replace(/\¶/g, "&amp;para;");
	//thing = thing.replace(/\·/g, "&amp;middot;");
	thing = thing.replace(/\¸/g, "&amp;cedil;");
	thing = thing.replace(/\º/g, "&amp;ordm;");
	thing = thing.replace(/\¿/g, "&amp;iquest;");
	thing = thing.replace(/\À/g, "&amp;Agrave;");
	thing = thing.replace(/\Á/g, "&amp;Aacute;");
	thing = thing.replace(/\Â/g, "&amp;Acirc;");
	thing = thing.replace(/\Ã/g, "&amp;Atilde;");
	thing = thing.replace(/\Ä/g, "&amp;Auml;");
	thing = thing.replace(/\Å/g, "&amp;Aring;");
	thing = thing.replace(/\Æ/g, "&amp;AElig;");
	thing = thing.replace(/\à/g, "&amp;agrave;");
	thing = thing.replace(/\á/g, "&amp;aacute;");
	thing = thing.replace(/\â/g, "&amp;acirc;");
	thing = thing.replace(/\ã/g, "&amp;atilde;");
	thing = thing.replace(/\ä/g, "&amp;auml;");
	thing = thing.replace(/\å/g, "&amp;aring;");
	thing = thing.replace(/\æ/g, "&amp;aelig;");
	thing = thing.replace(/\È/g, "&amp;Egrave;");
	thing = thing.replace(/\È/g, "&amp;Eacute;");
	thing = thing.replace(/\Ê/g, "&amp;Ecirc;");
	thing = thing.replace(/\Ë/g, "&amp;Euml;");
	thing = thing.replace(/\è/g, "&amp;egrave;");
	thing = thing.replace(/\è/g, "&amp;eacute;");
	thing = thing.replace(/\ê/g, "&amp;ecirc;");
	thing = thing.replace(/\ë/g, "&amp;euml;");
	thing = thing.replace(/\Ì/g, "&amp;Igrave;");
	thing = thing.replace(/\Í/g, "&amp;Iacute;");
	thing = thing.replace(/\Î/g, "&amp;Icirc;");
	thing = thing.replace(/\Ï/g, "&amp;Iuml;");
	thing = thing.replace(/\ì/g, "&amp;igrave;");
	thing = thing.replace(/\í/g, "&amp;iacute;");
	thing = thing.replace(/\î/g, "&amp;icirc;");
	thing = thing.replace(/\ï/g, "&amp;iuml;");
	thing = thing.replace(/\Ò/g, "&amp;Ograve;");
	thing = thing.replace(/\Ó/g, "&amp;Oacute;");
	thing = thing.replace(/\Ô/g, "&amp;Ocirc;");
	thing = thing.replace(/\Õ/g, "&amp;Otilde;");
	thing = thing.replace(/\Ö/g, "&amp;Ouml;");
	thing = thing.replace(/\ò/g, "&amp;ograve;");
	thing = thing.replace(/\ó/g, "&amp;oacute;");
	thing = thing.replace(/\ô/g, "&amp;ocirc;");
	thing = thing.replace(/\õ/g, "&amp;otilde;");
	thing = thing.replace(/\ö/g, "&amp;ouml;");
	thing = thing.replace(/\Ù/g, "&amp;Ugrave;");
	thing = thing.replace(/\Ú/g, "&amp;Uacute;");
	thing = thing.replace(/\Û/g, "&amp;Ucirc;");
	thing = thing.replace(/\Ü/g, "&amp;Uuml;");
	thing = thing.replace(/\ù/g, "&amp;ugrave;");
	thing = thing.replace(/\ú/g, "&amp;uacute;");
	thing = thing.replace(/\û/g, "&amp;ucirc;");
	thing = thing.replace(/\ü/g, "&amp;uuml;");
	thing = thing.replace(/\Ç/g, "&amp;Ccedil;"); 
	thing = thing.replace(/\ç/g, "&amp;ccedil;"); 
	thing = thing.replace(/\Ý/g, "&amp;Yacute;"); 
	thing = thing.replace(/\ý/g, "&amp;yacute;"); 
	thing = thing.replace(/\ÿ/g, "&amp;yuml;"); 
	thing = thing.replace(/\Þ/g, "&amp;THORN;"); 
	thing = thing.replace(/\þ/g, "&amp;thorn;"); 
	thing = thing.replace(/\Ñ/g, "&amp;Ntilde;"); 
	thing = thing.replace(/\ñ/g, "&amp;ntilde;"); 
	thing = thing.replace(/\Ð/g, "&amp;ETH;");
	thing = thing.replace(/\ð/g, "&amp;eth;"); 
	thing = thing.replace(/\Ø/g, "&amp;Oslash;"); 
	thing = thing.replace(/\ø/g, "&amp;oslash;");
	thing = thing.replace(/\×/g, "&amp;times;"); 
	thing = thing.replace(/\÷/g, "&amp;divide;"); 
	thing = thing.replace(/\ß/g, "&amp;szlig;"); 
	thing = thing.replace(/\™/g, "&amp;trade;");   
	thing = thing.replace(/\„/g, "&amp;bdquo;");   
	thing = thing.replace(/\†/g, "&amp;dagger;");   
	thing = thing.replace(/\‡/g, "&amp;Dagger;"); 
	thing = thing.replace(/\‰/g, "&amp;permil;");   
	//thing = thing.replace(/\‹/g, "&amp;lsaquo;");   
	//thing = thing.replace(/\›/g, "&amp;rsaquo;");   
	thing = thing.replace(/\«/g, "&amp;laquo;");   
	thing = thing.replace(/\»/g, "&amp;raquo;");   
	thing = thing.replace(/\€/g, "&amp;euro;"); 	
	//thing = thing.replace(/"/g,'&quot;'); 
	return thing.replace(/"/g,'&quot;');
}

function jsrsUnescape( str ){
  // payload has slashes escaped with whacks
  return str.replace( /\\\//g, "/" );
}

function jsrsBrowserSniff(){

	if (document.layers) return "NS";
	if (document.all) return "IE";
	if (document.getElementById) return "MOZ";

	return "OTHER";
}

/////////////////////////////////////////////////
//
// user functions

function jsrsArrayFromString( s, delim ){
  // rebuild an array returned from server as string
  // optional delimiter defaults to ~
  var d = (delim == null)? '~' : delim;
  return s.split(d);
}

function jsrsDebugInfo(){
  // use for debugging by attaching to f1 (works with IE)
  // with onHelp = "return jsrsDebugInfo();" in the body tag
  var doc = window.open().document;
  doc.open;
  doc.write( 'Pool Size: ' + jsrsContextPoolSize + '<br><font face="arial" size="2"><b>' );
  for( var i in jsrsContextPool ){
    var contextObj = jsrsContextPool[i];
    doc.write( '<hr>' + contextObj.id + ' : ' + (contextObj.busy ? 'busy' : 'available') + '<br>');
    doc.write( contextObj.container.document.location.pathname + '<br>');
    doc.write( contextObj.container.document.location.search + '<br>');
    doc.write( '<table border="1"><tr><td>' + contextObj.container.document.body.innerHTML + '</td></tr></table>' );
  }
  doc.write('</table>');
  doc.close();
  return false;
}
