/*  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;
	},
	isValidate: function(command) {
		field = command.getField(this.fieldName);
		if (field.options.length == 0) {
			command.setErrorMessage(this.errorMessage + "欄位未選");
		}
		if (field.selectedIndex==-1 || isEmpty( field.options[ field.selectedIndex ].value ) ) {
			command.setErrorMessage(this.errorMessage + "欄位未選");
		}
		return true;
	}
};

var Radio = Class.create();
Radio.prototype = {
	maxSelection: null,
	count: 0,
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
	},
	isValidate: function(command) {
		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) {
			command.setErrorMessage(this.errorMessage + "欄位未選擇");
		}
		if(this.maxSelection!=null && this.count > this.maxSelection) {
			command.setErrorMessage(this.errorMessage + "欄位最多只能選"+this.maxSelection+"項");
		}

		return true;
	},
	setMaxSelection : function(maxSelection) {
		this.maxSelection = maxSelection;
		return this;
	}
};


var Checkbox = Class.create();
Checkbox.prototype = Radio.prototype;


var TextField = Class.create();
TextField.prototype = {
	maxLength: null,
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
	},
	setMaxLength: function(maxLength) {
		this.maxLength = maxLength;
		return this;
	},
	isValidate : function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value)) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		if (this.maxLength != null && field.value.length > this.maxLength){
			command.setErrorMessage(this.errorMessage + "欄位超過"+this.maxLength+"字元限制，請重新修改");
		}
		return true;
	}
};

var Integer = Class.create();
Integer.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate : function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		
		if (isNaN(field.value)) {
			command.setErrorMessage(this.errorMessage + "格式不正確! 應該是數值");
		}
		return true;
	},
	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;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		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;
	}
};

/*
 * plugin method
*/
var PersonalID = Class.create();
PersonalID.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		data = field.value;
		//空值
		if (isEmpty(data) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		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 Password = Class.create();
Password.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	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 (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		var pattern = /^[a-zA-Z0-9]{4,}/;
		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 Email = Class.create();
Email.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		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;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		//第一個字元用 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;
	}
};

var Member = Class.create();
Member.prototype = Account.prototype;

var DateFormat = Class.create();
DateFormat.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		//空值
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		if(this.format=="YYYYMMDD") {
			var pattern = new RegExp("^[0-9]{8,8}$", "g");
			if( !pattern.test(field.value) ) {
				command.setErrorMessage(this.errorMessage + "格式不正確(YYYYMMDD)");
			}
			var yearFormat =  field.value.substring(0,4);
			var monthFormat =  field.value.substring(4,6);
			var dayFormat =  field.value.substring(6,8);
		}
		if(this.format == "YYYY/MM/DD") {
			var pattern = new RegExp("^[0-9]{4,4}/[0-9]{1,2}/[0-9]{1,2}$", "g");
			if( !pattern.test(field.value) ) {
				command.setErrorMessage(this.errorMessage + "格式不正確(YYYY/MM/DD)");
			}
			formatArray = field.value.split("/");
			var yearFormat =  formatArray[0];
			var monthFormat =  formatArray[1];
			var dayFormat =  formatArray[2];
		}
		var dayArray = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
		yearFormat = parseInt(yearFormat,10);
		monthFormat = parseInt(monthFormat,10);
		dayFormat = parseInt(dayFormat,10);

		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 DateFormat2 = Class.create();
DateFormat2.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		var fields = command.getFields(this.fieldName);
		if(this.isNecessary) {
			if (isEmpty(fields[0].value)) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
			}
			if (isEmpty(fields[1].value)) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
			}
			if (isEmpty(fields[2].value)) {
				command.setErrorMessage(this.errorMessage + "欄位未填");
			}
		}
		var yearFormat =  fields[0].value;
		var monthFormat = fields[1].value;
		var dayFormat =  fields[2].value;
		var dayArray = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
		yearFormat = parseInt(yearFormat,10);
		monthFormat = parseInt(monthFormat,10);
		dayFormat = parseInt(dayFormat,10);
		if(monthFormat==2 && (yearFormat % 4)==0 ) {
			dayArray[2] = 29;
		}
		if( !dayArray[monthFormat] || dayFormat > dayArray[monthFormat]) {
			command.setErrorMessage(this.errorMessage + "格式不正確");
		}
		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;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		//空值
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		pattern = new RegExp("^[http://]?[a-zA-Z0-9_-]+(\.+[a-zA-Z0-9_-]+){1,}", "g");
		if( !pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "格式不正確!");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Invoice = Class.create();
Invoice.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		var cx = new Array(1,2,1,2,1,2,4,1);
		var SUM = 0;
		var pattern = /^(\d{8,8})$/;
		if( !pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "格式不正確!應該是八碼的數字");
		}
		//分割成字元陣列
		var cnum = Num.split("");
		for (i=0; i<8; i++) {
			var n = cnum[i] * cx[i];
			//若乘出來的值為二位數則將十位數和個位數相加, 並傳回
			if (n > 9) {
				n = parseInt(n/10) + n%10;
			}
			SUM += n;
		}
		if (SUM % 10 != 0) {
			//若上述演算不正確但是 G 為 7, 再加上 1 被 10 整除也為正確
			if( !(cnum[6] == 7 && (SUM + 1)%10 == 0) ) {
				command.setErrorMessage(this.errorMessage + "格式不正確!");
			}
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var Folder = Class.create();
Folder.prototype = {
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		var field = command.getField(this.fieldName);
		if (isEmpty(field.value) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		var pattern = /['|"]/g;
		if( pattern.test(field.value) ) {
			command.setErrorMessage(this.errorMessage + "資料夾名稱請勿輸入[ \' 或 \"]字元");
		}
		return true;
	},
	setRequired: function(isNecessary) {
		this.isNecessary = isNecessary;
		return this;
	}
};

var CreditCard = Class.create();
CreditCard.prototype = {
	VISA: "11",
	MASTER: "12",
	JCB: "13",
	initialize: function(fieldName, errorMessage) {
		this.fieldName = fieldName;
		this.errorMessage = errorMessage;
		this.isNecessary = true;
	},
	isValidate: function(command) {
		//傳入卡號[0]跟卡別[1]
		var fields = command.getFields(this.fieldName);
		for(var i=0;i<fields[1].length;i++) {
			if(fields[1][i].checked) {
				var cardType = fields[1][i];
				break;
			}
		}
		cardNoData =  cardNo.value;
		cardTypeData = cardType.value;
		if (isEmpty(cardNoData) && this.isNecessary) {
			command.setErrorMessage(this.errorMessage + "欄位未填");
		}
		chv = parseInt(cardNoData.substring(0,2));
		if(cardTypeData==this.MASTER){
			chv  -= 50;
			if (chv<0 || chv >10 || cardNoData.length != 16) {
				command.setErrorMessage("您的卡號有問題，請重新輸入 !\n");
			}
		}
		if(cardTypeData==this.VISA){
			chv  -= 40;
			if (chv<0 || chv >10 || cardNoData.length != 16) {
				command.setErrorMessage("您的卡號有問題，請重新輸入 !\n");
			}
		}
		if(cardTypeData==this.JCB){
			if ((chv != "34" && chv != "37") ||  cardNoData.length != 15) {
				command.setErrorMessage("您的卡號有問題，請重新輸入 !\n");
			}
		}
		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");
		}
		
		command = new Command(form, this);
		for(var i=0;i<this.checkArray.length;i++) {
			this.checkArray[i].isValidate(command);
			command.reset();
		}
		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;