(function(jQuery){
	jQuery.fn.checkFormAdvance=function(o)
	{
		o=o?o:{};
		var root=this;
		if(o.group&&o.msgBox)
		{
			jQuery(o.group).each(bindGroup);
		}
		iniFormCheck.call(this);
		return this;
		/**
		 * 初始化表单检查；
		 * @method
		 */
		function iniFormCheck()
		{
			var that=this;
			this.formItems=jQuery(":input[reg]",this);
			this.formItems.each(iniFormItem);
			this.checkForm=checkForm;
			this.btn=o.btnSubmit?jQuery(o.btnSubmit,this):null;
			if(this.btn) 
			{
				this.btn.click(function(){
					return that.checkForm()
				})
			}
			this.form=jQuery("form",this);
			if(this.form.length)
			{
				this.form.submit(function(){return that.checkForm()})
			}
		}
		/**
		 * 检查整个表单并调用回调函数
		 * @method
		 */
		function checkForm()
		{
			for(var i=0;i<this.formItems.length;i++)
			{
				if(!this.formItems[i].doTest())
				{return false}
			}
			var formComplete=true;
			var callBack=o.callBack?eval(o.callBack):null;
			if(jQuery.isFunction(callBack))
			{
				formComplete=callBack.apply(this);
			}
			return formComplete;
		}
		/**
		 * 初始化每个需要检查的表单；
		 * @method
		 */
		function iniFormItem()
		{
			var that=jQuery(this);
			this.msg=that.attr("msg")||decodeURI("%E4%B8%8D%E8%83%BD%E8%BE%93%E5%85%A5%E7%A9%BA%E5%AD%97%E7%AC%A6%E4%B8%B2");
			this.rel=getRelationEle(that.attr("rel"));
			this.reg=that.attr("reg")?getRegExp(that.attr("reg")):null;
			this.func=jQuery.isFunction(eval(that.attr("func")))?eval(that.attr("func")):null;
			this.doTest=doTest;
			this.showTest=showTest;
			that.change(doTest);
		}
		/**
		 * 根据传入的字符串生成正则表达式，内置了部分简单常用表达式。
		 * @param {String} regStr 用于生成正则的字符串;
		 * @return {RegExp} 返回正则表达式
		 */ 
		function getRegExp(regStr)
		{
			var regExp;
			switch (regStr)
			{
				case "ID":
					regExp=/(?:^\d{15}jQuery)|(?:^\d{17}[\dxX]jQuery)/;
					break;//身份证号码应为15～18位数字
				case "email":
					regExp=/^\w+@\w+\.\w{2,4}jQuery/;
					break;//邮箱地址应如：xxx@yyy.zzz格式
				case "msn":
					regExp=/^\w+@\w+\.\w{2,4}jQuery/;
					break;//msn号码应是一个邮箱
				case "date":
					regExp=/^\d{4}([-_\/\.]\d{2}){2}jQuery/;
					break;//日期应为yyyy-mm-dd格式，分割符可以为：-_/.
				case "qq":
					regExp=/^\d{5,10}jQuery/;
					break;//qq号应为5～10个数字
				case "tel":
					regExp=/^\d{8,12}jQuery/;
					break;//电话号码应为8～12位数字
				case "web":
					regExp=/.+\.\w{2,4}jQuery/;
					break;//电话号码应为8～12位数字
				default:
					regExp=new RegExp(regStr)
					break;
			}
			return regExp;
		}
		/**
		 * 获取相关联的元素,若传入的是字符串，则生成jQuery对象
		 * @param {String,jQuery} selector 
		 */
		function getRelationEle(selector)
		{
			var ele=typeof(selector)=="string"?jQuery(selector,root):selector;
			return selector&&ele.length?ele:null;
		}
		/**
		 * 执行测试，先以正则测试，通过后若有额外的方法，则执行它，并根据返回值显示信息。
		 * @method
		 */
		function doTest()
		{
			if(this.reg.test(this.value))
			{
				this.pass=this.rel&&this.value!=this.rel.val()?false:true;
				this.pass=this.pass&&(!this.func||this.func())?true:false;
			}
			else
			{
				this.pass=false;
			}
			this.showTest();
			return this.pass;
		}
		/**
		 * 显示验证结果
		 * @method
		 */
		function showTest()
		{
			if(!this.pass)
			{
				if(this.msgBox)
				{this.msgBox.showMsg("err");}
				else
				{alert(this.msg)}
				this.focus();
				this.select();
			}
			else
			{
				if(this.msgBox)
				{this.msgBox.showMsg("suc");}
			}
		}
		/**
		 * 显示提示信息
		 * @param {String} msgType 提示信息的类型
		 * @method
		 */
		function showMsg(msgType)
		{
			switch (msgType)
			{
				case "suc":
					this.removeClass("err").addClass("suc");
					break;
				case "err":
					this.addClass("err").removeClass("suc");
					break;
			}
			var msgTxtBox=this.msgTxtBox.length?this.msgTxtBox:this;
			msgTxtBox.html(this[msgType]);
		}
		/**
		 * 按组绑定msgBox
		 * @method
		 */
		function bindGroup()
		{
			var itemForCheck=jQuery(":input[reg]",this)
			var msgBox=jQuery(o.msgBox, this);
			if (itemForCheck[0]&&msgBox[0])
			{
				itemForCheck[0].msgBox = msgBox;
				if(o.msgTxtBox)
				{
					msgBox.msgTxtBox=$(o.msgTxtBox,msgBox);
				}
				msgBox.def=msgBox.msgTxtBox&&msgBox.msgTxtBox.length?msgBox.msgTxtBox.html():msgBox.html();
				msgBox.suc=itemForCheck.attr("suc")||msgBox.def;
				msgBox.err=itemForCheck.attr("msg");
				msgBox.showMsg=showMsg;
			}
		}
	}
})(jQuery);
