
	if(!document.mp)	document.mp={};
	if(!document.mp.form)	document.mp.form={};

	// input data characters
	var num_keyin_str= '1234567890' ;
	var hex_num_keyin_str= num_keyin_str+'abcdefABCDEF' ;
	var uppercase_char_keyin_str= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ;
	var lowercase_char_keyin_str= 'abcdefghijklmnopqrstuvwxyz' ;
	var char_keyin_str=uppercase_char_keyin_str+lowercase_char_keyin_str;
	var char_num_keyin_str=char_keyin_str+num_keyin_str;
	var idno_keyin_str=char_num_keyin_str;
	var host_keyin_str=char_num_keyin_str+'.-_';
	var email_keyin_str=host_keyin_str+'@';

/* ****************************************
	input_only -- 限制輸入欄位只能輸入特定字元。
*/
	function input_only( event,strV, editkeys )	{
		/*
			strV - 允許輸入欄位的字元所串成的字串。

				系統內建以下幾個字串供選用

					變數名稱								說明				內容值
					-------------------------------		--------------	------------------------------------------
					num_keyin_str						數字				'1234567890'
					uppercase_char_keyin_str	大寫英文字		'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
					lowercase_char_keyin_str	小寫英文字		'abcdefghijklmnopqrstuvwxyz'
					char_keyin_str						英文字			uppercase_char_keyin_str+lowercase_char_keyin_str
					char_num_keyin_str			英文字與數字	char_keyin_str+num_keyin_str
					idno_keyin_str						身分證字號		char_num_keyin_str
					host_keyin_str						電腦主機名稱	char_num_keyin_str+'.-_'
					email_keyin_str					E-mail 信箱	host_keyin_str+'@'

		*/
		if( window.event )	{	// MSIE
			return ( strV.indexOf( String.fromCharCode(event.keyCode) )>=0 );
			// none control-key event
		}	else	{	//	FF
			if ( strV.indexOf( String.fromCharCode(event.which) )>=0 )	return true;
			if ( editkeys && ( event.keyCode )>0 )	return true;
			return false;
		}
	}

	function select_value( obj )	{
		if ( obj.selectedIndex==-1 )	return null;
		return obj.options[ obj.selectedIndex ].value;
	}

	function check_empty( obj, name, ename )	{
		/*
			obj - 輸入欄位。
			name - 輸入欄位的名稱。
			傳回 - 若輸入欄位內容為空字串，則傳回錯誤訊息；否則傳回空字串。
		*/
		if( obj.value=='' ) return '欄位 ['+name+'] 不得為空白 You must fill in ['+ename+'].\n';
		return '';
	}

	function check_numeric( obj, name, ename )	{
		var ValidChars = "0123456789.";
		var IsNumber=true;
		var Char;
		sText=obj.value;
		for (i = 0; i < sText.length && IsNumber == true; i++)	{
			Char = sText.charAt(i);
			if (ValidChars.indexOf(Char) == -1)	{
				IsNumber = false;
			}
		}
		if( !IsNumber ) return '欄位 ['+name+'] 必須為數字 ['+ename+'] must be numeric.\n';
		return '';
		return IsNumber;
	}

	var idno_regexp = /^[A-Z][0-9]{9}$/;

/* ****************************************
	qualified_idno -- 檢查身分證字號是否合格。
*/
	function qualified_idno( idno, sex )	{
		/*
			idno - 身分證字號字串
			sex - 性別
				註 : 為了不排斥變性人，所以改為不檢查性別與身分證字號的性別編碼。

			傳回 - 若身分證字號不合格，則傳回 false ；否則傳回 true。
		*/
		if( !idno_regexp.test(idno) )	return false;
		var idno_char0_verify=[	10 ,	11 ,	12 ,	13 ,	14 ,	15 ,	16 ,	17 ,	34 ,	18 ,	19 ,	20 ,	21 ,	22 ,	35 ,	23 ,	24 ,	25 ,	26 ,	27 ,	28 ,	29 ,	32 ,	30 ,	31 ,	33];
		var idno_pow_verify=[	1, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1 ];
		if( idno.length!=10 )	return false;
		if( !value_only( idno.charAt(0), uppercase_char_keyin_str ) )	return false;
		if( !value_only( idno.charAt(1), '12' ) )	return false;
/*
		不排斥變性人所以改掉了
		if ( sex!='' )	{
			if( idno.charAt(1)=='1' && sex!='M' )	return false;
			if( idno.charAt(1)=='0' && sex!='F' )	return false;
		}
*/
		if( !value_only( idno.substr(1), num_keyin_str ) )	return false;
		char01_num=idno_char0_verify[ idno.charCodeAt(0)-"A".charCodeAt(0) ];
		verify_arr=new Array(11);
		verify_arr[0]=Math.floor( char01_num / 10 );
		verify_arr[1]=char01_num % 10;
		for ( i=2; i<11 ;i++ )	{
			verify_arr[i]=idno.charAt(i-1);
		}
		check_sum=0;
		for( i=0; i<11;i++)	{
			check_sum+=idno_pow_verify[i]*verify_arr[i];
		}
		return ( ( check_sum%10)==0 );
	}

/* ****************************************
	value_only -- 檢查字串內的字元是否為所指定的某些字元。
*/
	function value_only( instr, vstr )	{
		/*
			instr - 要檢查的字串
			vstr - 指定範圍內的的字元串

				系統內建以下幾個字串供選用 :

					變數名稱								說明				內容值
					-------------------------------		--------------	------------------------------------------
					num_keyin_str						數字				'1234567890'
					uppercase_char_keyin_str	大寫英文字		'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
					lowercase_char_keyin_str	小寫英文字		'abcdefghijklmnopqrstuvwxyz'
					char_keyin_str						英文字			uppercase_char_keyin_str+lowercase_char_keyin_str
					char_num_keyin_str			英文字與數字	char_keyin_str+num_keyin_str
					idno_keyin_str						身分證字號		char_num_keyin_str
					host_keyin_str						電腦主機名稱	char_num_keyin_str+'.-_'
					email_keyin_str					E-mail 信箱	host_keyin_str+'@'

			傳回 - 若instr 字串內的字元皆為所指定的 vstr 內的字元則傳回 true；否則傳回 false。
		*/
		for( i=0; i<instr.length; i++ )
			if( vstr.indexOf( instr.charAt(i) )<0 ) return false;
		return true;
	}

/* ****************************************
	qualified_date -- 檢查日期輸入欄位內容是否合格。
*/
	function qualified_date( date )	 {
		/*
			date - 日期輸入欄位
			name - 日期輸入欄位的名稱
			not_empty - 若為 true ，日期輸入不得為空字串，否則視為錯誤；若為 false 則允許日期輸入為空字串。
			傳回 - 若日期輸入欄位內容不是合格的日期，則傳回錯誤訊息；否則傳回空字串。
		*/
		date_part=date.match( /(\d+)-(\d+)-(\d+)/ );
		if( date_part==null )	return false;
		if( date_part.length!=4)	return false;
		year= date_part[1];
		if( year<=0 )	 return false;
		month= date_part[2];
		if( month<1 || month>12 )	 return false;
		mday= date_part[3];
		if( mday<1 || mday>last_mday( year, month ) )	 return false;
		return true;
	}


/* ****************************************
	last_mday -- 指定年月的最後一天(或該月天數)。
*/
	function last_mday( year , month )	{
		/*
			year - 西元年
			month - 月份
			傳回 - 西元 year 年 month 月的最後一天(或該月天數)。
		*/
		var l_mday=[ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
		return ( month!=2 )?( l_mday[month-1] ):( ( (year%4)==0 )?( ( (year%100)==0 )?(( (year%400)==0 )?29:28):29):28);
	}

/* ****************************************
	qualified_email -- 檢查 E-mail 輸入欄位內容是否合格。
*/
	function qualified_email( email )	 {
		/*
			email - E-mail 輸入欄位
			傳回 - 若 E-mail 輸入欄位內容不是合格的 E-mail，則傳回 false；否則 true。
		*/
		if( email=='' ) return true;
		email_part=email.match( /(.+)@(.+)/ );
		if( email_part==null )	return false;
		account= email_part[1];
		host= email_part[2];
		if( !value_only( account, host_keyin_str ) )	return false;
		if( !value_only( host, host_keyin_str ) )	return false;
		return true;
	}

/* ****************************************
*/
	function __refresh_date_chooser( i,date )	{
			var jajax = new Jajax();
			jajax.onreadystatechange = function ()	{
				try	{
					if (jajax.XMLHttpRequestObject.readyState == 4 &&
						jajax.XMLHttpRequestObject.status == 200)	{
							var dinput=document.mp.form.DateInput[i];
							var sname=dinput.name.replace('[','_l_');
							sname=sname.replace(']','_r_');
							document.getElementById('__date_chooser_'+dinput.formname+'_'+sname ).innerHTML=jajax.XMLHttpRequestObject.responseText;
					}
				}	catch(e){}
			}
			jajax.get( '/util/DateChooser.php?ind='+i+'&date='+date );
	}

	function __click_date_chooser( i,date,close )	{
		var dinput=document.mp.form.DateInput[i];
		var changed=(dinput.value!=date);
		dinput.value=date;
		__refresh_date_chooser( i, dinput.value );
		if( close )	{
			var sname=dinput.name.replace('[','_l_');
			sname=sname.replace(']','_r_');
			var dchooser=document.getElementById('__date_chooser_'+dinput.formname+'_'+sname);
			dchooser.style.display='none';
		}
		if( changed && dinput.onchange )	dinput.onchange();
	}
/* ****************************************
*/
	function __refresh_country_chooser( i,country_id,continent_id )	{
			var jajax = new Jajax();
			jajax.onreadystatechange = function ()	{
				try	{
					if (jajax.XMLHttpRequestObject.readyState == 4 &&
						jajax.XMLHttpRequestObject.status == 200)	{
							var dinput=document.mp.form.CountryChooser[i];
							document.getElementById('__country_chooser_'+dinput.formname+'_'+dinput.name ).innerHTML=jajax.XMLHttpRequestObject.responseText;
					}
				}	catch(e){}
			}
			jajax.get( '/util/CountryChooser.php?ind='+i+'&country_id='+country_id+'&continent_id='+continent_id );
	}

	function __refresh_country_chooser_pane( i )	{
			var jajax = new Jajax();
			jajax.onreadystatechange = function ()	{
				try	{
					if (jajax.XMLHttpRequestObject.readyState == 4 &&
						jajax.XMLHttpRequestObject.status == 200)	{
							var dinput=document.mp.form.CountryChooser[i];
							document.getElementById('__country_chooser_pane_'+dinput.formname+'_'+dinput.name ).innerHTML=jajax.XMLHttpRequestObject.responseText;
					}
				}	catch(e){}
			}
			var country_id=document.mp.form.CountryChooser[i].value;
			jajax.get( '/util/CountryChooserPane.php?country_id='+country_id );
	}

	function __display_div__( divname )	{
		with ( document.mp.form )	{
			for ( i=0; i<divs.length ;i++ )	{
				var div=document.getElementById( divs[i] );
				if( divs[i]==divname )	{
					div.style.display=( div.style.display=='none' )?'block':'none';
				}	else	{
					div.style.display='none';
				}
			}
		}
	}

/* ****************************************
*/
	function __refresh_address_input( i, town, trigger_onchange )	{
			var jajax = new Jajax();
			jajax.onreadystatechange = function ()	{
				try	{
					if (jajax.XMLHttpRequestObject.readyState == 4 &&
						jajax.XMLHttpRequestObject.status == 200)	{
							var xmlDoc = jajax.XMLHttpRequestObject.responseXML;
							if(xmlDoc.documentElement==null)	return;
							var root = xmlDoc.documentElement;
							var dinput=document.mp.form.AddressInput[i];
							var twn=dinput.twn;
							twn.options.length=0;
							var ds = root.getElementsByTagName('town');
							for( var j=0;j<ds.length;j++)	{
								var d=ds[j];
								twn.options[j]=new Option(innerText(d),d.getAttribute('id') );
								twn.options[j].postno=d.getAttribute('postno');
								if (d.getAttribute('selected')!=null)	twn.selectedIndex=j;
							}
							__reform_address_input(i);
							__refresh_address_input_pane(i);
							if(dinput.onchange && trigger_onchange ) dinput.onchange();
					}
				}	catch(e){}
			}
			var dinput=document.mp.form.AddressInput[i];
			jajax.get( '/util/AddressInput.php?ind='+i+'&county='+select_value(dinput.cty)+'&name='+dinput.name+'&town='+encodeURIComponent(town ) );
	}

	function __reform_address_input( i )	{
		var dinput=document.mp.form.AddressInput[i];
		var cty=dinput.cty;
		var twn=dinput.twn;
		var addr=dinput.addr;
		dinput.value='['+twn.options[twn.selectedIndex].postno+']'+cty.options[cty.selectedIndex].text+'.'+twn.options[twn.selectedIndex].text+'.'+addr.value;
	}

	var __address_input_maps=[];
	var geocoder=null;
	function __refresh_address_input_pane( i )	{
			var dinput=document.mp.form.AddressInput[i];
			if( document.getElementById(dinput.map_div).style.display=='none' ) return;
			var cty=dinput.cty;
			var twn=dinput.twn;
			var addr=dinput.addr;
			var addr_text=cty.options[cty.selectedIndex].text+twn.options[twn.selectedIndex].text+addr.value;
			var map_pane=dinput.map_pane;
			if (__address_input_maps[map_pane]==undefined)	__initialize_address_input_map(map_pane);
			geocoder.getLatLng(
					addr_text,
					function(p) {
						if (!p) {
							alert("'" + addr_text + "' 地址找不到");
							__address_input_maps[map_pane].clearOverlays();
						} else {
							__address_input_maps[map_pane].openInfoWindowHtml(p,'<div style=\'font-size:9pt;\'><p style="font-size:9pt;">'+addr_text +'</span></p></div>');
							__address_input_maps[map_pane].setCenter(p, __address_input_maps[map_pane].getZoom());
						}
					}
				);
	}

	function __initialize_address_input_map(map_pane) {
		var default_point=new GLatLng( 23.7250, 120.8386 );
		var default_zoom=13;
		__address_input_maps[map_pane] = new GMap2(document.getElementById(map_pane), {draggableCursor:'crosshair'});
		__address_input_maps[map_pane].setMapType(G_HYBRID_MAP);
		__address_input_maps[map_pane].addControl(new GSmallMapControl());
		__address_input_maps[map_pane].enableContinuousZoom();
		__address_input_maps[map_pane].enableScrollWheelZoom();
		__address_input_maps[map_pane].setCenter(default_point, default_zoom);
		if(geocoder==null)	geocoder = new GClientGeocoder();
	}

	function insertAtCaret(obj, text) {
		try	{
			if(document.selection) { 
				var orgv=obj.value;
				obj.focus();
				obj.value=orgv;
				var orig = obj.value.replace(/\r\n/g, "\n"); 
				var range = document.selection.createRange(); 
		 
				if(range.parentElement() != obj) { 
					return false; 
				} 
		 
				range.text = text; 
				 
				var actual = tmp = obj.value.replace(/\r\n/g, "\n"); 
		 
				for(var diff = 0; diff < orig.length; diff++) { 
					if(orig.charAt(diff) != actual.charAt(diff)) break; 
				} 
		 
				for(var index = 0, start = 0;  
					tmp.match(text)  
						&& (tmp = tmp.replace(text, ""))  
						&& index <= diff;  
					index = start + text.length 
				) { 
					start = actual.indexOf(text, index); 
				} 
			} else if(obj.selectionStart) { 
				var start = obj.selectionStart; 
				var end   = obj.selectionEnd; 
		 
				obj.value = obj.value.substr(0, start)  
					+ text  
					+ obj.value.substr(end, obj.value.length); 
			} 
			 
			if(start != null) { 
				setCaretTo(obj, start + text.length); 
			} else { 
				obj.value += text; 
			} 
		}	catch(e)	{}
	} 
	 
	function setCaretTo(obj, pos) { 
		if(obj.createTextRange) { 
			var range = obj.createTextRange(); 
			range.move('character', pos); 
			range.select(); 
		} else if(obj.selectionStart) { 
			obj.focus(); 
			obj.setSelectionRange(pos, pos); 
		} 
	}
	function __reform_telno_input( input )	{
		var country_code=input.form['__country_code_'+input.name].value;
		var zone_code=input.form['__zone_code_'+input.name].value;
		var local_code=input.form['__local_code_'+input.name].value;
		var ext_code=('__ext_code_'+input.name in input.form )?
			input.form['__ext_code_'+input.name].value : '' ;
		if(country_code=='' || zone_code=='' || local_code=='' )	input.value='';
		else
			input.value=
				'+'+(input.form['__country_code_'+input.name].value) +
				'-'+(input.form['__zone_code_'+input.name].value) +
				'-'+(input.form['__local_code_'+input.name].value) +
				((ext_code!='')?'#'+ext_code:'') ;
	}

	function qualified_telno( telno )	{
		if( telno=='' ) return true;
		telno_part=telno.match( /^\+([\d|\-]+)-(\d+)-(\d+)#?(\d*)$/ );
		if( telno_part==null )	return false;
		return true;
	}

/*--- BEGIN: REQUEST PARAMETER FUNCTIONS ---*/
	function toQueryString(obj){
		//determine the variable type
		if(typeof(obj) == 'string')
			return obj;
		if(typeof(obj) == 'object'){
			if(typeof(obj.elements) == 'undefined')//It's an Object()!
				return object2queryString(obj);
			else //It's a form!
				return form2queryString(obj);
		}	
	}

	function object2queryString(obj){
		var ar = new Array();
		for(x in obj) ar[ar.length] = x+'='+obj[x];
		return ar.join('&');
	}

	function form2queryString(form){
		var obj = new Object();
		var ar = new Array();
		for(var i=0;i<form.elements.length;i++){
			try {
				elm = form.elements[i];
				nm = elm.name;
				if(nm != ''){
					switch(elm.type.split('-')[0]){
						case "select":
							for(var s=0;s<elm.options.length;s++){
								if(elm.options[s].selected){
									if(typeof(obj[nm]) == 'undefined') obj[nm] = new Array();
									obj[nm][obj[nm].length] = encodeURIComponent(elm.options[s].value);
								}	
							}
							break;
						
						case "radio":
							if(elm.checked){
								if(typeof(obj[nm]) == 'undefined') obj[nm] = new Array();
								obj[nm][obj[nm].length] = encodeURIComponent(elm.value);
							}	
							break;
						
						case "checkbox":
							if(elm.checked){
								if(typeof(obj[nm]) == 'undefined') obj[nm] = new Array();
								obj[nm][obj[nm].length] = encodeURIComponent(elm.value);
							}	
							break;
						
						default:
							if(typeof(obj[nm]) == 'undefined') obj[nm] = new Array();
							obj[nm][obj[nm].length] = encodeURIComponent(elm.value);
							break;
					}
				}
			}catch(e){}
		}
		for(x in obj) ar[ar.length] = x+'='+obj[x].join(',');
		return ar.join('&');
	}
/*--- END: REQUEST PARAMETER FUNCTIONS ---*/

function die( msg )	{
	alert( msg );
	return false;
}

function IdManager(ids)	{
	this.ids=ids;
	this.org_ids=this.ids.slice();
	this.changed=false;
}
IdManager.prototype={
		refresh:function(info)	{
			alert('refresh(info) must be defined!');
		},
		add:function(xid)	{
			if( in_array(this.ids,xid)==null)	{
				this.ids.push(xid);
				this.changed=true;
			}
			this.refresh();
		},
		remove:function(xid)	{
			if( (i=in_array(this.ids,xid))!=null )	{
				this.ids.splice(i,1);
				this.changed=true;
			}
			this.refresh();
		},
		reset:function()	{
			this.ids=this.org_ids.slice();
			this.changed=false;
			this.refresh(true);
		},
		dialog:function()	{
			alert('show_dialog() must be defined!');
		},
		isChanged:function()	{
			return this.changed;
		}
	};
	function in_array( arr, val )	{
		for(var i=0;i<arr.length;i++)	{
			if(arr[i]==val)	return i;
		}
		return null;
	}
