	Validation = {
		lang : 'english',
		form : null,
		elements : null,
		fieldname : null,
		rules : null,
		target : '',
		error_msg : new Array(),
		tag : 'p',
		
		/** Ajax Related **/
		ajax_target : '',
		action : '',
		/** End Ajax Related Var **/
		
		init : function( elements, fieldname, rules, language ) {
			if (language != undefined) {
				this.lang = language;
			}
			
			this.elements = elements;
			this.fieldname = fieldname;
			this.rules = rules;
			
			this.init_errormsg();
		},
		
		init_errormsg : function() {
			if (this.lang == 'english') {
				this.error_msg['ckvalid_heading'] = 'Error List : ';
				this.error_msg['required'] = ' must be field in.';
				this.error_msg['email'] = 'Invalid Email Address';
				this.error_msg['numeric'] = ' must contact numeric numbers only';
				this.error_msg['integer'] = ' must be an integer';
				this.error_msg['minValue'] = ' must be at least ';
				this.error_msg['maxValue'] = ' must not greater than';
			}
			else {
				this.error_msg['ckvalid_heading'] = '請更正以下錯誤 : ';
				this.error_msg['required'] = ' 必須填寫';
				this.error_msg['email'] = '請填寫正確電郵';
				this.error_msg['numeric'] = ' 必須是數字';
				this.error_msg['integer'] = ' 必需為整數';
				this.error_msg['minValue'] = ' 必須至少等於';
				this.error_msg['maxValue'] = ' 不能大於';
			}
		},
		
		set_errormsg: function( rules, msg ) {
			this.error_msg[rules] = msg;
		},
		
		set_error_tag: function ( tagname ) {
			this.tag = tagname;
		},
		
		set_ajaxPost: function (post_to) {
			this.action = post_to;
			this.ajax_target = '';
		},
		
		set_ajaxLoad: function (post_to, output) {
			this.action = post_to;
			this.ajax_target = output;
		},
		
		checkForm : function( form_name, target_block ) {
			this.form = $('form[name='+form_name+']');
			
			if (target_block != undefined) {				
				this.target = target_block;
				$(this.target).html('');
			}
			else {				
				$(this.form).find( this.tag + '.error' ).empty();		
			}
			
			var thisOk = new Boolean;	
			var submitOK = true;			
			
			for (var i = 0 ; i < this.elements.length ; i++) {
				//alert(this.elements[i]);
				var obj = $(this.form).find(':input[name='+this.elements[i]+']');
				
				thisOk = true;
				thisOk = this.checkError(obj, i);
								
				//alert(this.fieldname[i] + ' : ' + thisOK);
				if (thisOk == false) {
					submitOK = false;
				}
			}
			
			if (submitOK) {				
				this.handle_post();
				return true;
			}
			else {
				if (target_block != undefined) {
					$(this.target).prepend('<p class="error head"><b><u>'+this.error_msg['ckvalid_heading']+'</u></b></p>');
				}	
			}
			
			return false;
		},
		
		handle_post : function() {
			if (this.action == '') {
				this.form.submit();
			}
			else {
				if (this.ajax_target == '') {
					$.post(this.action, $(':input').serializeArray());
				}
				else {
					$(this.ajax_target).load(this.action, $(':input').serializeArray());
				}
			}
		},
		
		checkError : function( obj, i ) {
			var valueOK = true;
			var error = '';
			var arr_rules = this.rules[i].split('|');
			var full_rules = '';
			var msg = '';
			
			var obj_value = $(obj).val();		
			
			for (var j = 0 ; j < arr_rules.length ; j++) {
				full_rules = arr_rules[j];				
				switch(arr_rules[j].replace(/\[.*\]/, '')) {
					case 'required':                                       
						if ( obj_value == '' ) {
							valueOK = false;						
							msg = this.fieldname[i] + this.error_msg['required'];
							error = this.set_error(error, msg);
						}
						break;
					case 'email':                                    
						if ( !( this.isEmail(obj_value) ) ) {
							valueOK = false;
							msg = this.fieldname[i] + ' : ' + this.error_msg['email'];											
							error = this.set_error(error, msg);
						}
						break;
					case 'numeric':
						if ( !( this.isNumeric(obj_value) ) ) {
							valueOK = false;
							msg = this.fieldname[i] + this.error_msg['numeric'];											
							error = this.set_error(error, msg);
						}
						break;
					case 'integer':
						if ( !( this.isInterger(obj_value) ) ) {
							valueOK = false;
							msg = this.fieldname[i] + this.error_msg['integer'];											
							error = this.set_error(error, msg);
						}
						break;
					case 'minValue':
						var matches = full_rules.match(/\[(.*)\]/);					
						
						if (obj_value < parseInt(matches[1])) {
							valueOK = false;
							msg = this.fieldname[i] + this.error_msg['minValue'] + matches[1];											
							error = this.set_error(error, msg);
						}						
						break;
					case 'maxValue':
						var matches = full_rules.match(/\[(.*)\]/);					
						
						if (obj_value > parseInt(matches[1])) {
							valueOK = false;
							msg = this.fieldname[i] + this.error_msg['maxValue'] + matches[1];											
							error = this.set_error(error, msg);
						}						
						break;
					default:
						valueOk = true;
						error = '';
						break;
				}
			}

			if (valueOK != false) {
				this.removeError( $(obj).parent(), i );
			}
			else {
				this.appendError( $(obj).parent(), error, i);                     
			}
			
			return valueOK;
		},
		
		set_error : function( org_error, new_error ) {
			if (org_error != '') {
				return org_error;
			}
			else {
				return new_error;
			}		
		},
		
		appendError : function ( obj, error_msg, i ) {
			if (this.target == '') {	
				obj.find( this.tag + '.error.' + this.elements[i] ).empty();
				obj.append( '<' + this.tag + ' class="error ' + this.elements[i] +'">'+error_msg+'</' + this.tag + '>' );
				obj.addClass('error');
			}
			else {
				$(this.target).append('<' + this.tag +' class="error">'+error_msg+'</' + this.tag + '>');
			}
		},
		
		removeError : function (obj, i) {
			if (this.target == '') {		
				obj.find( this.tag + '.error.'+ this.elements[i]).empty();
				obj.removeClass('error');
			}			
		},
		
		isEmail : function ( email ) {
			return (email.search(/^\w+[A-Za-z0-9._-]*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1); 
		},
		
		isNumeric : function ( value ) {
			return (value.search(/^[\-+]?[0-9]*\.?[0-9]+$/) != -1); 
		},
		
		isInterger : function ( value ) {
			return (value.search(/(^-?\d\d*$)/) != -1);
		}
	};