<!--

//====================================================================================
//		Define checking function for controls
//====================================================================================

//-------------------------------------------------------------------------
// Trim the string
//-------------------------------------------------------------------------
function chkTrim(sInput){
	if(sInput==null) return sInput;
	re = /^\s*(\S*)\s*$/;
	sInput = sInput.replace(re, "$1");
	return sInput;
}


//-------------------------------------------------------------------------
// Return boolean value indicate whether sValue is null
//-------------------------------------------------------------------------
function chkNullValue(sValue){
	if(sValue == null) return true;
	if(chkTrim(sValue).length == 0) return true;
	return false;
}


//-------------------------------------------------------------------------
// Return boolean value indicate whether sValue between minval and maxval
//-------------------------------------------------------------------------
function chkRange(sValue, minval, maxval){
	if (isNaN(sValue) == false)
		if (sValue * 1 >= minval && sValue * 1 <= maxval) return true;
	else	return false;
}


//-------------------------------------------------------------------------
// Return list of selected values seperate by sSeperator
//-------------------------------------------------------------------------
function chkGetSelected(control, sSeperator){
var i,j,aTmp;

	aTmp = new Array();
	j=0;
	for(i=0;i<control.length;i++)
		if(control[i].selected) aTmp[j++] = control[i].value;
		
	return aTmp.join(sSeperator);
}


//-------------------------------------------------------------------------
// Return list of checked values seperate by sSeperator
//-------------------------------------------------------------------------
function chkGetChecked(control, sSeperator){
var i,j,aTmp;

	aTmp = new Array();
	j=0;
	for(i=0;i<control.length;i++)
		if(control[i].checked) aTmp[j++] = control[i].value;

	return aTmp.join(sSeperator);
}


//-------------------------------------------------------------------------
// Return boolean value indicate whether sValue is in the array aListValue
//-------------------------------------------------------------------------
function chkIsInList(aListValue, sValue){
var i;
	for(i=0;i<aListValue.length;i++){
		if(aListValue[i] == sValue) return true;
	}
	return false;
}


//-------------------------------------------------------------------------
// Return boolean value indicate whether sValue is Integer
//-------------------------------------------------------------------------
function chkIsInteger(str){
var str1;
	str1 = chkTrim(str);
	return /^\d+$/.test(str1);
}


//-------------------------------------------------------------------------
// Return boolean value indicate string is valid email address
//-------------------------------------------------------------------------
function chkEmail(sValue){

	return (sValue.indexOf("@") != -1)
}


//-------------------------------------------------------------------------
// Load data Function
//-------------------------------------------------------------------------
function chkLoadData(){
	var vType, i, j, sTmp, aTmp, blnFlag;

	vType = this.controltype;
	this.value = null;

	if(this.control==null) return null;

	if(vType == "T") 	{ // text
		this.value = this.control.value;
	}
	else if(vType == "R") {	// radio
		for(i=0;i<this.control.length;i++)
			if(this.control[i].checked) this.value = this.control[i].value;
	}
	else if(vType == "O") {	// option -- select box
		if(this.control.selectedIndex == -1) return null;
		this.value = chkGetSelected(this.control,",");
	}
	else if(vType == "C") {	// checkbox
		if(this.control.checked) {
			this.value = this.control.value;
			if(this.value.length==0) this.value = "on";
		}
		else this.value = "";
	}
	else if(vType == "CG") {	// CheckboxGroup

		//check whether anyone is selected
		blnFlag = false;
		for(i=0;i<this.control.length;i++) blnFlag = blnFlag || this.control[i].checked;
		if(!blnFlag) return null;

		this.value = chkGetChecked(this.control,",");
	}
	else if(vType == "A") {	// Textarea
		this.value = this.control.value;
	}
	return this.value;
}


//-------------------------------------------------------------------------
// Get Errors Function (assume already call loadData function)
// Parameters: value -- value for checking
// Return:
//	empty string  -- no error
// error message -- have error
//-------------------------------------------------------------------------
function chkGetError(value){
var vType, i, j, sTmp, aTmp, blnFlag;

	vType = this.controltype;
	if(this.control==null) return "Script Error: [" + this.name + "] is not define!";

	if(vType == "T") {		// text
		if(this.allownull && chkNullValue(value)) return "";
		if(!this.allownull && chkNullValue(value)) return "Please enter " + this.title;
		if(this.isnumber && isNaN(value)) return this.title + " should be a number!";
	}

	else if(vType == "R") {	// radio
		if(this.allownull && chkNullValue(value)) return "";
		if(!this.allownull && chkNullValue(value)) return "Please select " + this.title;
	}

	else if(vType == "O") {	// option -- select box
		if(this.allownull && chkNullValue(value)) return "";
		if(!this.allownull && chkNullValue(value)) return "Please select " + this.title;
	}

	else if(vType == "C") {	// checkbox
	}

	else if(vType == "CG") {	// CheckboxGroup
		if(this.allownull && chkNullValue(value)) return "";
		if(!this.allownull && chkNullValue(value)) return "Please select at least " + this.title;
	}

	else if(vType == "A") {	// Textarea
		if(this.allownull && chkNullValue(value)) return true;
		if(!this.allownull && chkNullValue(value)) return "Please enter " + this.title ;
		if(this.isnumber && isNaN(value)) return this.title + " should be a number!";
	}

	//validation function
	for(i=0;i<this.rules.length;i++){
		sTmp = this.rules[i](this.frm,value);
		if(sTmp.length > 0) return sTmp;
	}

	return "";
}


//-------------------------------------------------------------------------
// Checking Function
//-------------------------------------------------------------------------
function chkChecking(){

	this.value = null;
	if(this.control==null) return false;

	this.errormsg = this.getError(this.loadData());
	if(this.errormsg.length > 0){
		alert(this.errormsg);
		if(chkIsInList("T|O|C|A".split("|"),this.controltype)) this.control.focus();
		else	this.control[0].focus();
		this.value = null;
		return false;
	}
	else return true;
}


//-------------------------------------------------------------------------
// Setting Data of control
//-------------------------------------------------------------------------
function chkSetData(Value){
var vType, i, j, sTmp, aTmp, blnFlag;

	if(this.control==null) return false;

	vType = this.controltype;
	this.value = Value;

	if(vType == "T") {		// text
		if(chkNullValue(this.value)) this.control.value = "";
		else this.control.value = this.value;
	}

	else if(vType == "R") {	// radio
		if(this.value == null) for(i=0;i<this.control.length;i++) this.control[i].checked=false;
		else{
			for(i=this.control.length-1;i>=0;i--){
				if(this.control[i].value == this.value) this.control[i].checked = true;
				else this.control[i].checked = false
			}
		}
	}

	else if(vType == "O") {	// option -- select box
		this.value = Value;
		if(this.value == null) this.control.selectedIndex = -1;
		else{
			aTmp = this.value.split(",");
			for(i=0;i<this.control.length;i++){
				if(chkIsInList(aTmp,this.control.options[i].value)) this.control.options[i].selected = true;
				else this.control.options[i].selected = false;
			}
		}
	}

	else if(vType == "C") {	// checkbox
		this.value = Value;
		this.control.checked = false;
		if(this.control.value.length == 0 && Value == "on") this.control.checked = true;
		else if(this.control.value.length > 0 && this.control.value == Value) this.control.checked = true;
	}

	else if(vType == "CG") {	// CheckboxGroup
		this.value = Value;
		if(this.value == null) for(i=0;i<this.control.length;i++) this.control[i].checked=false;
		else{
			aTmp = this.value.split(",");
			for(i=0;i<this.control.length;i++){
				if(chkIsInList(aTmp,this.control[i].value)) this.control[i].checked = true;
				else this.control[i].checked = false;
			}
		}
	}

	else if(vType == "A") {	// Textarea
		this.value = Value;
		if(this.value == null) this.control.value = "";
		else this.control.value = this.value;
	}
}


//-------------------------------------------------------------------------
// Define checking control object
//	Parameters:	frm				-- form object
//					control 			-- field object name
//					controltype		-- T(Text)|R(Radio)|O(Option)|C(Checkbox)|
//											CG(CheckboxGroup)|A(Textarea)
//					fieldtitle		--	Title of the control
//					allownull		-- true|false whether allow null value
//					isnumber			-- true|false whether field must be numeric
//-------------------------------------------------------------------------
function chkControl(frm,control,controltype,fieldtitle,allownull,isnumber){
	this.frm				= frm;							// Form object
	this.control 		= eval("frm." + control);	// Field control object
	this.name			= control;						// Name attribute of control
	this.errormsg		= "";								// Error Message
	this.controltype	= controltype;					// Control Type
	this.title			= fieldtitle;					// Title of the field
	this.allownull		= allownull;					// Allow null value
	this.isnumber		= isnumber;						// Numeric value
	this.value 			= null;							// Default value
	this.rules 			= new Array();					// contains array of functions for validation
	this.loadData		= chkLoadData;					// load data
	this.getError		= chkGetError;					// Get Errors Message
	this.checking 		= chkChecking;					// checking data
	this.setData		= chkSetData;					// setting data
}


//====================================================================================
//		Define multi-pages object
//====================================================================================

//-------------------------------------------------------------------------
// Add control
//	Parameters:	cControl 		-- checking control
//					defaultValue	-- default value
//					hiddenName		-- hidden field name
//-------------------------------------------------------------------------
function multiAdd(cControl,defaultValue,hiddenName){
	this.controlsIndex = this.controlsIndex + 1;
	this.controls[this.controlsIndex] = new multiControl(this.frm,cControl,this.maxpage,defaultValue,hiddenName);
}


//-------------------------------------------------------------------------
// Change Max Page
//-------------------------------------------------------------------------
function multiChangeMax(max){
	if(max > this.initmax) {
		alert("Max. number of records can't exceed " + this.initmax);
		return;
	}
	if(max < 1) {
		alert("Max. number of records can't smaller than 1!");
		return;
	}
	if(this.withChecking && !this.checkCurrentPage()) return;	//Checking current page
	this.maxpage = max;
	this.moveFirst();
}


//-------------------------------------------------------------------------
// Change Page
//-------------------------------------------------------------------------
function multiChangePage(page){
var newPage;
	     if(page=="F") newPage = 0;								//First page
	else if(page=="P") newPage = this.currentIndex - 1;	//Previous page
	else if(page=="N") newPage = this.currentIndex + 1;	//Next page
	else if(page=="L") newPage = this.maxpage -1;			//Last page
	else					 newPage = parseInt(page);				//Specific page
	if(isNaN(newPage)) return;
	if(newPage< 0 || newPage >= this.maxpage) return;
	if(this.maxpage > this.initmax) {
		alert("Max. number of records can't exceed " + this.initmax);
		return;
	}
	if(this.withChecking && !this.checkCurrentPage()) return;	//Checking current page
	this.loadData();
	this.currentIndex = newPage;
	this.setData();
	this.updateIndex(this.currentIndex+1,this.maxpage);
}


//-------------------------------------------------------------------------
// Move to next Page
//-------------------------------------------------------------------------
function multiMoveNext(){
	this.changePage("N");
}


//-------------------------------------------------------------------------
// Move to Previous Page
//-------------------------------------------------------------------------
function multiMovePrevious(){
	this.changePage("P");
}


//-------------------------------------------------------------------------
// Move to First Page
//-------------------------------------------------------------------------
function multiMoveFirst(){
	this.changePage("F");
}


//-------------------------------------------------------------------------
// Move to Last Page
//-------------------------------------------------------------------------
function multiMoveLast(){
	this.changePage("L");
}


//-------------------------------------------------------------------------
// Goto Page index
// Parameters: index -- index of the page (start from 0)
//-------------------------------------------------------------------------
function multiGoto(index){
	this.changePage(index - 1);
}


//-------------------------------------------------------------------------
// Reset this page
//-------------------------------------------------------------------------
function multiReset(){
var i,index,mControl;
	index = this.currentIndex;
	for(i=0;i<this.controls.length;i++){
		mControl = this.controls[i];
		mControl.setValue(index,mControl.defaultValue);
	}
	this.setData();
}


//-------------------------------------------------------------------------
// Reset all this page
//-------------------------------------------------------------------------
function multiResetAll(){
var i,j,index,mControl;
	for(j=0;j<this.maxpage;j++)
		for(i=0;i<this.controls.length;i++){
			mControl = this.controls[i];
			//mControl.setValue(j,mControl.defaultValue);
			mControl.setValue(j,"");
		}
	this.setData();
}


//-------------------------------------------------------------------------
// Load data from form fields
//-------------------------------------------------------------------------
function multiLoadData(){
var i, index, mControl;
	index = this.currentIndex;
	if(index < 0) return;

	for(i=0;i<this.controls.length;i++){
		mControl = this.controls[i];
		mControl.setValue(index,mControl.cControl.loadData());
	}
}


//-------------------------------------------------------------------------
// Set form fields data
//-------------------------------------------------------------------------
function multiSetData(){
var i, index, mControl, value;
	index = this.currentIndex;
	if(index < 0) return;

	for(i=0;i<this.controls.length;i++){
		mControl = this.controls[i];
		value = mControl.getValue(index);
		if(value.length == 0 && mControl.defaultValue != null) value = mControl.defaultValue;
		mControl.cControl.setData(value);
	}
}


//-------------------------------------------------------------------------
// Check current page
//-------------------------------------------------------------------------
function multiCheckCurrentPage(){
var i, mControl, errMsg, sTmp;

	if(this.currentIndex < 0) {
		this.errormsg = "Invalid page index!";
		return false;
	}

	this.errormsg = ""
	errMsg = "";
	for(i=0;i<this.controls.length;i++){
		mControl = this.controls[i];
		sTmp = mControl.cControl.getError(mControl.cControl.loadData());
		if(sTmp.length > 0) errMsg = errMsg + "- " + sTmp + "\n";
	}

	if(errMsg.length > 0){
		this.errormsg = "Record " + (this.currentIndex+1)+ "/" + this.maxpage + "\n\n" + errMsg;
		return confirm(this.errormsg + "\nContinue anyway ?");
	}

	return true;
}


//-------------------------------------------------------------------------
// Check all page
//-------------------------------------------------------------------------
function multiCheckAllPage(){
var i, j, mControl, errAllMsg, errMsg, sTmp;
	if(this.currentIndex < 0) {
		this.errormsg = "Invalid page index!";
		return false;
	}

	this.loadData();
	this.errormsg = ""

	errAllMsg = "";

	for(j=0;j<this.maxpage;j++){
		errMsg = "";
		for(i=0;i<this.controls.length;i++){
			mControl = this.controls[i];
			sTmp = mControl.cControl.getError(mControl.getValue(j));
			if(sTmp.length > 0) errMsg = errMsg + "- " + sTmp + "\n";
		}
		if(errMsg.length > 0) {
			errAllMsg = errAllMsg + "Record " + (j+1)+ "/" + this.maxpage + "\n\n" + errMsg + "\n";
		}
	}

	if(errAllMsg.length > 0) {
		this.errormsg = errAllMsg;
		return false;
	}

	return true;
}


//-------------------------------------------------------------------------
// Fill in the form hidden value
//-------------------------------------------------------------------------
function multiFillHidden(){
//var i,j,name,mControl,frm,field;
//	frm = this.frm;
//	frm.multi_maxpage.value = this.maxpage;
//	for(i=0;i<this.controls.length;i++){
//		mControl = this.controls[i];
//		name = mControl.cControl.name;
//		field = eval("frm." + mControl.hiddenName);
//		for(j=0;j<this.maxpage;j++) field[j].value = mControl.values[j]==null ? "" : mControl.values[j] ;
//	}
}


//-------------------------------------------------------------------------
// Print the hidden form fields
//-------------------------------------------------------------------------
function multiPrintHidden(){
var i,j,name,mControl;
	document.write("<!-- Place for storing the hidden values for multi-page -->\n")
	document.write("<Input type=text name='multi_maxpage'>\n<BR>");
	for(i=0;i<this.controls.length;i++){
		mControl = this.controls[i];
		name = mControl.cControl.name;
		document.write("\n<!-- Control: " + name + " -->");
		for(j=0;j<this.maxpage;j++) document.write("<Input type=text name='" + mControl.hiddenName + "'>\n");
		document.write("<BR><BR>");
	}
	document.write("<!-- Place for storing the hidden values for multi-page -->")
}


//-------------------------------------------------------------------------
// Update index -- should be replace with user specific function
//-------------------------------------------------------------------------
function multiUpdateIndex(currentPage,maxPage){ //dummy function
}


//-------------------------------------------------------------------------
// Get value from Hidden value
//-------------------------------------------------------------------------
function multiGetValue(index){
var frm, fieldObjs;
	frm = this.frm;
	fieldObjs = eval("frm." + this.hiddenName);
	return fieldObjs[index].value;
}


//-------------------------------------------------------------------------
// Set value to hidden value
//-------------------------------------------------------------------------
function multiSetValue(index,value){
	var frm, fieldObjs;
	frm = this.frm;
	fieldObjs = eval("frm." + this.hiddenName);
	fieldObjs[index].value = value == null? "" : value ;
}


//-------------------------------------------------------------------------
// Define multi-control object
//	Parameters:	frm			-- form object
//					control  	-- control
//					maxpage  	-- max. number of page
//					sDefault 	-- default value
//					hiddenName	-- hidden field name
//-------------------------------------------------------------------------
function multiControl(frm,control,maxpage,sDefault,hiddenName){
var i;
	this.frm = frm;								// form object
	this.getValue = multiGetValue;			// function to get the value from hidden field
	this.setValue = multiSetValue;			// function to set the value from hidden field
	this.defaultValue = sDefault;
	if(hiddenName==null) this.hiddenName = "multi_" + control.name;
	else this.hiddenName = hiddenName;
	this.cControl = control;
	//for(i=0;i<maxpage;i++) this.values[i]=sDefault;
	//this.values = new Array();
}


//-------------------------------------------------------------------------
// Define multi-pages object
//	Parameters:	frm 	  		 -- Form object
//					maxpage 		 -- max. number of page
//					withChecking -- true|false need to check each time when
//										 change pages
//-------------------------------------------------------------------------
function multiPage(frm,maxpage,withChecking){
	this.frm = frm;											// Form object
	this.initmax = maxpage;									// initial max. number of page
	this.maxpage = maxpage;									// max. number of page
	this.withChecking = withChecking;					// need to check each time when change pages
	this.currentIndex = 0;									// current index
	this.errormsg = "";										// error mesage
	this.add = multiAdd;										// Add control
	this.changeMax = multiChangeMax;						// Change max page value
	this.changePage = multiChangePage;					// Change Page
	this.moveNext = multiMoveNext;            		// Move to next Page
	this.movePrevious = multiMovePrevious;    		// Move to Previous Page
	this.moveFirst	= multiMoveFirst;          		// Move to First Page
	this.moveLast = multiMoveLast;            		// Move to Last Page
	this.Go = multiGoto;			               		// Goto Page index
	this.reset = multiReset;                  		// Reset this page
	this.resetAll = multiResetAll;            		// Reset all this page
	this.loadData = multiLoadData;						// Load data from form fields
	this.setData = multiSetData;							// Set form fields data
	this.checkCurrentPage = multiCheckCurrentPage;	// Check current page
	this.checkAllPage = multiCheckAllPage;				// Check current page
	this.fillHidden = multiFillHidden;        		// Fill in the form hidden value
	this.printHidden = multiPrintHidden;      		// Print the hidden form fields
	this.updateIndex = multiUpdateIndex;      		// Update Index
	this.controlsIndex = -1;								// Control index
	this.controls = new Array();							// Hold the controls
}
//-->

