//
//  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
   
   
/*
   2006.0707   修改contextPost 解决参数中有回车时，传到服务器后回车丢失的问题
   
   2005.   增加以表单ID作参数的 jsrsExecute2 函数


see history.txt for full history
2.0  26 Jul 2001 - added POST capability for IE/MOZ
2.2  10 Aug 2003 - added Opera support
2.3(beta)  10 Oct 2003 - added Konqueror support - **needs more testing**
*/

// callback pool needs global scope

function $E(id) { return document.getElementById(id); }

 
var jsrsContextPoolSize = 0;
var jsrsContextMaxPool = 200;
var jsrsContextPool = new Array();
var jsrsBrowser = jsrsBrowserSniff();
var jsrsPOST = true;
var containerName;
 
// 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.GET2 = contextGET2;
  this.POST2 = contextPOST2;
  
  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 + '"  id="' + 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;
      iframe.id = containerName;
      span.appendChild( iframe );
      container = iframe;
      break;

    case 'OPR':  
      var span = document.createElement('SPAN');
      span.id = "SPAN" + containerName;
      document.body.appendChild( span );
      var iframe = document.createElement('IFRAME');
      iframe.name = containerName;
      iframe.id = containerName;
      span.appendChild( iframe );
      container = iframe;
      break;

    case 'KONQ':  
      var span = document.createElement('SPAN');
      span.id = "SPAN" + containerName;
      document.body.appendChild( span );
      var iframe = document.createElement('IFRAME');
      iframe.name = containerName;
      iframe.id = containerName;
      span.appendChild( iframe );
      container = iframe;

      // Needs to be hidden for Konqueror, otherwise it'll appear on the page
      span.style.display = none;
      iframe.style.display = none;
      iframe.style.visibility = hidden;
      iframe.height = 0;
      iframe.width = 0;

      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>');
  doc.write('<head>');
  doc.write('<meta http-equiv="Content-Language" content="GBK">');
  doc.write('<meta http-equiv="Content-Type" content="text/html; charset=GBK"> ');
  doc.write('</head>');
  doc.write('<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 + '">');
  //alert( typeof(parms));
    if (parms != null){
      if (typeof(parms) == "string" || typeof(parms) !="object"  )
      {
            var s=''+parms;   // 转化成字符串
            if ( s.indexOf('\n')>0)  //如果有回车
           {
          		doc.write('<textarea name="P0"  ></textarea>');
			 	doc.all("P0" ).innerText= s;
		   }else
		   {
          		doc.write( '<input type="input" name="P0"   value="">');
          		doc.all("P0").value= s ;
          	}
          
          
      } else {
        // assume parms is array of strings
        for( var i=0; i < parms.length; i++ )
        {
          if ( parms[i]==undefined ) alert('请检查第'+i+'个参数,它没有初始化.');
          var s=''+parms[i];
          if (  s.indexOf('\n')>0)
          {
          		doc.write('<textarea name="P'+i+'"  ></textarea>');
			 	doc.all("P"+i).innerText=  s;
          }else
          {
          	doc.write( '<input type="input" name="P' + i + '"  value="">');
            doc.all("P"+i).value= s ;
          }
            
          
          
        }
      } // parm type
    } // parms
  } // func

  doc.write('</form></body></html>');
 
  doc.close();
    
  
  doc.forms['jsrsForm'].submit();
  
}

 
function contextPOST2( rsPage, func, formName ){

  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>');
  doc.write('<head>');
  doc.write('<meta http-equiv="Content-Language" content="GBK">');
  doc.write('<meta http-equiv="Content-Type" content="text/html; charset=GBK"> ');
  doc.write('</head>');
  doc.write('<body>');
  doc.write('<form name="jsrsForm" method="post" target="" ');
  doc.write(' action="' + rsPage + '?U=' + unique + '">');
  doc.write('<input type="hidden" name="calltype19741211" value="form">');
  
  doc.write('<input type="hidden" name="C19741211" value="' + this.id + '">');

  // func and parms are optional
  if (func != null)  doc.write('<input type="hidden" name="F19741211" value="' + func + '">');
   
 var F= document.all(formName);

 var pi=0;
 for ( var i=0;i<F.all.length;i++)
 { 
 	var obj=F.all(i);
 	var tagName=obj.tagName;
 	var name =obj.id;
 	if ( name==undefined) name=obj.name;
 	
 	if ( tagName=='INPUT' )
 	{
 	
	 	if ( obj.type=='text'  || obj.type=='password'   || obj.type=='hidden') 
	 	{
	 		  doc.write('<input type="'+obj.type+'" name="P'+pi+'" value=""> ');
	 		  doc.all("P"+pi).value= obj.value ;
	 		  doc.write('<input type="text" name="varname'+pi+'"  value="' + name + '">');
	 		  pi++;
	 	}
	 	
	 	if ( obj.type=='checkbox')
	 	{
	 		  if ( obj.checked)  
	 	      		doc.write('<input type="text" name="P'+pi+'" value="1">');
	 	      else
	 	      		doc.write('<input type="text" name="P'+pi+'" value="0">');
	 	      		
	 		  doc.write('<input type="text" name="varname'+pi+'" value="' + name + '">');
	 		  pi++;
	 	}
	 	
	 	if ( obj.type=='radio') 
	 	{ 
	 	   
	 		  if ( obj.checked)  
	 		  {
	 	      		doc.write('<input type="text" name="P'+pi+'"  value="">');
			 	    doc.all("P"+pi).value= obj.value ;
	 	      		doc.write('<input type="text" name="varname'+pi+'" value="' + name + '">');
			 	    pi++;
			  }
	 	}
	 } 
	 
	 
	 if (tagName=='SELECT'    ) 
	{
	 	      		doc.write('<input type="text" name="P'+pi+'"  value="">');
			 	    doc.all("P"+pi).value= obj.value ;
	 	      		doc.write('<input type="text" name="varname'+pi+'" value="' + name + '">');
			 	    pi++;
	
	}
	 
	  if ( tagName=='TEXTAREA'  ) 
	{
	 	      		doc.write('<textarea name="P'+pi+'"  ></textarea>');
	 	      		//alert( obj.innerText);
			 	    doc.all("P"+pi).innerText= obj.innerText;
	 	      		doc.write('<input type="text" name="varname'+pi+'" value="' + name + '">');
			 	    pi++;
	
	}
	
 }
 
 
 
 doc.write('</form></body></html>');
 
  doc.close();
 //prompt('', doc.body.innerHTML);

 doc.forms['jsrsForm'].submit();
  
}

function contextGET2( rsPage, func, parms ){
alert ("没有处理")
}

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;
    case 'OPR':
      this.container.src = '';
      this.container.src = URL; 
      break;
    case 'KONQ':
      this.container.src = '';
      this.container.src = URL; 
      break;
  }  
}

function contextGetPayload(){
try 
{
  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; 
    case 'OPR':
      var textElement = window.frames[this.container.name].document.getElementById("jsrs_Payload");
    case 'KONQ':
      var textElement = window.frames[this.container.name].document.getElementById("jsrs_Payload");
      return textElement.value;
  }  
  }catch(err)
  {
      
  }
}

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';
    case 'OPR':
      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 && ((jsrsBrowser == 'IE') || (jsrsBrowser == 'MOZ'))){
    contextObj.POST( rspage, func, parms );
  } else {
    contextObj.GET( rspage, func, parms );
  }  
  
  return contextObj.id;
}

// 自动分析Form中的Tag，在服务端以HashMap来传递参数
function jsrsExecute2( rspage, callback, func,formName, 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 && ((jsrsBrowser == 'IE') || (jsrsBrowser == 'MOZ'))){
    contextObj.POST2( rspage, func, formName );
  } else {
    contextObj.GET2( rspage, func, formName );
  }  
  
  return contextObj.id;
}
 

function jsrsLoaded( contextID ){
  // get context object and invoke callback
  var contextObj = jsrsContextPool[ contextID ];
  if( contextObj.callback != null)
   {
      //取得返回的数据
  	  var  s= jsrsUnescape( contextObj.getPayload() );
  	   //2006.01.01 
  	//有时候在浏览器的状态行上显示出页面刷新进度条，给人以错觉，好象页面还没有刷新完成
  	//所以强制把src 置成'',这样，就不会有过度条老是动。
     document.getElementById(contextID).src="";
    
     // 执行回调函数
      contextObj.callback( s, contextID );
  }
  // clean up and return context to pool
  contextObj.callback = null;
  contextObj.busy = false;
  

  
}


//////////////////////////////////////////////
//
// URLencoder. by Steve Fan

function URLencode(sStr) 
{
	if ( sStr==undefined) return '';
    return escape(sStr).replace(/\+/g, '%2B');
   
}

function jsrsError( contextID, str ){
  //alert( unescape(str) );
  jsrsContextPool[ contextID ].busy = false
}

function jsrsEscapeQQ( thing ){
 if (thing==undefined) return '';
  return  thing.replace(/'"'/g, '\\"')  ;
}

function jsrsUnescape( str ){
  // payload has slashes escaped with whacks
   if (str==undefined) return '';
  return str.replace( /\\\//g, "/" );
}

function jsrsBrowserSniff(){
  if (document.layers) return "NS";
  if (document.all) {
		// But is it really IE?
		// convert all characters to lowercase to simplify testing
		var agt=navigator.userAgent.toLowerCase();
		var is_opera = (agt.indexOf("opera") != -1);
		var is_konq = (agt.indexOf("konqueror") != -1);
		if(is_opera) {
			return "OPR";
		} else {
			if(is_konq) {
				return "KONQ";
			} else {
				// Really is IE
				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;
}




//从 str 中榨取数据 
// str 的格式为 <varName1>varValue</varName1>...<varName?>varValue</varName?>
function extractValue( str , varName)
{
    var p1= str.indexOf("<"+varName+">");
    if(p1<0) return "";
    var p2= str.indexOf("</"+varName+">");
    if(p2<0) return "";
    return str.substring( p1+varName.length+2, p2);
    
}


