/******************************** PAGE CONTENT *****************************************
 *				FUNCTIONS 									DESCRIPTION
 *		validateForRegex(value, regex)			Examine if the value matches the regular expression
 *		validateAganistRegex(value, regex)		Examine if the value does not match the regex
 *		validateLength(value, minLength, maxLength)	Validate if value is within specified length
 *		validateNotEmpty(value)					Examine if the value is not null or empty
 *		validateRadio(object)					Examine if at least one radio button is checked
 *		doValidation(frmObj)					Perform validation using validateForm(frmObj). alert and return false if not valid
 *		validateForm(frmObj)					Examine the form for elements annotated by custom attributes
 *		saveForm(frm)							Save the form elements in a piece of string
 *		loadForm(frm, values)					Load stored information (from saveForm(frm)) to form elements
 *		getRadioValue(object)					Get values from radio button(s).
 *		getCheckBoxValue(object)				Get value from checkbox(s).
 *		
 *      depend by Hashtable.js
 ***************************************************************************************/

var V_NUMERIC = "[0-9]";

var V_ALP_NUM = "[0-9A-Za-z]";

var V_ALP_ONLY = "[A-Za-z]";

var V_ALP_SPACE = "[ A-Za-z]";

var V_ALP_NUM_SPACE = "[ 0-9A-Za-z]";

var V_ZDECIMAL = "[^0-9.]";

var V_ZNUMERIC = "[^0-9]";

var V_ZALP_NUM = "[^0-9A-Za-z]";

var V_ZALP_ONLY = "[^A-Za-z]";

var V_ZALP_SPACE = "[^ A-Za-z]";

var V_ZALP_NUM_SPACE = "[^ 0-9A-Za-z]";

var V_DDMMM = "([0-2][0-9]|30|31|[0-9])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)";

var V_DDMMMYY = "([0-2][0-9]|30|31|[0-9])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)([0-9]{2})";

var V_DDMMMYY_OR_YYYY = "([0-2][0-9]|30|31|[0-9])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)([0-9]{2})?([0-9]{2})?";

var V_DDMMM_OR_YY = "([0-2][0-9]|30|31|[0-9])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)([0-9]{2})?";

var V_DDMMMYYYY = "([0-2][0-9]|30|31|[0-9])(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)((19|20)[0-9]{2})";

var V_DD_MM_YYYY = "([0-2][0-9]|30|31|[0-9])(.)([0-9]|0[0-9]|10|11|12)(.)((19|20)([0-9]{2}))";

var V_VISA = "[0-9]{4}( |-){0,1}[0-9]{4}( |-){0,1}[0-9]{4}( |-){0,1}[0-9]{4}";

/**
 *	return true if the given regular expression matches the string
 *
 *	if the "value" parameter is an object, assumes it is an html form input object. the
 *	value of the underlying object is checked.
 */
function validateForRegex(value, regex) {
	var v = typeof(value) == "object" ? value.value : value;
	var exp = new RegExp(regex);
	return exp.test(v);
}

/**
 *	return true if the given regular expression does not match the string
 *
 *	if the "value" parameter is an object, assumes it is an html form input object. the
 *	value of the underlying object is checked.
 */
function validateAganistRegex(value, regex) {
	var v = typeof(value) == "object" ? value.value : value;
	return !validateForRegex(v, regex);
}

/**
 *	return true if the value's length is within the specified range
 *
 *	if the "value" parameter is an object, assumes it is an html form input object. the
 *	value of the underlying object is checked.
 */
function validateLength(value, minLength, maxLength) {
	var v = typeof(value) == "object" ? value.value : value;
	return v.length >= minLength && v.length <= maxLength;
}

/**
 *	return true if the value is not empty.
 *
 *	if the "value" parameter is an object, assumes it is an html form input object. the
 *	value of the underlying object is checked.
 */
function validateNotEmpty(value) {
	var v = typeof(value) == "object" ? value.value : value;
	return v != null && v.replace(" ", "") != "";
}

/**
 *	return true if at least one radio button in the group is checked.
 *
 *	@param object the radio button object. if the length property of the object is undefined, 
 *	assume it is the only radio.
 */
function validateRadio(object) {
	if (object.length == undefined) {
		return object.checked;
	} else {
		for (var i = 0; i < object.length; i++) {
			if (object[i].checked) return true;
		}
		return false;
	}
}

function getElementsByName(elements, name , strict) {
	var r = new Array();
	var n = 0;
	for (var i = 0; i < elements.length; i++) {
		if(strict == 1 || strict == true || strict == self.undefined){
			if (elements[i].name == name) {
				r[n] = elements[i];
				n++;
			}
		}else{
			if (elements[i].name != self.undefined && elements[i].name !=null && elements[i].name.indexOf(name) ==0) {
				r[n] = elements[i];
				n++;
			}
		}
	}
	return r;
}

/**
 *	Perform validation using attributes of objects in each element in a given form.
 *	if the validation returns error, alert the error and return false.
 *
 *	please see function validateForm(frmObj) for more details.
 */
function doValidation(frmObj) {
	var msg = validateForm(frmObj);
	if (msg == "") {
		return true;
	} else {
		if(alertL) alertL(msg);
		else alert(msg);
		return false;
	}
}

/*
	用於自定義ValidationRule的驗證
*/
function doValidation4Rule(frmObj,ValidationRule,ValidationRuleOther) {
	var msg = "";
	if(ValidationRule!=null){
		msg = validateForm4Rule(frmObj,ValidationRule);
	}
	if (msg == "") {
		if(ValidationRuleOther!=null){
			msg = validateForm4RuleOther(frmObj,ValidationRuleOther);
			if (msg == "") {
				return true;
			} 
		}else{
			return true;
		}
	}
	if(alertL) alertL(msg);
	else alert(msg);
	return false;
}

/**
 *	Validate the given form using attributes of objects in each element in a given form.
 *	The validation methods are defined above in this page.
 */
function validateForm(frmObj, group) {
	var msg =  {};
	for (var i = 0; i < frmObj.elements.length; i++) {
		var o = frmObj.elements[i];
		if (group == "all" || o.getAttribute("v:group") == group || o.getAttribute("v:group") == null) {
			var err = false;
			if (o.getAttribute("v:validateIf") != null) {
				var e = o.getAttribute("v:validateIf");
				if (!eval(e.replace(/\{0\}/g, "frmObj"))){
					 continue;
				}
			}
			if (o.type != undefined && o.type == "text") {
				if(o.getAttribute("v:mIf") != null){
					var e = o.getAttribute("v:mIf");
					if (!eval(e.replace(/\{0\}/g, "frmObj"))){
						if (o.getAttribute("v:allowEmpty") != null && o.getAttribute("v:allowEmpty") == "true"
							&& o.value == "")
						continue;
					}
				}else{
					if (o.getAttribute("v:allowEmpty") != null && o.getAttribute("v:allowEmpty") == "true"
							&& o.value == "")
						continue;
				}
				if (o.getAttribute("v:forRegex") != null) {
					var regex = o.getAttribute("v:forRegex");
					if (regex.indexOf("V_") == 0) 
						err |= !eval("validateForRegex(o.value, " + regex + ")");
					else err |= !validateForRegex(o.value, regex);
				}
				if (o.getAttribute("v:againstRegex") != null) {
					var regex = o.getAttribute("v:againstRegex");
					if (regex.indexOf("V_") == 0) 
						err |= !eval("validateAganistRegex(o.value, " + regex + ")");
					else err |= !validateAganistRegex(o.value, regex);
				}
				if (o.getAttribute("v:length") != null) {
					var length = o.getAttribute("v:length").split("-");
					err |= !validateLength(o.value, parseInt(length[0], 10), parseInt(length[1], 10));
				}
				if (o.getAttribute("v:required") != null) {
					err |= !validateNotEmpty(o.value);
				}
				if (o.getAttribute("v:express") != null) {
					var express =o.getAttribute("v:express");
					err |= !eval(express);
				}
			} else if (o.type != undefined && (o.type == "radio" || o.type == "checkbox")) {
				if (o.getAttribute("v:required") != null) {
					err |= !validateRadio(getElementsByName(frmObj.elements, o.name));
				}
			}
			
			if (err){
				msg["- " + o.getAttribute("v:errmsg")]="";
			}
		}
	}
	var msg_array=[];
	for(i in msg){
		msg_array.push(i);	
	}
	return msg_array.join("\n");
}

/**
 *	Validate the given form using attributes of objects in each element in a given form.
 *	The validation methods are defined above in this page.
 */
function validateForm4Rule(frmObj, ValidationRule) {
	var msg =  {};
	for (var i = 0; i < frmObj.elements.length; i++) {
		var o = frmObj.elements[i];
		var key = o.name;
		if (ValidationRule[key]!=self.undefined || ValidationRule[key]!=null) {
			var err = false;
			var vv = ValidationRule[key]["v"];
			if (vv["validateIf"] != self.undefined) {
				var e = vv["validateIf"];
				if (!eval(e.replace(/\{0\}/g, "frmObj"))){
					 continue;
				}
			}
			if (o.type != self.undefined && o.type == "text" || o.type=="textarea") {
				if(vv["mIf"]!= self.undefined){
					var e = vv["mIf"];
					if (!eval(e.replace(/\{0\}/g, "frmObj"))){
						if (vv["allowEmpty"]!= self.undefined && vv["allowEmpty"] == "true"
							&& o.value == "")
						continue;
					}
				}else{
					if (vv["allowEmpty"] != self.undefined && vv["allowEmpty"] == "true"
							&& o.value == "")
						continue;
				}
				if (vv["forRegex"] != self.undefined) {
					var regex = vv["forRegex"];
					if (regex.indexOf("V_") == 0) {
						err |= !eval("validateForRegex(o.value, " + regex + ")");
					}else{
					    err |= !validateForRegex(o.value, regex);
					}
				}
				if (vv["againstRegex"] != self.undefined) {
					var regex = vv["againstRegex"];
					if (regex.indexOf("V_") == 0) {
						err |= !eval("validateAganistRegex(o.value, " + regex + ")");
					}else {
						err |= !validateAganistRegex(o.value, regex);
					}
				}
				if (vv["length"]!= self.undefined) {
					var length = vv["length"].split("-");
					err |= !validateLength(o.value, parseInt(length[0], 10), parseInt(length[1], 10));
				}
				if (vv["required"]  != self.undefined) {
					err |= !validateNotEmpty(o.value);
				}
				if (vv["express"] != self.undefined) {
					var express =vv["express"];
					err |= !eval(express);
				}
			} else if (o.type != undefined && (o.type == "radio" || o.type == "checkbox")) {
				if (vv["required"] != self.undefined) {
					err |= !validateRadio(getElementsByName(frmObj.elements, o.name));
				}
			}
			if (err){
				msg["- " + vv["errmsg"]]="";
			}
		}
	}
	var msg_array=[];
	for(i in msg){
		msg_array.push(i);	
	}
	return msg_array.join("\n");
}


function validateForm4RuleOther(frmObj,ValidationRules) {
	var msg =  {};
	for (var i=0;i<ValidationRules.length;i++){
		var err = false;
		var vv = ValidationRules[i];
		if (vv["validateIf"] != self.undefined) {
			var e = vv["validateIf"];
			if (!eval(e.replace(/\{0\}/g, "frmObj"))){
				 continue;
			}
		}
		
		var o = null;
		if(vv["target"]!=null){ //基本上同單個field驗證
			o = document.getElementById(vv["target"]);
			if (o.type != self.undefined && o.type == "text") {
				if(vv["mIf"]!= self.undefined){
					var e = vv["mIf"];
					if (!eval(e.replace(/\{0\}/g, "frmObj"))){
						if (vv["allowEmpty"]!= self.undefined && vv["allowEmpty"] == "true"
							&& o.value == "")
						continue;
					}
				}else{
					if (vv["allowEmpty"] != self.undefined && vv["allowEmpty"] == "true"
							&& o.value == "")
						continue;
				}
				if (vv["forRegex"] != self.undefined) {
					var regex = vv["forRegex"];
					if (regex.indexOf("V_") == 0) {
						err |= !eval("validateForRegex(o.value, " + regex + ")");
					}else{
					    err |= !validateForRegex(o.value, regex);
					}
				}
				if (vv["againstRegex"] != self.undefined) {
					var regex = vv["againstRegex"];
					if (regex.indexOf("V_") == 0) {
						err |= !eval("validateAganistRegex(o.value, " + regex + ")");
					}else {
						err |= !validateAganistRegex(o.value, regex);
					}
				}
				if (vv["length"]!= self.undefined) {
					var length = vv["length"].split("-");
					err |= !validateLength(o.value, parseInt(length[0], 10), parseInt(length[1], 10));
				}
				if (vv["required"]  != self.undefined) {
					err |= !validateNotEmpty(o.value);
				}
				if (vv["express"] != self.undefined) {
					var express =vv["express"];
					err |= !eval(express);
				}
			} else if (o.type != undefined && (o.type == "radio" || o.type == "checkbox")) {
				if (vv["required"] != self.undefined) {
					err |= !validateRadio(getElementsByName(frmObj.elements, o.name));
				}
			}
		}else{ //針對無Target的情況
			if (vv["express"] != self.undefined) {
				var express =vv["express"];
				err |= !eval(express);
			}
		}
		if (err){
			msg["- " + vv["errmsg"]]="";
		}
	}
	var msg_array=[];
	for(i in msg){
		msg_array.push(i);	
	}
	return msg_array.join("\n");
}
/**
 *	Save the values of all non-button elements of a given form in a string. The values can then
 *	be persisted for future retrieval. Values may not contain "::" or "|".
 *
 *	Please see function loadForm(frm, values) for loading saved form.
 */
function saveForm(frm) {
	var values = new Array();
	var numSaved = 0;
	for (var i = 0; i < frm.elements.length; i++) {
		var obj = frm.elements[i];
		if (obj.type == "text" || obj.type == "text" || obj.type == "password" || obj.type == "hidden" || obj.type == "file" || obj.type == "select-one") {
			values[numSaved] = obj.name + "::" + obj.value;
			numSaved++;
		} else if (obj.type == "checkbox") {
			values[numSaved] = obj.name + "::" + obj.checked;
			numSaved++;
		}else if( obj.type == "radio"){
			if (obj.checked) {
				values[numSaved] = obj.name + "::" + obj.value;
				numSaved++;
			}
		}
	}
	return values.join("|");
}


/**
 *	Load the values of all non-button elements of a given form previously saved. The given 
 *	form will be examined against the stored values. elements with names specified will have
 *	values assigned to.
 */
function loadForm(frm, values) {
	var v = values.split("|");
	for (var i = 0; i < frm.elements.length; i++) {
		var obj = frm.elements[i];
		if (obj.type == "text" || obj.type == "password" || obj.type == "hidden" || obj.type == "file" || obj.type == "select-one") {
			for (var j = 0; j < v.length; j++) {
				if (v[j].split("::")[0] == obj.name) {
					obj.value = v[j].substring(v[j].indexOf("::") + 2);
					break;
				}
			}
		} else if (obj.type == "checkbox") {
			for (var j = 0; j < v.length; j++) {
				var pair = v[j].split("::");
				if (pair[0] == obj.name) {
						obj.checked = eval(pair[1]);
						break;
				}
			}
		} else if (obj.type == "radio"){
			for (var j = 0; j < v.length; j++) {
				var pair = v[j].split("::");
				if (pair[0] == obj.name) {
					if (pair[1] == obj.value) {
						obj.checked = true;
						break;
					}
				}
			}
		}
	}
}

/**
 *	Get the value of a radio button group. returns the string value of the checked button. if none 
 *	of the radio buttons are checked, return null.
 */
function getRadioValue(object) {
	if (object.length == undefined) {
		return object.checked ? object.value : null;
	} else {
		for (var i = 0; i < object.length; i++) {
			if (object[i].checked) return object[i].value;
		}
		return null;
	}
}

/**
 *	Get the value(s) of a set of check boxes. returns an array of string values. if none 
 *	of the check boxes are checked, return an empty array.
 */
function getCheckBoxValue(object) {
	if (object.length == self.undefined) {
		return object.checked ? [object.value] : new Array();
	} else {
		var a = new Array();
		var num = 0;
		for (var i = 0; i < object.length; i++) {
			if (object[i].checked) {
				a[num] = object[i].value;
				num++;
			}
		}
		return a;
	}
}

function switchAllowed(obj) {
	var opt = obj.options[obj.selectedIndex];
	if (opt.getAttribute("s:disallow") != null) {
		var disallows = opt.getAttribute("s:disallow").split(",");
		for (var i = 0; i < disallows.length; i++) {
			if (disallows[i] != "") {
				document.getElementById(disallows[i]).disabled = true;
				document.getElementById(disallows[i]).style.backgroundColor = "#cccccc";
			}
		}
	}
	if (opt.getAttribute("s:allow") != null) {
		var allows = opt.getAttribute("s:allow").split(",");
		for (var i = 0; i < allows.length; i++) {
			if (allows[i] != "") {
				document.getElementById(allows[i]).disabled = false;
				document.getElementById(allows[i]).style.backgroundColor = "#ffffff";
			}
		}
	}
}

function PartialForm(frm) {
	this.frm = frm;
	this.name = frm.name;
	this.method = frm.method;
	this.target = frm.target;
	this.elements = new Array();
	
	this.submit = function() {
		this.frm.submit();
	}
	
	this.reset = function() {
		for (var i = 0; i < this.elements.length; i++) {
			if (elements[i].type == "radio" || elements[i].type == "checkbox") {
				elements[i].checked = elements[i].defaultChecked;
			} else {
				elements[i].value = elements[i].defaultValue;
			}
		}
	}
}

// use in function display!
function disableGroup(group,disabled) {
	var e = "{0}.disabled = " + (disabled ? "true" : "false") + ";";
	e += "if ({0}.type != 'radio' && {0}.type != 'checkbox' && {0}.type != 'button' && {0}.type !='reset') {{0}.style.backgroundColor = '#" + (disabled ? "CCCCCC" : "FFFFFF") + "';}";
	closureSpecial(group.elements, e);
}
function disableGroupelements(group,disabled) {
	var e = "{0}.disabled = " + (disabled ? "true" : "false") + ";";
	e += "if ({0}.type != 'radio' && {0}.type != 'checkbox' && {0}.type != 'button' && {0}.type !='reset') {{0}.style.backgroundColor = '#" + (disabled ? "CCCCCC" : "FFFFFF") + "';}";
	closureSpecial(group, e);
}

function visiableGroupelements(obj,visiable) {
	obj.style.visibility  =visiable ? "hidden" : "visible";
}
function closureSpecial(ary, evaluation) {
		for (var i = 0; i < ary.length; i++) {
			if (ary[i].length != undefined) {
				//add by ho 
				try {
					eval(evaluation.replace(/\{0\}/g, "ary[i]"));
			   	} catch(e){}
				for (var j = 0; j < ary[i].length; j++) {
					eval(evaluation.replace(/\{0\}/g, "ary[i][j]"));
				}
			} else {
				eval(evaluation.replace(/\{0\}/g, "ary[i]"));
			}
		}
}
/**
 *	 display from obj 
 *  	disable  visiable 
 */
function display(objName, bb) {
	var o = null;
	var _documentBodyAllLength = document.body.all.length;
	for (var i = 0; i < _documentBodyAllLength; i++){
		o = document.body.all[i];
		if (o.tagName.toUpperCase()!="TABLE"){
			 if(o.getAttribute("d:disableIf") != null) {
				var es = o.getAttribute("d:disableIf").split(":");
				//if(es.length==1) alert("error");
				if(es[0]==objName){
					if(bb==undefined || bb==false){
						var b=eval(es[1]);
						disableGroupelements([o],b);
						if(es.length==3){
							if(es[2].toLowerCase()=="parent"){
								display(o.name,b);
							}
						}
					}else if(bb==true){
						var b=true;
						disableGroupelements([o],b);
						if(es.length==3){
							if(es[2].toLowerCase()=="parent"){
								display(o.name,b);
							}
						}
					}
				}
			}
			if(o.getAttribute("d:visibleIf") != null) {
				var es = o.getAttribute("d:visibleIf").split(":");
				//if(es.length==1) alert("error");
				if(es[0]==objName){
					if(bb==undefined || bb==false){
						var b=eval(es[1]);
						visiableGroupelements(o,b);
						if(es.length==3){
							if(es[2].toLowerCase()=="parent"){
								display(o.name,b);
							}
						}
					}else if(bb==true){
						var b=true;
						visiableGroupelements(o,b);
						if(es.length==3){
							if(es[2].toLowerCase()=="parent"){
								display(o.name,b);
							}
						}
					}
				}
			}
		}
	}
}