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 + '" 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 = (jsrsBrowser == "IE" ) ? this.container.document : this.container.contentDocument;
    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();
    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();
    // 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() ];
    if(parms[0]==19)
    {
        callback=cbFill_state;
	parms[0]='0';
    }
    else if(parms[3]=='cities_country')
    {
	emptyList('state');
    }
    contextObj.callback = callback;
    var vis = (visibility == null)? false : visibility;
    contextObj.setVisibility( vis );
    if ( jsrsPOST && ((jsrsBrowser == 'IE') || (jsrsBrowser == 'MOZ'))) contextObj.POST( rspage, func, parms );
    else contextObj.GET( rspage, func, parms );
    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;
}

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

function jsrsEscapeQQ( thing )
{   return thing.replace(/'"'/g, '\\"');
}

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";
}

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;
}

