//
//  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
     20 Jan 2002 - switched Mozilla back to using GET - John Lim
*/

// callback pool needs global scope
var jsrsContextPoolSize=0;
var jsrsContextMaxPool=15;
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=this.container.document;
  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;
	default:
    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 );

 /* POST does not work for MOZ - jlim 20/1/2002 */
  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) {
  	 if (navigator.userAgent.indexOf("Opera") > -1 || 
	 	navigator.userAgent.indexOf("Konqueror") > -1) return "MOZ";
	return "IE";
  }
  if (document.getElementById) return "MOZ";
  return "OTHER";
}

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


//// JLIM ADDED CODE


var _dlookup;
var ns4=(navigator.appName=='Netscape' && parseInt(navigator.appVersion)==4);
var ie4=(document.all)? true:false;
var ns6=(document.getElementById)? true:false;
if (ie4 && ns6) ns6=false;
function LensShow(obj){
if(ns4)obj.visibility='show';
else if(ie4)obj.style.visibility='visible';
else if(ns6)obj.style.visibility='visible';
}
function LensHide(obj){
if(ns4)obj.visibility='hide';
else if(ie4)obj.style.visibility='hidden';
else if(ns6)obj.style.visibility='hidden';
}
function LensTo(obj,xL,yL){
if(ns4){obj.left=xL;obj.top=yL;}
else{obj.style.left=xL+'px';obj.style.top=yL+'px';}
}


function PHPLens_GetOffTop(o)
{
var v=o.offsetTop;
while (o.offsetParent){
	o=o.offsetParent;
	v += o.offsetTop;
	if (ie4 && o.tagName == 'TD')v += o.clientTop; 
} 
return v;
}

function LensGo(to){document.location = to;}

function LensTrim(v){return v.replace(/( *)$/,'');}

function PHPLens_GetOffLeft(o)
{
var v=o.offsetLeft;
while (o.offsetParent){
	o=o.offsetParent;
	v += o.offsetLeft;
	if (ie4 && o.tagName == 'TD') v += o.clientLeft;
} 
return v;
}

function lens_dlookup(form,zself,sql,zclear)
{
_dlform = form;
_dlpopup[form][3]='document.'+form+'.elements["'+zself+'"]';
var o=eval(_dlpopup[form][3]);
if (o) {_dltext=o.value;} 
else {alert('Unknown object ' + _dlpopup[form][3]);return;}
if (_dltext.length < _dlpopup[form][0]) {
	alert(_minChars+': '+_dlpopup[form][0]);
	return;
}
LensBtn(form,false);
var v=escape(o.value); if (zclear) o.value='';
jsrsExecute(_remoteQ,PHPLens_DLCallback,'PHPLens_Remote_Query',Array('',zself,sql+_sepRS+'#::'+v));
}

function lens_dclose(o)
{
if(ie4) var zdiv=lensdiv;
if (ns6) var zdiv=self.document.getElementById('lensdiv');
var input=eval(_dlpopup[_dlform][3]),zat,recno,f;
zat = _dlupdate[_dlform][1];
f=eval('document.'+_dlform);
recno = f.elements[zat]; if (recno) LensShow(recno);
LensShow(input);LensHide(zdiv);LensBtn(_dlform,true);
}


function lens_esc(s)
{
	s = unescape(s);
	s = s.replace(/\&nbsp;/g,'\xA0');
	return s;
}

function lens_dsel(o)
{
if(ie4) var zdiv=lensdiv;
if (ns6) var zdiv=self.document.getElementById('lensdiv');
var opt=o.options[o.selectedIndex];
if (opt.value) { 
var c,v,z,k,a,f=_dlform,s,arr2,upd,recno
	if (opt.value=='::')arr2=Array('','','','','','','');
	else arr2=(opt.value).split('::');
	var input=eval(_dlpopup[f][3]),upd=_dlpopup[f][2];
	input.value=unescape(arr2[1])
	a=_dlupdate[f];c=1;f=eval('document.'+f);
	lens_dclose(f);
	for (k in a) {
		c++;v=LensTrim(unescape(arr2[c]));
		if (upd) {LensGo(upd.replace(/##/,v));return};
		if (z=f.elements['_'+a[k]+'_y']){//date
			v=v.split('-');
			if (v.length==3){
				z.value=v[0];
				z=f.elements['_'+a[k]+'_m'];z.value=v[1];
				var v=(v[2]).split(' ');
				z=f.elements['_'+a[k]+'_d'];z.value=v[0];
				if (v.length>1){
					v=(v[1]).split(':');
					z=f.elements['_'+a[k]+'_h'];z.value=v[0];
					z=f.elements['_'+a[k]+'_i'];z.value=v[1];
					z=f.elements['_'+a[k]+'_s'];z.value=v[2];
				}
			}
		} else {
			z=f.elements[a[k]];
			if (z)PHPLens_Set(z,v);
			else{
				z=self.document.getElementById(a[k]);
				if (z) {
					if (z.innerText) {if (v) z.innerText=v; else z.innerText = ' ';}
					else if (z.firstChild && z.firstChild.nodeName=='#text'&&z.firstChild.data)z.firstChild.data=v;
				} else { // radio or cb
					z=a[k]; z=z.substr(0,4)+'_CB_'+z.substr(8);
					PHPLens_RBCB(z,v)
				}
			}
		}
	}
}
}

function PHPLens_RBCB(z,v)
{
var i=0,a=Array(),j,k;
v = LensTrim(v);
while(1) {
	o=self.document.getElementById(z+'_'+i)
	if (!o) return;
	if (o.type == 'radio') {if(LensTrim(o.value) == v) {o.checked=true;return}}
	else {return;
	// does not work because we store array index in o.value
		a=v.split(', ');
		for (j in a) {
		alert(j+' '+o.value);
		if (LensTrim(o.value) == LensTrim(j)){alert(o.id);o.checked=true}
		}
	}
	i++;
}
}

function PHPLens_Set(z,v)
{
v = LensTrim(v);
if ((z.type && z.type=='text') || z.value) z.value=v;
else if ((z.type).substr(0,6) == 'select') {
	var m,x;
	m=z.options.length;
	for (i=0; i<m; i++) {
		x=z.options[i];
		if (x.value) {if (LensTrim(x.value)==v) {x.selected=true;break;}}
		else if (LensTrim(x.text)==v) {x.selected=true;break;}
	}
} 
}

function PHPLens_DLCallback(ret)
{
var o,arr,arr2,input,dv,f,recno;
	arr=ret.split(_sepRS);
	if (arr.length<2) {alert(ret.replace(/\+/g,' '));return;}
	if (arr[0].length) alert(arr[0])
	f=_dlform
	
	input=PHPLens_FindObj(f,arr[2]);
	if (arr.length <= 4) {
		var zform=eval('document.'+f);
		LensShow(zform.elements['dl_'+arr[2]]);
		input.value=_dltext;
		lens_dclose('');
		alert(_noRecs);return;
	}
	
	if(ie4)var dv=lensdiv;
	else if(ns6)var dv=document.getElementById('lensdiv');
	if (ie4) o=dv.children('menu');
	else o=document.getElementById('lensdivsel'); 
	if (o.type == 'text') o.value=unescape(arr[3]);
	LensHide(input);
	var zform=eval('document.'+f);
	recno = zform.elements[_dlupdate[_dlform][1]]; if (recno) LensHide(recno);
	
	if ((o.type).substr(0,6) == 'select') {
	var max,val,hasval,arr1;
		max=o.options.length; hasval=_dlpopup[f][1];arr1=arr[1]+'::';
		for (i=0; i<max; i++) o.options[0]=null;
		o.options[0]=new Option('','');
		for (i=3; i < arr.length; i++) {
			arr2=(arr[i]).split('::');
			if (hasval) {val=arr[i].substr(arr2[0].length+2);}
			else val=arr[i];
			o.options[i-2]=new Option(lens_esc(arr2[0]),arr1+val);
		}
	}
	LensTo(dv,PHPLens_GetOffLeft(input),PHPLens_GetOffTop(input))
	LensShow(dv);
}


function PHPLens_FindObj(form,name)
{
var zform=eval('document.'+form);
var cnt,oname,len=name.length,obj;

	for(cnt=zform.elements.length; --cnt>=0;) {
		obj=zform.elements[cnt]
		if (obj && obj.name == name) return obj;
	}
	return false;
}
function PHPLens_GetVal(form,name)
{
var s,val;
	o=PHPLens_FindObj(form,name)
	if (!o.name) return '';
	if (o.options) {
	var opt=o.options[o.selectedIndex];
		if (opt.value) val=opt.value
		else val=opt.text
	} else if (o.value) val=o.value
	else val=o.text
	if (o) return _sepRS + name.substr(_prefixLen) + '::'+escape(''+val)+'::'+name.substr(_prefixLen-2,1);
	return '';
}

// version\tdb\tSQL\tMD5\tcol1name::col1val::col1type\tcol2name::col2val::col2type....
function PHPLens_Remote_Query(form,name,s)
{	
	jsrsExecute(_remoteQ,PHPLens_MyCallback,'PHPLens_Remote_Query',Array(form,name,s));
}

function PHPLens_MyCallback(ret)
{
var o,arr,arr2;
	arr=ret.split(_sepRS);
	if (arr.length<2) {alert(ret.replace(/\+/g,' '));return;}
	if (arr[0].length) alert(arr[0])
	o=PHPLens_FindObj(arr[1],arr[2]);
	if (!o) {o=PHPLens_FindObj(arr[1],arr[2]+'[]');noBlank=true;if (!o) return;}
	if (o.type == 'text') o.value =unescape(arr[3]);

	if ((o.type).substr(0,6) == 'select') {
	var max,text,val;
		max=o.options.length;
		for (i=0; i<max; i++) o.options[0]=null;
		
		for (i=3; i < arr.length; i++) {
			arr2=(arr[i]).split('::');
			if (arr2.length==1) text=lens_esc(arr2[0]);
			else text=lens_esc(arr2[1]);
			val=lens_esc(arr2[0]);
			o.options[o.options.length]=new Option(text,val);
		}
	}
}


function lens_dateauto(field, limit, next, evt, zmax) {
    evt = (evt) ? evt : event;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : 
        ((evt.which) ? evt.which : 0)), v=field.value;
	if (v > zmax) v=field.value=lens_last_dval;
	if (v.length>0 && v == 0 && limit < 0) v=field.value='01'
	if (charCode > 31 && (v.length == limit)) {
       // field.form.elements[next].focus( );
		if ((zmax == 31 || zmax == 12) && v == 0) {
	   		if (lens_last_dval != 0) field.value = lens_last_dval;
			else field.value = '01';
		}
		field.form.elements[next].select();
    }
}

function lens_datenum(evt,obj)
{
   lens_last_dval = obj.value;
   evt = (evt) ? evt : event;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : 
        ((evt.which) ? evt.which : 0));
	if (charCode > 31 && (charCode < 48 || charCode > 57))  return false;
	//if (obj.maxLength == (obj.value).length) obj.value = (obj.value).substr(0,(obj.value).length-1);
	return true;
}

function lens_onlynum(evt,decPt) {
    evt = (evt) ? evt : event;
    var charCode = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : 
        ((evt.which) ? evt.which : 0));
	
	if (!ie4) if (evt.keyCode == 37 || evt.keyCode == 39) return true; // left/right arrow
	if (decPt == -1) { // -/+ int
	 if (charCode > 31 && (charCode < 48 || charCode > 57) && // 0-9
			charCode != 43 && charCode != 45 ) // -/+
			return false;
	} if (decPt == 0) { // only +ve int
	 if (charCode > 31 && (charCode < 48 || charCode > 57) && // 0-9
			charCode != 43) // #
        return false;
	} else { // -/+ float
	    if (charCode > 31 && (charCode < 48 || charCode > 57) && // 0-9
		 charCode != 46 && charCode != 43 && charCode != 45 && charCode != decPt)  // . + -
        return false;
    }
    return true;
}

