﻿var NOW = new Date();
$.browser.msie6 = $.browser.msie && ($.browser.version && $.browser.version < 7 || /MSIE 6.0/.test(navigator.userAgent));

/********************************************************
 * Prototype functions
 *
 * String.trim()
 *
 *
 ********************************************************/

String.prototype.trim = function()
{
	return this.replace(/(^[\s]*)|([\s]*$)/g, "");
}


/********************************************************
 * Cookie management functions for use to build the custom dictionary
 *
 * setCookie(name, value, expires, path, domain, secure)
 * getCookie(name)
 *
 ********************************************************/

function setCookie(name, value, expires, path, domain, secure)
{
	//Thu, 2 Aug 2001 20:47:11 UTC
	var curCookie = name + "=" + escape(value) +
		(expires ? "; expires=" + expires.toGMTString() : "") +
		(path ? "; path=" + path : "; path=/") +
		(domain ? "; domain=" + domain : "") +
		(secure ? "; secure" : "");
	document.cookie = curCookie;
}

function getCookie(name, def)
{
	var cookies = document.cookie;
	var separated_values = cookies.split(";");
	if (typeof separated_values != "undefined" && separated_values!=null)
		for(i=0;i<separated_values.length;i++)
		{
			var values = separated_values[i].split("=");
			if(values[0].trim() == name)
					return values[1];
		}
		return def;

}

/********************************************************
 * AJAX
 *
 * ajaxInclude(url, elem)
 * ajaxInvoke(url, callback)
 * ajaxPulldown(url, elem, sep, callback)
 * ajaxSubmit(form, blocking)
 *
 ********************************************************/

var AJAX_JS_EVAL = function (oXML) { eval(oXML.responseText); }

function ajaxInclude(url, el, history, callback)
{
	if (history)
		$.history.save(url)

	if (typeof el == "string") el = gE(el)

	var l919 = $('<div id=div919 style="position:absolute; background:#fff url('+JS_BASEPATH+'/static/GUIControl/wait.gif); filter:alpha(opacity=40); -moz-opacity:0.4; opacity:0.4; display:none;"></div>')
	l919.prependTo(el);
	var div919 = gE("div919")

 	if (div919.style)
 	{
		moveRelTo(gE("div919"), el)
		div919.style.width = el.offsetWidth;
		div919.style.height = el.offsetHeight;
	}

	$(el).load(url.replace(/ /, "+"), null, callback)
}

function ajaxInvoke(url, callback)
{
	$.getScript(url, callback)
}

function ajaxPulldown(url, el, sep, callback)
{
	if (typeof el == "string") el = gE(el)
	el.disabled = 1

	$.get(url, null, function(str){
		var arr = str.trim().split(sep)

		for (var i=el.options.length; --i>=0;)
			el.options[i]=null

		for (var i in arr)
		{
			var vals = arr[i].trim().split('=')

			if (vals.length>1)
				el.options[el.length] = new Option(vals[1].trim(), vals[0].trim())
		}

		el.disabled = 0

		if (callback)
			callback()
		else if (el.type == "select-one")
			$(el).trigger("change")
	})
}

function ajaxSubmit(f, blocking)
{
	if (blocking)
		waitforinput(true)

	var xmlhttp

	try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
	catch (e)
	{
		try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
		catch (e)
		{
			try {
				xmlhttp = new XMLHttpRequest();

				if (xmlhttp.overrideMimeType)
					xmlhttp.overrideMimeType('text/xml');
			}
			catch (e)
			{
				alert("XMLHTTP Not Supported!")
				return;
			}
		}
	}

	var params = makeQueryString(f)

	try
	{
		xmlhttp.onreadystatechange = function()
		{
			if (xmlhttp.readyState == 4)
			{
				AJAX_JS_EVAL(xmlhttp);
				xmlhttp = null;
			}
		};

		xmlhttp.open("POST", f.action, true);
		xmlhttp.setRequestHeader("Method", "POST "+f.action+" HTTP/1.1");
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		xmlhttp.setRequestHeader("Content-Length", params.length);
		xmlhttp.setRequestHeader("Connection", "close");

		xmlhttp.send(params);
	}
	catch(z)
	{
	}
}
	function makeQueryString(f)
	{
		var buf = ""

		for (var i=0; i<f.elements.length; i++)
		{
			var e = f.elements[i]
			var n = e.name
			var t = e.type

			if (t == "checkbox" || t == "radio")
			{
				if (f.elements[i].checked)
					buf += n + "=" + escape(valueOf(e)) + "&"
			}
			else if (n)
				buf += n + "=" + _escape(valueOf(e)) + "&"
		}

		return buf
	}

ajaxUpload = function(url, onselect, oncomplete, onerror)
{
	if (typeof ajaxuploadDiv == "undefined")
	{
		$("<div id=ajaxuploadDiv></div>").appendTo(document.body)

		var swf = new SWFObject("/static/GUIControl/fileupload.lzx.swf", "ajaxfileupload", 0, 0, 8, "", true)
		swf.addVariable("browseOnStart", true)
		swf.write("ajaxuploadDiv")
	}
	else
		window.document.ajaxfileupload.browse()

	var ajaxuploadDiv = gE("ajaxuploadDiv")
	ajaxuploadDiv.onselect = function() { if (!onselect || onselect()) window.document.ajaxfileupload.upload(url); }
	ajaxuploadDiv.oncomplete = oncomplete
	ajaxuploadDiv.onerror = onerror
}

if ($.browser.msie)
ajaxUpload = function(url, onselect, oncomplete, onerror)
{
	if (typeof ifUpload == "undefined")
		$("<iframe id=ifUpload style=width:0;height:0 onload=ajaxuploadcallback()></iframe>").appendTo(document.body)

	var fr = gE("ifUpload")
	fr._url = url
	fr._onselect = onselect
	fr._oncomplete = oncomplete
	fr._onerror = onerror
	fr._mode = 1

	if (ifUpload.document.body)
		ajaxuploadcallback()
}
	ajaxuploadcallback = function()
	{
		var d = ifUpload.document
		var fr = gE("ifUpload")

		if (fr._mode)
		{
			fr._mode = 0
			d.charset = document.charset
			d.body.innerHTML = "<form name=f method=post enctype='multipart/form-data'><input name=file type=file></form>";

			d.f.action = fr._url
			d.f.file.onchange = function() {
				if (!fr._onselect || fr._onselect(d.f.file.value)) d.f.submit(); }
			d.f.file.click()
		}
		else if (d.body.innerHTML && d.body.innerHTML != "ERROR")
			fr._oncomplete(d.body.innerHTML)
		else
			fr._onerror(d.body.innerHTML)
	}

function _escape(s)
{
	var i,j,k,l=s.length,v="",ch;

	for (i=0; i<l; i++)
	{
		ch=s.charAt(i)
		if (ch=='&')
			v+='%26'
		else if (ch=='?')
			v+='%3f'
		else if (ch=='=')
			v+='%3d'
		else if (ch=='+')
			v+='%2b'
		else if (ch=='%')
			v+='%25'
		else if (ch=='#')
			v+='%23'
		else
			v+=ch
	}

	return urlencode(v)
}

function urlencode(s)
{
	var v = ""

	for (var i = 0, l = s.length; i<l; i++)
	{
		var ch = s.charCodeAt(i)

		if (ch < 128)
		{
			v += s.charAt(i)
		}
		else
		{
			var c1 = (ch & 0xff00) >> 8
			var c2 = ch & 0x00ff

			if (ch < 2048)
			{
				// 110xxxxx 10xxxxxx
				var x1 = 192 | (c1 << 2 & 28) | (c2 >> 6)
				var x2 = 128 | (c2 & 63)

				v += "%" + x1.toString(16) + "%" + x2.toString(16)
			}
			else if (ch < 65536)
			{
				// 1110xxxx 10xxxxxx 10xxxxxx
				var x1 = 224 | (c1 >> 4)
				var x2 = 128 | (c1 << 2 & 60) | (c2 >> 6)
				var x3 = 128 | (c2 & 63)

				v += "%" + x1.toString(16) + "%" + x2.toString(16) + "%" + x3.toString(16)
			}
		}
	}

	return v
}

/********************************************************
 * Basic checking functions
 *
 * isDecimalNumber(input,precision,scale)
 * isIpAddress(ip)
 * isEmail(s)
 * isSimpleWord(s)
 * isChineseSimpleWord(s)
 * isKeyword(s)
 * isCtrlKey()
 *
 ********************************************************/

function isDecimalNumber(input, precision, scale)
{
	var dotPos = input.indexOf(".");
	var len = input.length;

	if (dotPos > 0)
	{
		if (dotPos > precision - scale) // check the LHS of the decimcal-point
			return false;

		if (len - dotPos - 1 > scale) // check the RHS of the decimal-point
			return false;
	}
	else
	{
		if (len > precision - scale)
			return false;
	}

	return !isNaN(input);
}

// check if the string is an email
function isEmail(s)
{
	if ("@.".indexOf(s.charAt(0)) != -1)
		return false

	var p = s.split("@")
	var regex = /^[-\d\w]*$/;

	for (var i in p)
	{
		var q = p[i].split(".")

		if (i > 0 && q.length < 2)
			return false

		for (var j in q)
		{
			if (!q[j] && i > 0)
				return false

			if (!regex.test(q[j]))
				return false
		}
	}

	return p.length == 2
}

// check if the string is a valid variable-syntaxed string
function isSimpleWord(s)
{
	var regex = /^[_\w\d]*$/;
	return regex.test(s)
}

function isChineseSimpleWord(s)
{
	var regex = /^[_\w\d\u4E00-\u9FA5]{0,20}$/;
	return regex.test(s)
}

function isIpAddress(ip)
{
	var regex = /^\d{1,3}[.]\d{1,3}[.]\d{1,3}$/;
	return regex.test(ip);
}

function isPhone(s)
{
	//校验普通电话、传真号码：可以“+”开头，除数字外，可含有“-”
	//var regex = /^[\d \-\+\(\)]{1,20}$/;
	var regex = /^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/ ;
	return regex.test(s);
}

/**
 * @return true if s1 is earlier than s2
 */
function isBefore(s1, s2)
{
	if (s1 == "" || s2 == "")
		return true;

	var d1 = parseDate2(s1, "yyyy-MM-dd") || parseDate2(s1, "yyyy-MM-dd HH:mm") || parseDate2(s1, "yyyy-MM-dd HH:mm:ss")
	var d2 = parseDate2(s2, "yyyy-MM-dd") || parseDate2(s2, "yyyy-MM-dd HH:mm") || parseDate2(s2, "yyyy-MM-dd HH:mm:ss")

	return d1 <= d2
}

function keycode(e)
{
	if ($.browser.msie)
		return typeof window.event != "undefined" ? window.event.keyCode : 0
	else
		return typeof e != "undefined" ? e.which : 0
}



/********************************************************
 * Formatting functions
 *
 * formatCurrency(value, scale)
 *
 *
 ********************************************************/

function formatCurrency(value, scale)
{
	var s =  "" + value;
	var i = s.indexOf('.');
	var val = "";
	if (i < 0)
		i = s.length;
	else
		val = s.substring(i, Math.min(i+2+1, s.length));

	for(i=i-3; i>0; i-=3)
		val = "," + s.substring(i,i+3) + val;

	return s.substring(0,i+3) + val;
}



/********************************************************
 * Date related functions
 *
 * formatDate(date, formatStr)
 * parseDate2(dateStr, formatStr)
 *
 *
 ********************************************************/

var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}

// Returns a date in the output format specified.
function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}

// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the
// getTime() of the date. If it does not match, it returns 0.
function parseDate2(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";

	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i<MONTH_NAMES.length; i++) {
				var month_name=MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<DAY_NAMES.length; i++) {
				var day_name=DAY_NAMES[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
	else if (hh>11 && ampm=="AM") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
}
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}



/********************************************************
 * Form validation object
 *
 * .checkEmpty(input, msg)
 * .checkNonLatin(input, msg)
 * .checkLength(input, msg, min, max)
 * .checkNumber(input, msg, precision, scale, minVal, maxVal)
 * .checkEmail(input, msg)
 * .checkSimpleWord(input, msg)
 * .checkPhone(input, msg)
 * .checkAfter(input1, input2, msg)
 * .checkDate(input1, msg)
 * .execute(msg)
 *
 *
 ********************************************************/

// form submission check
function Checker(form, skipcheck)
{
	this.frm = form;
	this.msg = "";
	this.err = [];

	if (typeof FCKeditorAPI != "undefined")
		for (var i=0; i<form.elements.length; i++)
		{
			var n = form.elements[i].name;
			if (gE("fck_"+n) && gE("fck_"+n).fckOK)
				form.elements[n].value = FCKeditorAPI.GetInstance("fck_"+n).GetXHTML(true)
		}

	if ((typeof skipcheck == "undefined" || !skipcheck) && typeof this.frm.chk != "undefined")
		for (var name in this.frm.chk)
		{
			var arr = this.frm.chk[name]
			var ctl = this.frm.elements[name]
			var tit = arr.length==3 ? arr[2] : this._titleOf(ctl)

			if (arr[1]) // mandatory
				this.checkEmpty(ctl, tit + _L12N_["REQ"])

			if (arr[0].toLowerCase() == "integer")
				this.checkNumber(ctl, tit + _L12N_["REQ_INT"], 38, 0, -100000000, 100000000)
			else if (arr[0].toLowerCase() == "float")
				this.checkNumber(ctl, tit + _L12N_["REQ_NUM"], 38, 2, -100000000, 100000000)
			else if (arr[0].toLowerCase() == "date" || arr[0].toLowerCase() == "datetime")
				this.checkDate(ctl, tit + _L12N_["REQ_DATE"])
			else if (arr[0].toLowerCase() == "longtext" && ctl.maxlength > 0)
				this.checkLength(ctl, tit + _L12N_["REQ_MAXLENGTH1"] + ctl.maxlength + _L12N_["REQ_MAXLENGTH2"], 0, ctl.maxlength)
			else if (arr[0] == "MULTIPLELOOKUP")
				for (var i=0; i<ctl.options.length; i++)
					ctl.options[i].selected = true;
			else if (arr[0].toLowerCase() == "email")
				this.checkEmail(ctl, tit + _L12N_["REQ_EMAIL"])
		}
}

Checker.prototype._titleOf = function(obj)
{
	if (!obj)
		return ""

	if (obj.type != "select-one" && typeof obj.length == "number" && obj.length > 0)
		return obj[0].title

	return obj.title
}

Checker.prototype.appendErr = function(input, msg)
{
	msg = msg.trim()

	if (msg.length > 0)
	{
		this.msg += "\n"

		if (msg.charAt(0) != "-")
			this.msg += "- ";

		this.msg += msg;
	}

	if (typeof input == "object" && input != null)
		this.err.push(input.name);
	else if (input)
		this.err.push(input);

	return false;
}

Checker.prototype.valueOf = function(input)
{
	if (typeof input == "number")
		return input

	var v = typeof input == "string" ? this.frm[input].value : valueOf(input)
	return v == null ? "" : v.trim();
}

/**
 * validate this specified input field value is null or empty string.
 *
 * @param input - input field name
 * @param msg - error message when validat failed
 * @return - when the input value is null or empty string, return true. Otherwise, return false.
 **/
Checker.prototype.checkEmpty = function(input, msg)
{
	if (this.valueOf(input).length == 0 && countSelected(input) == 0)
		return this.appendErr(input, msg);

	return true;
}

/**
 * check if the given input contains any Chinese character
 *
 * @param input - input field name
 * @param msg - error message when validat failed
 * @return - when the input value is null or empty string, return true. Otherwise, return false.
 **/
Checker.prototype.checkNonLatin = function(input, msg)
{
	if (this.valueOf(input).search(/[^\x00-\x80]/) >= 0)
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkLength = function(input, msg, min, max)
{
	var s = this.valueOf(input)

	if (s.length < min || s.length > max)
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkNumber = function(input, msg, precision, scale, minVal, maxVal)
{
	var v = this.valueOf(input)
	precision = precision == null ? 38 : precision
	scale = scale == null ? 8 : scale

	if (typeof minVal == "undefined") minVal = -32768
	if (typeof maxVal == "undefined") maxVal = 32767

	if (v.length > 0 && (!isDecimalNumber(v, precision, scale) || v < minVal || v > maxVal))
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkPhone = function(input, msg)
{
	var v = this.valueOf(input)

	if (v.length > 0 && !isPhone(v))
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkEmail = function(input, msg)
{
	var v = this.valueOf(input)

	if (v.length > 0 && !isEmail(v))
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkSimpleWord = function(input, msg)
{
	var v = this.valueOf(input)

	if (v.length > 0 && !isSimpleWord(v))
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkChineseSimpleWord = function(input, msg)
{
	var v = this.valueOf(input)

	if (v.length > 0 && !isChineseSimpleWord(v))
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkPassword = function(input, msg)
{
	var v = this.valueOf(input)

	if (v.length > 0 && !(/\d/.test(v) && /[a-zA-Z]/.test(v)))
		return this.appendErr(input, msg);

	return true;
}

// if input2 is after input1, return true
Checker.prototype.checkAfter = function(input1, input2, msg)
{
	var TODAY = "[TODAY]";
	var t = new Date();
	var d1, d2;

	if (input1 == TODAY)
		d1 = t.getFullYear()+"-"+a0(t.getMonth()+1)+"-"+a0(t.getDate())
	else
		d1 = this.valueOf(input1)

	if (input2 == TODAY)
		d2 = t.getFullYear()+"-"+a0(t.getMonth()+1)+"-"+a0(t.getDate())
	else
		d2 = this.valueOf(input2)

	if (d1.length > 0 && d2.length > 0 && !isBefore(d1, d2)) // d1 < d2 ==> true
	{
		this.appendErr(input1, ""); // highlight only
	return this.appendErr(input2, msg);
	}

	return true;
}

Checker.prototype.checkDate = function(input, msg)
{
	var d = this.valueOf(input)

	if (d.length > 0 && parseDate2(d, "yyyy-MM-dd") == 0 &&
		parseDate2(d, "yyyy-MM-dd HH:mm") == 0 &&
		parseDate2(d, "yyyy-MM-dd HH:mm:ss") == 0)
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.checkTrue = function(input, bool, msg)
{
	if (bool)
		return this.appendErr(input, msg);

	return true;
}

Checker.prototype.execute = function(msg)
{
	for (var i in this.frm.elements)
	{
		var f = this.frm.elements[i]
		if (f != null && typeof f.type != "undefined" && typeof f.borderColor_ != "undefined")
			if (f.type == "text" || f.type == "password" || f.type == "textarea" || f.type == "file")
				f.style.borderColor = f.borderColor_;
	}

	if (this.msg != "")
	{
		__alert((msg||_L12N_["PLS_RETRY"]) + this.msg);

		for (var i in this.frm.elements)
		{
			var f = this.frm.elements[i]

			if (f != null && typeof f.type != "undefined")
				if (f.type == "text" || f.type == "password" || f.type == "checkbox" || f.type == "textarea" || f.type == "file")
					if (contains(this.err, f.name))
					{
						f.borderColor_ = f.style.borderColor
						f.style.borderColor = "red";
					}
		}

		return false;
	}

	this.frm.dirty=0
	return true;
}

/********************************************************
 * Misc functions
 *
 * gE()
 * v()
 * __alert(msg)
 * find(arr, val)
 * valueOf(o)
 * contains(arr, obj)
 * selectItem()
 * toggleDisplay(arr)
 * swapImg(obj, imagename)
 * moveOption(list1, list2, val)
 *
 ********************************************************/

gE = function(s)
{
	var obj = document.getElementById(s)

	if(obj == null && $.browser.mozilla)
		obj = document.getElementsByName(s)[0]

	return obj
}
v = function(s) { return valueOf(s) }
__alert = function(msg) { alert(msg.replace("<t>", "").replace("</t>", "")); }

find = function(arr, v)
{
	for (var i in arr)
		if (arr[i]==v)
			return i;

	return -1;
}

/*
 * Return the given object's value
 * If the given object contains multiple instance (such as checkbox or an array of text input),
 * this function will return a comma-delimited string with all the values
 *
 * @param o - the specified object
 * @return - the string to be returned
 * NOTE: all string value are trimmed
 */
function valueOf(o)
{
	if (!o)
		return ""

	if (typeof o == "string" || typeof o == "number")
		return o

	if (typeof o == "object" || typeof o == "function") // assume it is a form object
	{
		var t = o.type

		if (t == "select-one")
		{
			if (o.selectedIndex != -1)
				return o.options[o.selectedIndex].value
		}
		else if (o.length)
		{
			var l = o.length
			var arr = []
			var isRadio = false
			// TODO: work with IE only :(
			// <select name="...." submit = "ALL|SELECTED" ><option....
			var submitSelected = typeof o.submit != "undefined" && o.submit == "SELECTED"

			for (var i = 0; i < l; i++)
			{
				if (i == 0 && !isRadio)
					isRadio = o[i].type == "radio"

				var v = valueOf(o[i])

				if (isRadio && v)
					return v

				if (v)
				{
					if (submitSelected)
					{
						if (o[i].selected)
							arr.push(v)
					}
					else
						arr.push(v)
				}
			}

			if (arr.length > 0)
				return arr.join(",");
		}
		else
		{
			if (t == "checkbox" || t == "radio")
			{
				if (o.checked)
					return o.value
				else
					return "";
			}
			else // if (t == "text" || t == "textarea" || t == "hidden" || t == "select")
			{
				var v = typeof o.submitvalue != "undefined" ? o.submitvalue : o.value

				if (v == "undefined")
					return ""

				if (typeof v == "string")
					return v.trim()

				return v
			}
		}
	}

	return ""
}

// count how many item was selected in a checkbox / radiogroup / listbox
function countSelected(o)
{
	if (!o)
		return 0

	if (o.type == "checkbox" || o.type == "radio")
		return o.checked ? 1 : 0;

	if (o.type == "select-one")
		//return o.selectedIndex != -1 ? 1 : 0;
		return 0

	var sel = 0;
	for (var i=o.length; --i>=0; )
		if (o[i].checked || o[i].selected)
			sel++;

	return sel;
}

// check if an item is contained in a given array and return its position if found
function contains(arr, obj)
{
	for (var i in arr)
		if (obj == arr[i])
			return true

	return false
}

// pre-select options according to the variables passed
var SELECT_ALL  = "@@SELECT_ALL@@"
var SELECT_NONE = "@@SELECT_NONE@@"
function selectItem()
{
	var args = selectItem.arguments;
	var frm

	for (var i=0; i<args.length-1; i+=2)
	{
		var obj = args[i]
		var val = args[i + 1]

		if (typeof obj == "undefined")
			continue

		if (typeof obj == "string")
			obj = frm.elements[args[i]];

		var t = obj.type

		if (t == 'checkbox' || t == 'radio')
		{
			obj.checked = (obj.value == val || val == SELECT_ALL) && val != SELECT_NONE;
		}
		else if (t == 'select-one' || t == 'select-multiple')
		{
			for (var j=0; j<obj.options.length; j++)
			{
				if (obj.options[j].value == val || val == SELECT_ALL)
					obj.options[j].selected = true;
				else if (val == SELECT_NONE)
					obj.options[j].selected = false;
			}
		}
		else if (obj.length)
		{
			for (var j=0; j < obj.length; j++)
			{
				var obj_ = obj[j]

				if (obj_.type == 'radio' || obj_.type == 'checkbox')
				{
					if (obj_.value == val || val == SELECT_ALL)
						obj_.checked = true;
					else if (val == SELECT_NONE)
						obj_.checked = false;
				}
				else if (obj_.type == 'text')
					obj_.value = val;
			}
		}
		else
			obj.value = args[i+1]
	}
}

function toggleDisplay(arr, state)
{
	for (var i=arr.length; --i>=0; )
	{
		if (typeof arr[i] == "string")
			arr[i] = gE(arr[i])

		if (arr[i])
			arr[i].style.display = state || (_style(arr[i],'display') == 'none' ? 'block' : 'none')
	}
}

function a0(i)
{
	return i>9 ? i : "0"+i
}

function Pt(p)
{
	this.x = 0
	this.y = 0

	while (p && p.tagName != "BODY")
	{
		this.x += p.offsetLeft;
		this.y += p.offsetTop;
		p = p.offsetParent;
	}
}

function swapImg(o,s)
{
	if (o == null)
		return

	if (o.tagName != "IMG")
	{
		if (s)
		{
			var x = _style(o, $.browser.msie ? "backgroundImage" : "background-image")
			o._src=x
			var j = x.lastIndexOf('/')
			o.style.backgroundImage = s.indexOf('/') < 0 ? x.substring(0,j+1) + s + ")" : s
		}
		else if (o._src)
			o.style.backgroundImage=o._src
	}
	else
	{
		if (s)
		{
			o._src=o.src
			var j = o.src.lastIndexOf('/')
			o.src = s.indexOf('/') < 0 ? o.src.substring(0,j+1) + s : s
		}
		else if (o._src)
			o.src=o._src
	}
}

function moveOption(src, dst, val)
{
	var sel = src.options.selectedIndex;

	if (sel == -1 && !val)
		;
	else
	{
		for (i=0; i<src.options.length; i++)
			if (src.options[i].selected || (val && src.options[i].value == val))
			{
				var o = new Option(src.options[i].text, src.options[i].value)
				dst.options[dst.options.length] = o;
				src.options[i--] = null;
			}
	}
}

var waitforinput_onresize=null
function waitforinput(bool)
{
	if (typeof ifWaitfor == "undefined")
	{
		if ($.browser.msie)
			bool && $('<iframe id=ifWaitfor src="'+JS_BASEPATH+'/static/GUIControl/waitbackground.html" style="position:absolute;top:0;left:0;filter:alpha(opacity=70);-moz-opacity:0.7;opacity:0.7;display:none;z-index:0;" ></iframe>').appendTo(document.body)
		else
			bool && $('<div id=ifWaitfor style="position:absolute;top:0;left:0;filter:alpha(opacity=70);-moz-opacity:0.7;opacity:0.7;display:none;z-index:9;background:#cccccc" ></div>').appendTo(document.body)

		bool && waitforinput(true)
	}
	else
	{
		var x = gE("ifWaitfor").style
		var b = truebody()
		var innerWidth = $.browser.msie ? document.body.clientWidth : window.innerWidth
		var innerHeight = $.browser.msie ? document.body.clientHeight : window.innerHeight

		x.width   = Math.max(b.scrollWidth, innerWidth)
		x.height  = Math.max(b.scrollHeight, innerHeight)
		x.display = bool ? "block" : "none"

		if (bool)
		{
			waitforinput_onresize = window.onresize
			window.onresize=function() { waitforinput(true); }
		}
		else
			window.onresize = waitforinput_onresize
	}
}

	function truebody() { return (!window.opera && document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body; }

if (typeof _L12N_ == "undefined")
{
	var _L12N_ = {}

	_L12N_["REQ"]            = " cannot be empty"
	_L12N_["REQ_INT"]        = " must be an integer"
	_L12N_["REQ_NUM"]        = " must be numeric value"
	_L12N_["REQ_DATE"]       = " must be a valid date"
	_L12N_["REQ_MAXLENGTH1"] = " cannot contains more than "
	_L12N_["REQ_MAXLENGTH2"] = " characters"
	_L12N_["PLS_RETRY"]      = "Please correct the following problem and submit again.\n";
	_L12N_["REQ_EMAIL"]      = " must be a valid email"
}

function moveRelTo(o1, o2, x, y)
{
	x = x || 0; y = y || 0;

	while (o2 && o2.tagName != "BODY")
	{
		x += o2.offsetLeft;
		y += o2.offsetTop;
		o2 = o2.offsetParent;
	}

	o1.style.left = x
	o1.style.top = y
	o1.style.display = "block"
}

if (typeof jlink == "undefined") document.write("<a id=jlink href=# ></a>")
j = jumpTo = function(url, target)
{
	if ($.browser.msie)
	{
		jlink.href = url || location;
		jlink.target = typeof target == "undefined" ? "" : target
		jlink.click();
	}
	else
		location.href = url || location.href
}

function _style(el,styleProp)
{
	if (el.currentStyle)
		return el.currentStyle[styleProp];
	else if (window.getComputedStyle)
		return document.defaultView.getComputedStyle(el,null).getPropertyValue(styleProp);
}

function switchLang(lang)
{
  var l = location + "";

	if (l.indexOf("?") == -1)
	{
	  l = l.replace(/$/, "?lang=" + lang);
	  j( l.replace(/#/, "?lang=" + lang + "#") );
	}
	else
	{
	  l = l.replace(/(\?|&)lang=[^&#]*/, "$1");
	  j( l.replace(/\?(&*)(.*)/, "?lang=" + lang + "&$2") );
	}
}
