/*  version 2.0
 *  (c) 2006-2007 Alan Hu
 *
 *  資料驗證程式
 *
/*--------------------------------------------------------------------------*/
function $(name) {
	var temp = null;
	temp = document.getElementById(name);
	if(temp!=null) {
		return temp;
	}
	temp = document.getElementsByName(name);
	if(temp!=null) {
		return temp[0];
	}
	return null;
}

function isEmpty(str) {
	for (var i = 0; i < str.length; i++)
		if (" " != str.charAt(i))return false;
	return true;
}


var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

var Select = Class.create();
Select.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (field.options.length == 0) {
			return true;
		}
		if (field.selectedIndex==-1 || isEmpty( field.options[ field.selectedIndex ].value ) ) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Radio = Class.create();
Radio.prototype = {
	maxSelection: null,
	count: 0,
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if(!field.length) {
			field = new Array(field);
		}
		this.count = 0;
		for(var i=0;i<field.length;i++) {
			if(field[i].checked) {
				this.count++;
			}
		}
		if(this.count == 0) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		this.count = 0;
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		if(this.maxSelection!=null && this.count > this.maxSelection) {
			command.setErrorMessage(this.errorMessage + "欄位最多只能選"+this.maxSelection+"項");
		}
		return true;
	},
	setMaxSelection : function(maxSelection) {
		this.maxSelection = maxSelection;
		return this;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};


var Checkbox = Class.create();
Checkbox.prototype = Radio.prototype;


var TextField = Class.create();
TextField.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate : function(command) {
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			} else {
				return true;
			}
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Integer = Class.create();
Integer.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
		
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate : function(command) {
		var field = command.getField(this.fieldName);
		
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		if (isNaN(field.value)) {
			command.setErrorMessage(this.errorMessage + "格式不正確! 應該是數值");
		}
		if(!isNaN(this.minValue) && field.value < this.minValue) {
			command.setErrorMessage(this.errorMessage + "不可小於"+this.minValue);
		}
		if(!isNaN(this.maxValue) && field.value > this.maxValue) {
			command.setErrorMessage(this.errorMessage + "不可大於"+this.maxValue);
		}
		return true;
	},
	setRange: function(minValue, maxValue) {
		if(!isNaN(minValue)) {
			this.minValue = minValue;
		}
		if(!isNaN(maxValue)) {
			this.maxValue = maxValue;
		}
		return this;
	},
	setMax: function(maxValue) {
		if(!isNaN(maxValue)) {
			this.maxValue = maxValue;
		}
		return this;
	},
	setMin: function(minValue) {
		if(!isNaN(minValue)) {
			this.minValue = minValue;
		}
		return this;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};


var Float = Class.create();
Float.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
		this.expression = null;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate : function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		if (isNaN(field.value)) {
			command.setErrorMessage(this.errorMessage + "格式不正確! 應該是數值");
		}
		if(!isNaN(this.minValue) && field.value < this.minValue) {
			command.setErrorMessage(this.errorMessage + "不可小於"+this.minValue);
		}
		if(!isNaN(this.maxValue) && field.value > this.maxValue) {
			command.setErrorMessage(this.errorMessage + "不可大於"+this.maxValue);
		}
		if(this.expression) {
			var scale = this.expression.scale;
			var integer = this.expression.precision - scale;
			var regExpression = "(^(\\d{0,"+integer+"})(\\.\\d{0,"+scale+"})?$)";
			if(!new RegExp(regExpression).test(field.value)) {
				command.setErrorMessage(this.errorMessage + "格式不正確! 整數最多"+integer+"位, 小數點勿超過"+scale+"位");
			}
		}
		return true;
	},
	setDecimal: function(precision, scale) {
		var temp = {"precision":0, "scale":0};
		temp.precision = precision;
		temp.scale = scale;
		this.expression = temp;
		return this;
		
	},
	setRange: function(minValue, maxValue) {
		if(!isNaN(minValue)) {
			this.minValue = minValue;
		}
		if(!isNaN(maxValue)) {
			this.maxValue = maxValue;
		}
		return this;
	},
	setMax: function(maxValue) {
		if(!isNaN(maxValue)) {
			this.maxValue = maxValue;
		}
		return this;
	},
	setMin: function(minValue) {
		if(!isNaN(minValue)) {
			this.minValue = minValue;
		}
		return this;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};


var TextArea = Class.create();
TextArea.prototype = {
	maxLength: null,
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		if (this.maxLength != null && field.value.length > this.maxLength){
			command.setErrorMessage(this.errorMessage + "欄位超過"+this.maxLength+"字元限制，請重新修改");
		}
		return true;
	},
	setMaxLength: function(maxLength) {
		this.maxLength = maxLength;
		return this;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var FCKeditorTextField = Class.create();
FCKeditorTextField.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var fieldValue = FCKeditorAPI.GetInstance(this.fieldName).GetXHTML(false);
		if (isEmpty(fieldValue)) {
			return true;
		}
		return false;
	},
	isValidate : function(command) {
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Password = Class.create();
Password.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var fields = command.getFields(this.fieldName);
		var field = fields[0];
		var confirmField = fields[1];
		if (isEmpty(field.value) && this.isNecessary) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var fields = command.getFields(this.fieldName);
		var field = fields[0];
		var confirmField = fields[1];
		if(field==null) {
			command.setErrorMessage("找不到 " + this.fieldName + " 欄位");
		}
		if(confirmField==null) {
			command.setErrorMessage("找不到 " + this.fieldName + " 的確認欄位");
		}
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			} else {
				return true;
			}
		}
		var pattern = /^[a-zA-Z0-9]{6,}/;
		if( !pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "請輸入六碼以上的英文或數字!");
		}
		if(field.value != confirmField.value) {
			command.setErrorMessage("輸入的密碼不一致");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var MobilePhone = Class.create();
MobilePhone.prototype = {
	correctLength: 10,
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate : function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			} else {
				return true;
			}
		}
		if (field.value.substring(0,2) != "09") {
			command.setErrorMessage(this.errorMessage + "輸入錯誤");
		}
		if (field.value.length != this.correctLength) {
			command.setErrorMessage(this.errorMessage + "資料長度不正確！");
		}
		if (isNaN(field.value)) {
			command.setErrorMessage(this.errorMessage + "格式不正確! 應該為數字");
		}
		return true;
	},
	setCorrectLength: function(correctLength) {
		this.correctLength = correctLength;
		return this;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Email = Class.create();
Email.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			} else {
				return true;
			}
		}
		var pattern = /^([a-zA-Z\.0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
		if( !pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "格式不正確!");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Account = Class.create();
Account.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		//第一個字元用 a-z, A-Z, 0-9
		var pattern = new RegExp("^[a-zA-Z0-9]+", "g");
		if( !pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "第一個字母必須是a-z, A-Z, 0-9!");
		}
		//不能有例外字元
		pattern = new RegExp("[^a-zA-Z0-9_-]+", "g");
		if( pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "除了a-z, A-Z, 0-9 , -, _ 不能有其他字元!");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};


var URL = Class.create();
URL.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填，請輸入以http://為開頭的網址");
			} else {
				return true;
			}
		}
		var pattern = /^(http|https):\/\/.+/;
		if(pattern.test(field.value)==false) {
			command.setErrorMessage(this.errorMessage + "網址格式不正確，請輸入以http://為開頭的網址");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var UploadFile = Class.create();
UploadFile.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
			} else {
				return true;
			}
		}
		
		var ext = field.value.substring(field.value.lastIndexOf(".")+1).toLowerCase();
		if (ext != "doc"){
			command.setErrorMessage(this.errorMessage + "檔案類型不符，請上傳word(.doc)檔案");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var DateFormat = Class.create();
DateFormat.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		var text = field.value;
		var timeFormat = this.format;
		var date = new Date();
		var o = new Array ("(y+)","(M+)","(d+)","(h+)","(m+)","(s+)");
		var data = new Array (-1,-1,-1);
		for(var i=0; i<o.length; i++){
			var yearReg = new RegExp(o[i]);
			if(new RegExp(o[i]).test(timeFormat)){
				var start = timeFormat.search(yearReg)
				//必須是數字
				var value = text.substr(start, RegExp.$1.length);
				if(value=="" || isNaN(value)) {
					command.setErrorMessage(this.errorMessage + "格式不正確("+this.format+")");
					return;
				}
				if(i <= 2) {
					data[i] = parseInt(value,10);
				}
				timeFormat = timeFormat.replace(RegExp.$1, value);
			}
		}
		if(timeFormat!=text) {
			command.setErrorMessage(this.errorMessage + "格式不正確("+this.format+")");
		}
		
		var dayArray = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
		yearFormat = data[0];
		monthFormat = data[1];
		dayFormat = data[2];

		if(monthFormat==2 && (yearFormat % 4)==0 ) {
			dayArray[2] = 29;
		}
		if( !dayArray[monthFormat] || dayFormat > dayArray[monthFormat]) {
			command.setErrorMessage(this.errorMessage + "格式不正確");
		}
		return true;
	},
	setFormat: function(format) {
		this.format = format;
		return this;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
}

var PersonalID = Class.create();
PersonalID.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isEmpty: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			return true;
		}
		return false;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (this.isEmpty(command)) {
			if(this.isNecessary) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
				return false;
			}
			return true;
		}
		data = field.value;
		var UserID = data.toUpperCase();
		var AreaCode = UserID.charAt(0);
		// 取得首碼對應的區域碼，A ->10, B->11, ..H->17,I->34, J->18...
		var AreaNo = ("ABCDEFGHJKLMNPQRSTUVXYWZIO".indexOf(AreaCode)) + 10;
		// 確定身分證有10碼
		if ((UserID.length) != 10) {
			command.setErrorMessage(this.errorMessage + "格式不正確！");
		}
		// 確定首碼在A-Z之間
		if ((AreaCode < "A") || (AreaCode > "Z")) {
			command.setErrorMessage(this.errorMessage + "格式不正確！");
		}
		// 確定2-10碼是數字
		if (isNaN(parseInt(UserID.substring(1,10)))){
			command.setErrorMessage(this.errorMessage + "格式不正確！");
		}
		UserID = AreaNo.toString() + UserID.substring(1,10);
		// 取得CheckSum的值
		CheckSum = parseInt(UserID.charAt(0)) + parseInt(UserID.substring(10,11));
		for(var i=2;i<=10;i++){
			CheckSum = CheckSum + parseInt(UserID.substring(i-1,i)) * (11 - i);
		}
		if ((CheckSum % 10) != 0){
			command.setErrorMessage(this.errorMessage + "格式不正確！");
		}

		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};
var Association = Class.create();
Association.prototype = {
	initialize: function(errorMessage) {
		this.checkArray = new Array();
		this.errorMessage = errorMessage;
		this.isNecessary = true;
		this.selectedMinObject = 1;
	},
	isValidate: function(command) {
		var correct = 0;
		for(var i=0;i<this.checkArray.length;i++) {
			if(!this.checkArray[i].isEmpty(command)) {
				correct++;
			}
			command.reset();
		}
		if(correct < this.selectedMinObject) {
			command.setErrorMessage(this.errorMessage + "至少要填寫" + this.selectedMinObject + "個！");
		}
		return true;
	},
	add: function(obj) {
		this.checkArray[this.checkArray.length] = obj;
		return this;
	}
};

var Confirm = Class.create();
Confirm.prototype = {
	initialize: function(errorMessage) {
		this.errorMessage = errorMessage;
	},
	isValidate: function(command) {
		if(!confirm(this.errorMessage)) {
			command.setErrorMessage("");
		}
		return true;
	}
};

var Command = Class.create();
Command.prototype = {
	fields: new Array(),
	initialize: function(form, formValidator) {
		this.form = form;
		this.formValidator = formValidator;
		this.fields = new Array();
	},
	reset: function() {
		this.fields = new Array();
	},
	setErrorMessage: function(message) {
		if(this.fields!=null && this.fields[0]!=null) {
			var field = this.fields[0];
			if(!field.length) {
				field.focus();
			} else {
				field[0].focus();
			}

		}
		throw new Error(message);
	},
	getFields: function(name) {
		var formFields = name.split(",");
		for(var i=0;i<formFields.length;i++) {
			var field = eval("this.form."+formFields[i]);
			if(field==null) {
				throw new Error("找不到 "+formFields[i]+" 欄位");
			}
			
			this.fields[this.fields.length] = field;
		}
		return this.fields;
	},
	getField: function(name) {
		var field = eval("this.form."+name);
		if(field==null) {
			throw new Error("找不到 "+name+" 欄位");
		}
		this.fields[this.fields.length] = field;
		return this.fields[0];
	}
};


var FormValidator = Class.create();
FormValidator.prototype =  {
	checkArray: [],
	initialize: function(formName) {
		this.checkArray = [];
		this.formName = formName;
	},
	add: function(fieldObject) {
		this.checkArray[this.checkArray.length] = fieldObject;
	},
	checkData: function() {
		
		var form = $(this.formName);
		if(form==null) {
			throw new Error("找不到取名為 " + this.formName + " 的Form");
		}
		try {
			command = new Command(form, this);
			
			for(var i=0;i<this.checkArray.length;i++) {
				this.checkArray[i].isValidate(command);
				command.reset();
			}
		} catch(e) { 
			if(e.message && e.message!="") {
				throw e;
			}
			return false;
		}
		
		return true;
	},
	isEmpty: function(fieldName) {
		
		var form = $(this.formName);
		if(form==null) {
			throw new Error("找不到取名為 " + this.formName + " 的Form");
		}
		var field = eval("form."+fieldName);
		return isEmpty(field.value);
	}
};
var FormObject = Class.create();
FormObject.prototype = FormValidator.prototype;