
SmartVal={
	// Field types assigned to their handler function index
	types:{
		text:0,
		textarea:0,
		password:0,
		file:0,
		radio:1,
		select_one:2,
		select_multiple:2
	},

	// Validation methods for each type
	validator:[
		function (curObj) {
			return (curObj.Require!=null && !curObj.value.length) ? "\n* '"+curObj.nameDesc+"' is a required field." : (curObj.blockEx && curObj.blockEx!="" && !SmartVal.block(true,curObj)) ? "\n * "+curObj.nameDesc+": "+curObj.blockMsg : "";
		},
		function (curObj) {
			if (curObj.Require==null) return "";
			var rdGrp=curObj.form[curObj.name];
			for (var curIdx=0;curIdx<rdGrp.length;curIdx++) if (rdGrp[curIdx].checked) return "";
			return "\n* '"+curObj.nameDesc+"' is a required field, please select one.";
		},
		function (curObj) {
			if (curObj.Require==null) return "";
			if (curObj.multiple) {
				if (curObj.minSelected==null) curObj.minSelected=1;
				if (curObj.maxSelected==null) curObj.maxSelected=curObj.length;
				var selectedOpts=0;
				for (var curIdx=0;curIdx<curObj.length;curIdx++) {
					if (curObj.options[curIdx].selected) {
						if (curObj.invalidIndex!=null && curIdx==curObj.invalidIndex*1) return "\n* '"+curObj.nameDesc+"' contains a disallowed selected option.";
						selectedOpts++;
					}
				}
				return (selectedOpts<curObj.minSelected*1 || selectedOpts>curObj.maxSelected*1) ? "\n* '"+curObj.nameDesc+"' should contain at least "+curObj.minSelected+" selected options and at most "+curObj.maxSelected+" selected options." : "";
			} else
				return curObj.invalidIndex==null ? (curObj.selectedIndex!=-1 ? "" : "\n* '"+curObj.nameDesc+"' is a required field, please select one.") : (curObj.selectedIndex!=-1 && curObj.selectedIndex!=curObj.invalidIndex*1) ? "" : "\n* '"+curObj.nameDesc+"' has no selected option or contains a disallowed selected option.";
		}
	],

	// "Real time" scheme
	realTime:function () {
		var curObj=event.srcElement, curRX=new RegExp(curObj.realTimeEx,curObj.realTimeSw);
		return curRX.test(String.fromCharCode(event.keyCode));
	},

	// "Block" scheme
	block:function (silentMode,cstObj) {
		var curObj=cstObj ? cstObj : event.srcElement, curRX=new RegExp(curObj.blockEx,curObj.blockSw);
		if (curObj.value.length && !curRX.test(curObj.value)) {
			if (!silentMode) {
				alert(""+curObj.nameDesc+": "+curObj.blockMsg);
				curObj.focus();
				curObj.select();
			}
			return false;
		}
		return true;
	},

	// "Final" scheme
	final:function (frmObj) {
		var curObj, curType, isValid, defErrs="Please fill in the following required fields:\n", curErrs="";
		for (var curIdx=0;curIdx<frmObj.length;curIdx++) {
			curObj=frmObj[curIdx];
			if (curObj.type) {
				curType=this.types[curObj.type.replace(/-/g,"_")];
				if (curType!=null) curErrs+=this.validator[curType](curObj);
			}
		}
		isValid=curErrs=="";
		if (!isValid) alert(defErrs+curErrs);
		return isValid;
	}
}
