/*******************************************************************
  GLOBAL GX OBJECT
*******************************************************************/
var gx=new Object()
gx.ie55=/(msie 5\.[56789])|(msie 6\.)/i.test(navigator.userAgent)
gx.go=function(u,t){
  var id=document.uniqueID
  document.body.insertAdjacentHTML('beforeEnd','<A href="'+u+'" id="'+id+'" target="'+(t?t:'')+'"></A>')
  try{da[id].click()}catch(e){} // if window.onbeforeunload cancelled event, da[id].click() generates 'unspecified error'
}
gx.close=function(){if(da.btnClose){da.btnClose.click()}}
gx.alert=function(s){if(s)alert(s)}
gx.dialog=function(title, body, opt){ // opt = buttons=ok,close;width=100;height=200;
  var argv=[]; argv['title']=title; argv['body']=body; argv['theme']=this.style.path; argv['buttons']=getVField(opt,'buttons',';')
  var w=getVField(opt,'width',';'), h=getVField(opt,'height',';')
  return showModalDialog('/gx/exec/xDialog.asp', argv, 'font:10px verdana; dialogWidth:'+(w?w:300)+'px; dialogHeight:'+(h?h:210)+'px; status:0; scroll:0; help:0')
}
gx.loading=function(s){
  if(!da['gx_loading'])document.body.insertAdjacentHTML('beforeEnd',
    '<table id=gx_loading class=xbox-body '
    +'style="position:absolute;width:160;height:60;'
    +'top:expression((document.body.clientHeight-60)/2);'
    +'left:expression((document.body.clientWidth-160)/2);'
    +'border:1 solid silver;'
    +'filter:alpha(opacity=70);'
    +'">'
    +'<tr><td align=center></table>')
  da['gx_loading'].cells(0).innerHTML=s&&typeof s!='undefined'?s:'Loading...'
  da['gx_loading'].style.visibility=s||typeof s=='undefined'?'visible':'hidden'
}
gx.resizeToStep = 1 // 1 for no animation, 4 for animation
gx.resizeTo=function(w,h,n){
  var isDialog=window.dialogWidth
  function pi(s){return parseInt(s,10)}
  function resizeBy(w,h){
    if(isDialog){
      window.dialogWidth=(pi(window.dialogWidth)+w)+'px'
      window.dialogHeight=(pi(window.dialogHeight)+h)+'px'
    }else{window.resizeBy(w,h)}
  }
  function getW(){return isDialog?pi(window.dialogWidth):document.body.clientWidth}
  function getH(){return document.body.clientHeight}
  var bw=getW(), bh=getH()
  if(!w)w=bw; if(!h)h=bh; if(!n)n=1 // n prevents infinite loop
  var dw=Math.ceil((w-bw)/this.resizeToStep), dh=Math.ceil((h-bh)/this.resizeToStep)
  if(Math.abs(dw)<=2 && Math.abs(dh)<=2 && n==1) return // ignore if resizing within 2 pix (caused by mismatches in window.open() & document.body.clientWidth)
  if(n>3)try{ // animate on 3rd tic -> smoother
    resizeBy(dw, dh)
    if((bw==getW()&&dw) || (bh==getH()&&dh)){ // if @ edge of screen, move & resize
      moveBy(-dw, -dh)
      resizeBy(dw, dh)
    }
  }catch(e){}
  if((dw || dh) && n<25){
    window.clearTimeout(gx.timerID)
    gx.timerID = setTimeout('gx.resizeTo('+w+','+h+','+(n+1)+')',50)
  }
}
gx.trace=function(s){
  if(!this.trace.div){
    this.trace.div=document.createElement('TEXTAREA')
    this.trace.div.style.cssText="position:absolute;width:180;height:300;top:expression(document.body.clientHeight-300);left:expression(document.body.clientWidth-180);background:white;border:1 solid dodgerblue;overflow:auto"
    this.trace.div.ondblclick=function(){this.style.display='none'}
    document.body.insertAdjacentElement('beforeEnd',this.trace.div)
  }
  this.trace.div.style.display='inline'
  //gx.trace.div.innerHTML+=s+'<br>'
  gx.trace.div.value+=s+'\r\n'
/*
  if(!this.trace.popup){this.trace.popup=window.open('/sys/trace.htm','','width=240,height=300,titlebar=0')}
  this.trace.popup.document.all.log.innerHTML+=s+'<br>'
*/
}
gKillList.add('if(gx.trace.popup&&!gx.trace.popup.closed)gx.trace.popup.close()')

gx.mbox=function(s,x,f){if(s)dw('<div class=mbox '+x+'>'+(f?s.replace(/<br>.*$/g,''):s)+'</div>')}
gx.ssbar=function(sCreatedBy, sCreatedOn, sModifiedBy, sModifiedOn, sFormat){
  if (sCreatedOn) sCreatedBy = 'Created '+formatDate(sCreatedOn, sFormat, null, true)+(typeof lstUser=='undefined'?'':' by '+lstUser.valueText(sCreatedBy))
  if (sModifiedOn) sModifiedBy = 'Modified '+formatDate(sModifiedOn, sFormat, null, true)+(typeof lstUser=='undefined'?'':' by '+lstUser.valueText(sModifiedBy))
  if (sModifiedOn)
    return '<img align=absmiddle src=/sys/icons/dialog.gif title="Show more record information" style=cursor:hand onclick=toggleObj(da.hteModifiedBy,da.hteCreatedBy) width=16 height=16> '+
      '<div id=hteModifiedBy style=display:inline>'+sModifiedBy+'</div>'+
      '<div id=hteCreatedBy style=display:none>'+sCreatedBy+'</div>'
  else
    return '<img align=absmiddle src=/sys/1x1.gif width=1 height=16>'+sCreatedBy
}
/*
gx.dbxNav=function(n){
  function btn(x,x2){return'<input class=xbtn50 type=submit name=cmDBXGo value="'+x+'" onclick=spt.reset();this.form.dbxPage.value='+x2+'>'}
  if(n>1)dw(btn('|<',1)+btn('<','dbxNavPage.move(-1)')+btn('>','dbxNavPage.move(1)')+btn('>|','dbxNavPage.pageCount'))
}
*/
gx.xbox=function(id,title,body){ // reload class=xbox HTML objects, e.g. gx.xbox('hteTask1','New Title','hteTask1_body1')
  showObj(da[id])
  if(typeof da[id+'_body']!='undefined'){
    if(title)da[id+'_title'].innerHTML = title
    da[id+'_body'].innerHTML = eval(body)
  }else{
    setTimeout("gx.xbox('"+id+"','"+title+"','"+body+"')")
  }
}
// gx._debug = true
gx.smartHeight=function(o,offset){
  // return document.body.clientHeight-o.offsetTop+(offset?offset:0)
  var offsetTop = o.offsetTop
//  var lastTableOffsetTop = 0, s=''
  while(o.parentElement!=document.body){
    o = o.parentElement
    if(o.tagName != 'TR' && o.tagName != 'TBODY' // ignore tags whose offsetTop is accounted for by their child Element
//    && (o.tagName == 'TABLE' && lastTableOffsetTop != o.offsetTop) // Kludge for DBX_setup
    ) 
      offsetTop += o.offsetTop
//    if(o.tagName == 'TABLE') lastTableOffsetTop = o.offsetTop
    // s += o.tagName + ':' + o.offsetTop + ' => '+offsetTop + '\r'
  }
  // if(gx._debug) gx._debug = confirm(s)
  // return document.body.clientHeight-offsetTop+(offset?offset:0)
  return document.documentElement.clientHeight-offsetTop+(offset?offset:0)
}
gx.smartWidth=function(o,offset){return document.body.scrollWidth-(o?o.offsetLeft:1)+(offset?offset:0)}
gx.setWidth=function(oS,o,offset){oS.style.width=document.body.clientWidth-(o?o.offsetLeft:1)+(offset?offset:0)}
gx.setHeight=function(oS,o,offset){oS.style.height=this.smartHeight(o,offset)}

gx.banner=new Object()
gx.banner.innerHTML=''

gx.toolbar=new Object()
gx.toolbar.logo=''
gx.toolbar.onBeforeLogout=function(){return confirm('Quit and Logout?')} // overload to intercept Logout button
gx.toolbar.onBeforeHome=function(){return true} // overload to intercept Home button

gx.vbar=new Object()
gx.vbar.logoHTML=''

gx.style=new Object()
gx.style.arTheme=['','Default Theme','/sys/thm/aqua','Aqua','/sys/thm/lunaXP','Luna XP','/sys/thm/silverXP','Silver XP','/sys/thm/design07','Design 07']
gx.style.path='/sys/thm/default'
gx.style.set=function(s){
  if(!s)return
  gx.style.path=s
  dw('<link rel=stylesheet type=text/css href="'+s+'/xstyles.css">')
//  gx.xbtn.init() // put into navCool.asp // 1. default here, 2. override in global/local header, 3. gx.xbtn.init()
}

gx.gxapp=function(s){return typeof gxapp=='undefined' ? true : gxapp.toString().indexOf(s)>=0} // true if s is found in gxapp1..6, e.g. s is subscribed

gx.studio = []

gx.xbtn=new Object()
gx.xbtn.init=function(){ // create global vars & loadImages for xbtn50,70,100
  var ar=['xbtn50','xbtn70','xbtn100']
  for(var t='',i=0;i<ar.length;i++){
    eval(ar[i]+'a="'+gx.style.path+'/'+ar[i]+'a.gif"')
    eval(ar[i]+'b="'+gx.style.path+'/'+ar[i]+'b.gif"')
    eval(ar[i]+'c="'+gx.style.path+'/'+ar[i]+'c.gif"')
    t+='.'+ar[i]+'{background:url('+gx.style.path+'/'+ar[i]+'a.gif)}'
    // loadImages(gx.xbtn.background(ar[i],'over'), gx.xbtn.background(ar[i],'down'))
  }
  dw('<style>'+t+'</style>')
}
gx.xbtn.background=function(c,s){return gx.style.path+'/'+c+(s=='over'?'b':(s=='down'?'c':'a'))+'.gif'}

gx.xtab=new Object()
gx.xtab.skin='SYS/xptabs1'

gx.exIML=function(s,r,ar,tagB,tagE){ // Very basic IML Processing (only rs matching & no recursion)
  function rs(s){if(r)if(r.selectSingleNode(s))return r.selectSingleNode(s).text}
  if(!tagB)tagB='{#'
  if(!tagE)tagE='#}'
  var i = 0, tag, val, p2, p1 = s.indexOf(tagB)
  var o = s.substr(0,p1)
  while(p1>=0 && i++<2){
    p1 += 2                  // pt to start of tagB content
    p2 = s.indexOf(tagE,p1)  // pt to start of tagE
    tag = s.substring(p1,p2) // fetch tag between 2 pts
    val = rs(tag)            // fetch tag value
    p2 += 2                  // pt to end of tagE
    p1 = s.indexOf(tagB,p2)  // pt to next tagB
    o+=val
    if(p1>=0) o+=s.substring(p2,p1)
  }
  return o + s.substr(p2)
}

// BACKGROUND TIMEOUT PING -----------------------------------------------------
// funny stuff: if used this.keepAliveInterval instead of gx.keepAliveInterval, 2 setInverval's are called
gx.keepAlive = function(){
  if(typeof gx.keepAliveInterval == 'undefined'){
    gx.keepAliveInterval = setInterval(gx.keepAlive, 15 * 60 * 1000)
    return
  }
  var http=new ActiveXObject("Microsoft.XMLHTTP")
  var sHref = window.location.href
  if(sHref.indexOf('https://') == 0){
    sHref = sHref.split('?')[0]
    sHref = sHref.substring(0, sHref.lastIndexOf('/')) + '/' // return http://abc.com/path1 from http://abc.com/path1/script1.asp
  }else{
    var sHref = ''
  }
  http.Open("GET", sHref + 'keepAlive.asp?'+(new Date()), false)
  try{http.Send()}catch(e){} // can generate error if network problem
  if(!window.opener && http.responseText!='true'){
    if(typeof gx.keepAliveWindow == 'undefined' // if already poped up
      || typeof gx.keepAliveWindow.document != 'object' // if popup was not closed
    ){
      gx.keepAliveWindow = openWindow('../users/login.asp?target=_self&start=../exec/popupAction.asp?noRefresh=true','login',410,210,'center')
      gKillList.add('try{gx.keepAliveWindow.close()}catch(e){}')
    }
    gx.keepAliveWindow.focus()
/*
  if(!gx.keepAliveWindow){
    gx.keepAliveWindow=document.createElement('IFRAME')
    gx.keepAliveWindow.style.cssText="position:absolute;width:410;height:210;top:expression((document.body.clientHeight-210)*2/5);left:expression((document.body.clientWidth-410)/2);background:white;border:1 solid dodgerblue;"
    gx.keepAliveWindow.border=0
    gx.keepAliveWindow.frameBorder='no'
    gx.keepAliveWindow.scrolling='no'
    document.body.insertAdjacentElement('beforeEnd',gx.keepAliveWindow)
  }
  gx.keepAliveWindow.src = '../users/login.asp?target=_self&start=popupAction.asp?noRefresh=true'
*/
  }
}
//gx.keepAlive()

// GLOBAL KEYBOARD SHORTCUTS ---------------------------------------------------
gx.kb=new Object()
gx.kb.keys = [ // concat other key bindings
  ['ctrl',81,'btnClose'], // ctrl-q
  ['ctrl',83,'btnSave'], // ctrl-s
  ['',13,'dbxBtnFind']
]
gx.kb.onkeydown = function(){
	var ev=window.event, kb=gx.kb.keys
//	if(ev.keyCode==81&&ev.ctrlKey) if(da.btnClose)da.btnClose.click() // ctrl-q
	for(var i=0; i<kb.length; i++)
	  if(ev.keyCode==kb[i][1] && (kb[i][0]=='ctrl' ? ev.ctrlKey : true)) if(da[kb[i][2]]){da[kb[i][2]].click(); return false}
}
if (ie) document.onkeydown=gx.kb.onkeydown

/*******************************************************************
  GX Hemingway Object
*******************************************************************/
var gxh=[]
gxh.get=function(s){return parseInt(this[s],10)}

/*******************************************************************
  Version Object
*******************************************************************/
function objVer(s){
  this.arVer=['','All / Default']
  this.arCharset=['Windows-1250','Default Language']
	var arVer=[]
		arVer['eng']=['E','ENG']
		arVer['cht']=['T','CHT']//['<img align=absmiddle border=0 src=/sys/ver_cht2.gif>','<img align=absmiddle border=0 src=/sys/ver_cht.gif>']
		arVer['chs']=['S','CHS']//['<img align=absmiddle border=0 src=/sys/ver_chs2.gif>','<img align=absmiddle border=0 src=/sys/ver_chs.gif>']
		arVer['utf']=['U','UTF']
		arVer['jap']=['J','JAP']
		arVer['kor']=['K','KOR']

  this.lang=function(n){return this.doc[n?n:0][0]}	// language
	this.path=function(n,d){
    if(n>this.doc.length-1)return'?'
    var s=this.doc[n?n:0][1]
    return s ? s + (d?d:''): s // path, if d is specified (e.g. '/') add it to end if s is not blank
  }
	this.desc=function(n){return this.doc[n?n:0][2]}	// description
	this.ltxt=function(n,n2){ // this.ltxt(''|'0'|'1'|...[,0|1]) -> language text(0|1) of version n
    if(!n&&parseInt(n)!=0)return'*'
    if(n>this.doc.length-1)return'?'
    var s = this.lang(parseInt(n,10))
    if(s.indexOf(',') >= 0){
      return getMField((n2?n2:0) + 1, s, ',') // new: utf-8,E,ENG|utf-8,J,JAP|...
    }else{
      return arVer[s][n2?n2:0] // old: eng|cht|chs|utf|...
    }
  }
  this.qtxt=function(n){return this.doc.length>1 ? this.ltxt(n) : ''} // questionable language text: print single char language representation if more than 1 language
  this.nav=function(s0,x,v){ // s0 = 'default.asp?cm=xxxForm&xid=[#@XID#]&ver={$VER$}', v = current ver to high-light
    if(typeof v == 'undefined') v = -1
    for(var s='',i=0;i<this.doc.length;i++){
      s+=s?' ':''
      if(i==v){
        s+='[<FONT '+(x?x:'')+'>'+this.ltxt(i,1)+'</FONT>]'
      }else{
        s+='[<A href="'+s0.replace(/VER/g,i)+'" '+(x?x:'')+'>'+this.ltxt(i,1)+'</A>]'
      }
    }
    return s
  }

	if(!s)s='eng||Default Version'
	this.doc=s.split('][') // lang|path|desc, lang=eng|cht|chs, path=''|cht|chs|..., desc=Long_Description
	for(var i=0;i<this.doc.length;i++)this.doc[i]=this.doc[i].split('|')
  for(var i=0;i<this.doc.length;i++) // create arVer & arCharset based on language definition s
    switch(this.lang(i)){
      case'eng':this.arVer=this.arVer.concat(['0','English']) // Western Alphabet ISO-8859-1
        this.arCharset=this.arCharset.concat(['iso-8859-1','English'])
        break
      case'cht':this.arVer=this.arVer.concat(['1','Traditional Chinese']) // BIG5
        this.arCharset=this.arCharset.concat(['big5','Traditional Chinese'])
        break
      case'chs':this.arVer=this.arVer.concat(['2','Simplified Chinese']) // GB2312
        this.arCharset=this.arCharset.concat(['gb2312','Simplified Chinese'])
        break
      case'utf':this.arVer=this.arVer.concat(['3','UTF-8'])
        this.arCharset=this.arCharset.concat(['utf-8','UTF-8'])
        break
      case'jap':this.arVer=this.arVer.concat(['4','Japanese']) // Shift_JIS
        this.arCharset=this.arCharset.concat(['Shift_JIS','Japanese'])
        break
      case'kor':this.arVer=this.arVer.concat(['5','Korean'])
        this.arCharset=this.arCharset.concat(['euc-kr','Korean'])
        break
      default:
        // this.arVer=['','All / Default'] is always predefined
        this.arVer=this.arVer.concat([((this.arVer.length/2)-1).toString(), this.desc(i)]) // def: utf-8,E,ENG||English
        this.arCharset=this.arCharset.concat([getMField(0, this.lang(i), ','), this.desc(i)])
        // Set 'Add / Default' to utf-8 if first definition of custom definition is utf-8
        if(this.arCharset[2].toLowerCase()=='utf-8') this.arCharset[0]='utf-8'  
        break
    }
	if(this.doc.length<=1)dw('<style>#verStuff{display:none}</style>')
}
/*
function remapAbsPathVer(obj,userRoot,v){
	remapAbsPath(obj,
		userRoot+(ver.path(v)==''?'':'/'+ver.path(v))+'/pic',
		userRoot+(ver.path(v)==''?'':'/'+ver.path(v))+'/bg',
		userRoot+(ver.path(v)==''?'':'/'+ver.path(v))+'/images')
}
*/

// --------------------------------------------------------------------
// CONTENT MODULE DEFINITIONS
// --------------------------------------------------------------------

//function objCm(key,pfx,edt){this.key=key;this.pfx=pfx;this.edt=edt}
//var	gCm = new Array()
//	gCm.add = function(key,pfx,edt){this[this.length]=new objCm(key,pfx,edt)}

//var	gCmTypeStatic = 0
//var gCmTypeDBX    = 4

//var	gCmLb = ['lbCmStatic','lbCmUsers','lbCmDBX']
//var	gCmLb = ['lbCmDBX']
//gCm.add(gCmTypeStatic,"STA:","../cmStatic/editStatic.asp")
//gCm.add(gCmTypeUsers,"USR:","../cmUsers/editUsers.asp")
//gCm.add(gCmTypeDBX,"DBX:","../cmDb/editDBX.asp")

var arCmIML = [
  '[$','[#',
  '$]','#]'
]

/*
function remapAbsPath(obj,pathPic,pathBg,pathImg) {
	tmp = obj.innerHTML
//	tmp = tmp.replace(/"pic/gi, '"'+pathPic)
//	tmp = tmp.replace(/background=bg/gi, 'background='+pathBg)
//	tmp = tmp.replace(/background=pic/gi, 'background='+pathPic)
	if(pathImg) tmp = tmp.replace(/"images/gi, '"'+pathImg)
	obj.innerHTML = tmp
}
*/

/*
function remapPathS2D(txt,pathPic,pathBg,pathImg,pathAny) {
	var pathRoot = 'http://'+window.location.hostname
	if(pathAny&&pathAny!=''){
		txt = txt.replace(/src="/gi,'src="'+pathRoot+pathAny).replace(/background=/gi,'background='+pathRoot+pathAny)
	} else {
//		txt = txt.replace(/"Main.asp/g, '"'+pathRoot+'/Main.asp')
		txt = replace(txt,'"/sys/','"'+pathRoot+'/sys/')
//		txt = replace(txt,'"pic', '"'+pathRoot+pathPic)
//		txt = replace(txt,'background=bg', 'background='+pathRoot+pathBg)
//		txt = replace(txt,'background=pic', 'background='+pathRoot+pathPic)
		if(pathImg)txt = replace(txt,'"images', '"'+pathRoot+pathImg)
	}
	return txt
}

function remapPathD2S(txt,pathPic,pathBg,pathImg,pathAny) {
	var pathRoot = 'http://'+window.location.hostname
	txt = replace(txt, pathRoot+'/#','#') // this is obsolete? because should map pathRoot+xroot, where xroot is /100/n/
//	txt = replace(txt, '"'+pathRoot+'/Main.asp','"Main.asp')
	txt = replace(txt,'"'+pathRoot+'/sys/','"/sys/')
//	txt = replace(txt, '"'+pathRoot+pathPic, '"pic' )
	if(pathImg)txt = replace(txt, '"'+pathRoot+pathImg, '"images' )
	if(pathAny&&pathAny!='')txt = replace(replace(txt, 'src="'+pathRoot+pathAny, 'src="'), 'background='+pathRoot+pathAny, 'background=')
//	txt = replace(txt, 'background='+pathRoot+pathBg, 'background=bg')
//	txt = replace(txt, 'background='+pathRoot+pathPic, 'background=pic')
	return txt
}
*/

// --------------------------------------------------------------------
// IML 2.0
// --------------------------------------------------------------------

var s2c = 0 // exIML server to client
var c2s = 1 // exIML client to server

function replace(txt,s1,s2) {
	var i=0,pfx,sfx,len=s1.length,pos=txt.indexOf(s1)
	while (pos!=-1) {
		pfx=txt.substring(0,pos)
		sfx=txt.substr(pos+len)
		txt=pfx+s2+sfx
		pos=txt.indexOf(s1,pfx.length+s2.length)
		if(i++>1000){alert('replace > 1000'); return txt}
	}
	return txt
}

function exIML(key,ar,txt){
	if (key==s2c)
		for(var i=0;i<ar.length;i+=2)txt=replace(txt,ar[i+1],ar[i])
	else 
		for(var i=0;i<ar.length;i+=2)txt=replace(txt,ar[i],ar[i+1])
	return txt
}

// --------------------------------------------------------------------
// IML TAG VALIDATOR
// --------------------------------------------------------------------

function imlValidate(obj){ // check open/close tag pairs, return true if no error
	var txt=obj.value
	function imlSelect(obj,sel){ // select and move to view 'sel' from 'obj'
		if(obj.style.display=='none'){alert('Switch to source mode to view error hi-lite.');return}
		var rng=obj.createTextRange()
		rng.findText(sel,-1); rng.select(); rng.scrollIntoView(); obj.focus()
	}
	function imlChkTag(txt,tagB,tagE){
		var pos=txt.lastIndexOf(tagB)
		if (pos==-1) return true
		pos=txt.indexOf(tagE,pos+tagE.length)
		if (pos==-1) alert('Tag '+tagB+' is missing close tag '+tagE+'.')
		return pos>=0
	}
	if (!imlChkTag(txt,'<!'+'--','-->')) { imlSelect(obj,'<!'+'--'); return false }
	if (!imlChkTag(txt,"<##","##>")) { imlSelect(obj,"<##"); return false }
	if (!imlChkTag(txt,"<#","#>")) { imlSelect(obj,"<#"); return false }
	if (!imlChkTag(txt,"[#","#]")) { imlSelect(obj,"[#"); return false }
	return true
}

// --------------------------------------------------------------------
// TOOLBAR (Horizontal & Vertical)
// --------------------------------------------------------------------

function objToolbar(pfx){
  this.url=[]; this.state=[]; this.txt=[]; this.i=0; this.pfx=(pfx?pfx:'')
	this.add=function(tn,txt,icon,url,state){
		var args=this.add.arguments
    if(this.i==0&&icon)this.add('item','','','') // if new bar & 1st add is not separator -> make sure start with separator
    if(tn=='item'){this.url[this.i]=url;this.txt[this.i]=(icon==''?'':'<img align=absmiddle src="'+icon+'"> ')+txt;this.state[this.i++]=state;return(true)}
		for(var i=0;i<args.length;i++)
			switch (args[i]) {
				case ('color'): this.add('item','Pick Color','../images/iconPalette.gif','javascript:dlgColor()'); break;
				case ('skin'): this.add('item','Skin Library','../images/iconSkinBox.gif',"javascript:openWindow('../customize/skinBox.asp','skin',360,320,'center','scrollbars')"); break;
				case ('save'): this.add('item','Save','../images/iconSave.gif',"javascript:if(da.btnSave)da.btnSave.click()"); break;
				case ('preview'): this.add('item','Preview Changes','../images/iconPreview.gif',"javascript:if(da.btnPreview)da.btnPreview.click()"); break;
				case ('separator'): this.add('item','','',''); break;
			}
	}
	this.out=function(v){ // v=='v' to put into vertical mode
		var out='',mtd='<td style="border:1 outset;padding:0;background-color:silver;"><img src=/sys/1x1.gif></td>' // spacer
		for(var i in this.url){
			out+=(v=='v'?'<tr>':'')+
				(this.txt[i]==''?mtd:'<td class=xbtn '+
					(this.state[i]?this.state[i]+' ':'')+ // anything in state field is passed as is (i.e. now more of extra rather than state)
					'onclick="'+
						(this.url[i].indexOf('javascript:')>=0 ? this.url[i].replace(/javascript:/,'')+'">' : 'da.tb_'+this.pfx+i+'.click()"><a id=tb_'+this.pfx+i+' href="'+this.url[i]+'"></a>')+
					this.txt[i]+'</td>')+
				(v=='v'?'</tr>':'')
      }
		return out
  }
	this.toolbar=function(v){return '<table'+(v=='v'?' width=100%':'')+' callpadding=2><tr>'+this.out(v)+'</tr></table>'}
}


/*******************************************************************************
  getIcon
*******************************************************************************/
function getIcon(s,type,filenameOnly){
  var src='/sys/icons/'
  if(typeof type==undefined) type=''
  switch(s.toLowerCase()){
    case 'html': s='htm'
    case 'htm':
    case 'txt':
    case 'pdf':
    case 'doc':
    case 'xls':
    case 'ppt': src+='doc_'+s+'.gif'; break
    case 'gif': s='jpg'
    case 'jpg': src+='doc_'+s+'.gif'; break
    default: 
      if(type == 'doc')
        src += 'doc.gif'
      else
        src = '/sys/1x1.gif'
  }
  if(filenameOnly)
    return src
  else
    return '<img align=absmiddle src="'+src+'" border=0 width=16 height=16>'
}

/*******************************************************************************
  attachmentTR(name, fieldValue, xpath, default_title, sExtraHTML)
  attachmentTR('file1','[#@FILE1#]','/ufiles/500/','Original Resume','<font color=red>++</font>')
  <tr>
    <td><input name={name}_title value="{title|default_title}">
    <td><img src=/sys/icons/delete.gif style=cursor:hand title="Mark / Un-mark document for deletin"
          onclick="if(fmCmDBX.{name}_del.checked){
                     fmCmDBX.{name}_del.checked=false
                     da.{name}_link.style.textDecoration=''
                   }else{
                     if(confirm('Delete {title|default_title} on Save?')){
                       fmCmDBX.{name}_del.checked=true
                       da.{name}_link.style.textDecoration='line-through'
                     }
                   }"
          >
        <input type=checkbox name={name}_del style=display:none>
    <td>
      <A class=xtag href="{xpath}{doc}" src="/sys/icons/doc_{xxx}.gif" target=_blank id={name}_link>
        {filedate}, {filesize}kB
      </A>
    <td>
      <input type=file name={name}><input type=hidden name={name}_ext>
*******************************************************************************/
function attachmentTR(n,s,xpath,title,x){ // s = 'filename|filedate|filesize|title'
  var filename = getMField(0,s)
  if(getMField(3,s)) title = getMField(3,s)
  return '<TR>'+
    '<TD nowrap><input type=file name='+n+' size=33><input type=hidden name='+n+'_ext> '+(x?x:'')+
    '<TD>'+
      (filename ?
        '<img src=/sys/icons/delete.gif style=cursor:hand title="Mark / Un-mark document for deletion"'+
          'onclick="if(fmCmDBX.'+n+'_del.checked){'+
              'fmCmDBX.'+n+'_del.checked=false;'+
              'da.'+n+'_link.style.textDecoration=\'\';'+
            '}else{'+
              'if(confirm(\'Delete '+title.replace(new RegExp('&#'+'039;'),'\\\'')+' on save?\')){'+
                'fmCmDBX.'+n+'_del.checked=true;'+
                'da.'+n+'_link.style.textDecoration=\'line-through\';'+
              '}'+
            '}'+
          '">'+
        '<input type=checkbox name='+n+'_del style=display:none>'
      : '')+
    '<TD nowrap>'+
      (filename ? ATag(xpath+filename,
        getIcon(getExtension(filename), 'doc', true),
        'txt:'+getMField(1,s).replace(/:\d+ /,' ')+', '+Math.ceil(parseInt(getMField(2,s),10)/1000)+' kB',
        16, 16, 'target=_blank id='+n+'_link') + '&nbsp;'
      : '')
}

/*******************************************************************************
  Usage: Overload fmCmDBX dbxOnSubmit() if attachmentTR() is called
    function dbxOnSubmit(){
      return attachmentOnSubmit(1)
    }
*******************************************************************************/
function attachmentOnSubmit(n){
  for(var i=1, isUpload=false; i<=n; i++){
    fmCmDBX['xfile'+i+'_ext'].value=fmCmDBX['xfile'+i].value.replace(/^.*\./g,'')
    isUpload |= fmCmDBX['xfile'+i].value!=''
  }
  if(isUpload)gx.loading('Uploading file(s)...')
  return document.fmCmDBX._onsubmit()
}

// --------------------------------------------------------------------
// LOOK & FEEL
// --------------------------------------------------------------------
/*
document.write('<style>'+
'.gxFrame {background:buttonFace;border-top:1 solid silver;width:100%}'+
'.gxPanel {display:none;text-align:center;width:160;padding-top:3;border-left:2 outset silver;background:buttonFace}'+
'.xhead   {font-family:tahoma;font-size:14px; font-weight:bolder;}'+
'SELECT,INPUT,TABLE{font-family:verdana,arial;font-size:11px}'+
'</style>')
*/
