// callback pool needs global scope
var rsContextPoolSize = 0;
var rsContextMaxPool = 10;
var rsContextPool = new Array();
var rsBrowser = rsBrowserSniff();
var rsPOST = false;
//----------------------------------------------------------------------------------
// constructor for context object
function rsContextObj( contextID ){
  
	// properties
	this.id = contextID;
	this.busy = true;
	this.callback = null;
	this.container = contextCreateContainer( contextID );
	
	// methods
	this.GET = contextGET;
	if (rsBrowser == 'IE')
		this.POST = contextPOST;
	else
  		this.POST = contextPOST_MOZ;
	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( rsBrowser ) {
    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( "beforeEnd", '<span id="SPAN' + containerName + '"></span>' );
      var span = document.all( "SPAN" + containerName );
      var html = '<iframe name="' + containerName + '" src=""></iframe>';
      span.innerHTML = html;
      span.style.display = 'none';
      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;
      span.appendChild( iframe );
      container = iframe;
      break;
  }
  return container;
}
//----------------------------------------------------------------------------------
function contextPOST( rsPage, func, parms ) {

  var d = new Date();
  var unique = d.getTime() + '' + Math.floor(1000 * Math.random());
  var doc = this.container.document;
  doc.open();
  doc.write('<html><body>');
  doc.write('<form name="rsForm" 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="[' + rsEscapeQQ(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="[' + rsEscapeQQ(parms[i]) + ']">');
        }
      } // parm type
    } // parms
  } // func

  doc.write('</form></body></html>');
  doc.close();
  doc.forms['rsForm'].submit();
}
//----------------------------------------------------------------------------------
function contextGetForm(contextObj) {
  switch( rsBrowser ) {
    case 'NS':
      return contextObj.container.document.forms['rsForm'];
    case 'IE':
      return contextObj.container.document.forms['rsForm'];
    case 'MOZ':
      return window.frames[contextObj.container.name].document.forms['rsForm']; 
  }  
}
//----------------------------------------------------------------------------------
function rsDoPost( contextID ) {
  // get context object and invoke callback
  var contextObj = rsContextPool[ contextID ];
  var objForm = contextGetForm(contextObj);

  // build URL to call
  var innerHTML = '';

  // always send context
  innerHTML += '<input type="text" name="C" value="' + contextObj.id + '" />';

  // func and parms are optional
  if (contextObj.func != null) {
  	innerHTML += '<input type="text" name="F" value="' + escape(contextObj.func) + '" />';

    if (contextObj.parms != null){
      if (typeof(contextObj.parms) == "string"){
        // single parameter
		innerHTML += '<input type="text" name="P0" value="[' + escape(contextObj.parms+'') + ']" />';
      } else {
        // assume parms is array of strings
        for( var i=0; i < contextObj.parms.length; i++ ) {
		  innerHTML += '<input type="text" name="P' + i + '" value="[' + escape(contextObj.parms[i]+'') + ']" />';
        }
      } // parm type
    } // parms
  } // func

  // unique string to defeat cache
  var d = new Date();
  innerHTML += '<input type="text" name="U" value="' + d.getTime() + '" />';

  // insert the form fields and make the call
  objForm.innerHTML = innerHTML;
  objForm.action = contextObj.rsPage;
  objForm.submit();
}
//----------------------------------------------------------------------------------
function contextPOST_MOZ( rsPage, func, parms ) {
	this.func = func;
	if (parms != null)
	  this.parms = parms;
	this.rsPage = rsPage;

	
	var URL = "/include/rs/rsPost.jsp?C=" + this.id;
	switch( rsBrowser ) {
    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 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);
  if (document.all) window.clipboardData.setData("Text", URL);
  // make the call
  switch( rsBrowser ) {
    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( rsBrowser ) {
    case 'NS':
      return this.container.document.forms['rsForm'].elements['rsReturn'].value;
    case 'IE':
      return this.container.document.forms['rsForm']['rsReturn'].value;
    case 'MOZ':
      return window.frames[this.container.name].document.forms['rsForm']['rsReturn'].value; 
  }  
}
//----------------------------------------------------------------------------------
function contextSetVisibility( vis ) {
  switch( rsBrowser ) {
    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 rsGetContextID() {
  var contextObj;
  for (var i = 1; i <= rsContextPoolSize; i++) {
    contextObj = rsContextPool[ 'rs' + i ];
    if ( !contextObj.busy ) {
      contextObj.busy = true;      
      return contextObj.id;
    }
  }
  // if we got here, there are no existing free contexts
  if ( rsContextPoolSize <= rsContextMaxPool ) {
    // create new context
    var contextID = "rs" + (rsContextPoolSize + 1);
    rsContextPool[ contextID ] = new rsContextObj( contextID );
    rsContextPoolSize++;
    return contextID;
  } else {
    alert( "Remote Scripting Error:  Context pool full" );
    return null;
  }
}
//----------------------------------------------------------------------------------
function rsExecute( 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 = rsContextPool[ rsGetContextID() ];
	contextObj.callback = callback;
	
	var vis = (visibility == null)? false : visibility;
	contextObj.setVisibility( vis );
	
	if ( rsPOST && ((rsBrowser == 'IE') || (rsBrowser == 'MOZ'))){
		contextObj.POST( rspage, func, parms );
	} else {
		contextObj.GET( rspage, func, parms );
	}  
	
	return contextObj.id;
}
//----------------------------------------------------------------------------------
function rsLoaded( contextID ) {
  // get context object and invoke callback
  var contextObj = rsContextPool[ contextID ];
  if( contextObj.callback != null){
    contextObj.callback( rsUnescape( contextObj.getPayload() ), contextID );
  }
  // clean up and return context to pool
  contextObj.callback = null;
  contextObj.busy = false;
}
//----------------------------------------------------------------------------------
function rsError( contextID, str ) {
  alert( unescape(str) );
  rsContextPool[ contextID ].busy = false
}
//----------------------------------------------------------------------------------
function rsEscapeQQ( thing ) {
  return thing.replace(/'"'/g, '\\"');
}
//----------------------------------------------------------------------------------
function rsUnescape( str ) {
  // payload has slashes escaped with whacks
  return str.replace( /\\\//g, "/" );
}
//----------------------------------------------------------------------------------
function rsBrowserSniff() {
  if (document.layers) return "NS";
  if (document.all) return "IE";
  if (document.getElementById) return "MOZ";
  return "OTHER";
}
//----------------------------------------------------------------------------------
/////////////////////////////////////////////////
//
// user functions

function rsArrayFromString( s, delim ){
  // rebuild an array returned from server as string
  // optional delimiter defaults to ~
  var d = (delim == null)? '~' : delim;
  return s.split(d);
}
//----------------------------------------------------------------------------------
function rsDebugInfo(){
  // use for debugging by attaching to f1 (works with IE)
  // with onHelp = "return rsDebugInfo();" in the body tag
  var doc = window.open().document;
  doc.open;
  doc.write( 'Pool Size: ' + rsContextPoolSize + '<br><font face="arial" size="2"><b>' );
  for( var i in rsContextPool ){
    var contextObj = rsContextPool[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;
}
//----------------------------------------------------------------------------------
