﻿$.fn.extend({
    tips: function(options){
        var o = {
            delay: 500,
            relation: '',
            parent: window,
            reMaxWidth: 'auto',
            tgClass: '',
            position: 'r' // t,r,b,l,lt,lb,rt,rb
        };
        $.extend(o,options);
        
        var re = $(o.relation),
            reMaxWidth = o.reMaxWidth,
            aTimer = null,
            self = this;
 
        this.hover(
            function(){
                aTimer = setTimeout(function(){
                    var offset = self.position(), l,t, position = o.position;
                    
                    if(o.tgClass) self.addClass(o.tgClass);
                    
                    re.show();
                    //alert(re.outerWidth())
                    //计算relation的宽度
                    //debugger;
                    if(reMaxWidth != 'auto'){
                        //计算里面元素宽度值和
                        var allwidth = 0;
                        re.children('a').each(function(){
                            allwidth += $(this).outerWidth(true);
                        });
                        //debugger;
                        if(allwidth > reMaxWidth){
                            re.width(reMaxWidth);
                        }
                        else{
                            re.width(allwidth);
                        }
                    }
                    
                    var reWidth = re.outerWidth(), reBlankWidth = reWidth - re.width();
                    //debugger;
                    //计算需摆放的位置
                    if(position == 'r'){
                        var leftWidth = offset.left,
                            reParent = o.parent,
                            rightWidth = ( reParent == window ? $(reParent).width() : $(reParent).outerWidth()) - leftWidth - self.outerWidth();
                        //alert(( o.parent == window ? $(o.parent).width() : $(o.parent).outerWidth) +'-'+ leftWidth +'-'+ self.outerWidth() +'='+  rightWidth +'<'+ reWidth);
                        
                        //debugger;
                        if(rightWidth < reWidth){
                            if( rightWidth < leftWidth ){
                                if( leftWidth < reWidth ){
                                    re.width( leftWidth - reBlankWidth - 2);
                                }
                                position = 'l';
                            }
                            else{
                                if( rightWidth < reWidth){
                                    re.width(rightWidth - reBlankWidth - 2);
                                }
                            }
                        }
                        
                    }
//                    else if(position == 'b'){
//                        
//                    }
                    
                    switch(position){
                        case 'r':
                            
                            l = offset.left + self.outerWidth();
                            t = offset.top;
                            
                        break;
                        
                        case 'l':
                            
                            l = offset.left - re.outerWidth();
                            t = offset.top;
                        
                        break;
                        
                        case 'b':
                            
                            l = offset.left;
                            t = offset.top + self.outerHeight();
                        
                        break;
                        
                        default: break;
                    }
                    //alert(l +'--'+ t)
                    re.css({'left': l, 'top': t}).show();
                      
                },o.delay);
            },function(){
                clearTimeout(aTimer);
                aTimer = setTimeout(function(){
                    self.removeClass(o.tgClass);
                    re.hide();
                },o.delay);
            }
        )

        re.hover(
            function(){
                clearTimeout(aTimer);
                $(this).show();
            },
            function(){
                clearTimeout(aTimer);
                
                aTimer = setTimeout(function(){
                    self.removeClass(o.tgClass);
                    re.hide();
                },o.delay);
            }
        );

    },
    
    validator: function(options){
        var o = {
            sb: '',
            form: '',
            callback: null
        };
        $.extend(o,options);
        
        var self = this,
            ii = $(':input',self),
            inputs = ii.filter(':not(:button,:radio,:checkbox,:file)'),
            chInputs = ii.filter(':radio,:checkbox'),
            inputsHidden = ii.filter(':hidden,:file'),
            
            method = {
                isPass: false,
                
                blur: function(a,b){
                    var self = b;
                    if(!b) self = $(this);
                    
                    var field = self.attr('field'),
                        value = $.trim(self.val()),
                        isBlank = self.attr('isBlank');
                        
                    if(self.is('select') && value === '0') value = '';
                    
                    if(value === ''){
                        if(isBlank === 'false')
                            return method.error(self);
                        else
                            return;
                    }
                    
                    if(!field) return method.ok(self);
                    
                    method.chk(self,value,field,isBlank);
                    
                },
                
                focus: function(){
                    var self = $(this);
                    //method.showTip();
                },
                
                chk: function(self,value,field,isBlank){
                    switch(field){
                        case 'member': 
                        
                            var regex = /^[\dA-Za-z_]+$/;
            		        
		                    if(!regex.test(value)){
		                        return method.error(self,'用户名由字母、数字和下划线组成');
		                    }
		                    else{
		                        var rgx = /^([A-Za-z])[\dA-Za-z_]*$/;
		                        if(!rgx.test(value)) return method.error(self,'用户名必须以字母开头');
		                    }
            		        
		                    var iLen = value.length;
            		        
                            if(iLen < 6 || iLen > 20){ 
                                return method.error(self,'会员名在6-20个字符内');
                            }
                            
                            var back = self.attr('back');
                            if(back){
                                var params = self.attr('params');
                                var isOk = eval(back + '("' + value + '","' + params + '")');
                                if(!isOk) return method.error(self,'会员名已注册，请重新输入');
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'email': 
                            
                            var regex = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/; 
                            
                            if(!regex.test(value)){
		                        return method.error(self,'请输入正确格式的邮箱！');
		                    }
    		                
		                    var back = self.attr('back');
                            if(back){
                                var params = self.attr('params');
                                var isOk = eval(back + '("' + value + '","' + params + '")');
                                if(!isOk) return method.error(self,'该邮箱已注册，请重新输入');
                            }
                            
		                    method.ok(self);
                            
                            break;
                            
                        case 'pw':
                        
                            if(value.length < 6 || value.length > 20) return method.error(self,'密码在6-20个字符内！');
                            
                            method.ok(self);
                            
                            this.pw = value;
                            
                            break;
                        
                        case 'repw':
                            
                            if(value.length < 6 || value.length > 20) return method.error(self,'密码在6-20个字符内！');
                            
                            if(value != this.pw)  return method.error(self,'密码不匹配');
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'code':
                            if(value == '') return method.error(self,'验证码还没填呢');
                            
                            var back = self.attr('back');
                            if(back){
                                var params = self.attr('params');
                                var isOk = eval(back + '("' + value + '","' + params + '")');
                                if(!isOk) return method.error(self,'验证码输入不正确，请重新输入');
                            }
                            
                            method.ok(self);
                            break;
                        
                        case 'title': 
                            
                            var length = self.attr('length'),
                                minLength, maxLength;
                            
                            if(length){
                                var l = length.split('-');
                                if(l.length == 1){
                                    maxLength = l[0];
                                }
                                else if(l.length == 2){
                                    minLength = l[0];
                                    maxLength = l[1];
                                }
                            }else{
                                return method.ok(self);
                            }
                            
                            var iLen = 0;
                            
                            for(var i = 0, j = value.length;i < j; i++)
		                    {
		                        var strSub = value.charAt(i);
            		            
		                        if('0' <= strSub && strSub <= 'z' )
		                        {
		                            iLen = iLen + 1;
		                        }
		                        else
		                        {
		                            iLen = iLen + 2;
		                        }
		                    }
    		                
		                    if(minLength && iLen < minLength){
		                        return method.error(self,'长度不能小于' + minLength + '字符，一个汉字为2个字符！');
		                    }
    		                
		                    if( iLen > maxLength)
		                    {
		                        return method.error(self,'长度不能超过' + maxLength + '字符，一个汉字为2个字符！');
		                    }
    		                
		                    var back = self.attr('back');
                            if(back){
                                var isOk = eval(back + '("' + value + '")');
                                if(!isOk) return method.error(self,self.attr('backmsg'));
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'price':
                            
                            var rgx = /^\d*(?:\.\d{0,2})*$/;
                            
                            if(!rgx.test(value)){
                                return method.error(self,'请输入数字，而且小数点后不超过2位数');
                            }
                            
                            var max = + self.attr('max');
                            value = + value;
                            
                            if(value > max){
                                return method.error(self,'填写0-'+ max +'之间的数值');
                            }
                            
                            method.ok(self);

                            break;

                        case 'integer':

                            var rgx = /^[\d\-]*$/;

                            if (!rgx.test(value)) {
                                return method.error(self, '请输入一个正整数');
                            }else if(self.attr('range')!=''){
                                var rng = self.attr('range').split("-");
                                if(rng.length==2){
                                    var n1 = Number(rng[0]), n2 = Number(rng[1]);
                                    if(n1==0 && value>=n2){
                                        return method.error(self, '请输入一个小于'+ n2 +'的正整数');
                                    }else if(n2 == 0 && value<= n1 ){
                                        return method.error(self, '请输入一个大于'+ n1 +'的正整数');
                                    }if( n1*n2 > 0 && (value - n1<0 || value - n2>0 )){
                                        return method.error(self, '请输入一个'+ n1 +' - '+ n2 +'的正整数');
                                    }
                                }
                            }

   
                            method.ok(self);

                            break;
                        
                        case 'tel': 
                            
                            var rgx = /^1[3|5|8]\d{9}$/;
                            
                            if(!rgx.test(value)){
                                return method.error(self,'请输入正确格式的手机号码！')
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'mobile': 
                            
                            var rgx = /^0\d{2}-\d{8}$|0\d{3}-\d{7,8}$/;
                            
                            if(!rgx.test(value)){
                                return method.error(self,'格式错误！')
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'tm':
                        
                            var rgx = /^[\d\s-]+$/ // /^(0\d{2}-\d{8}$|0\d{3}-\d{7,8})$|^(1[3|5|8]\d{9})$/;
                            
                            if(!rgx.test(value)){
                                return method.error(self,'格式错误！')
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'url':
                            var strRegex = "^((https|http|ftp|rtsp|mms)?://)"
                                  + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@
                                        + "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184
                                        + "|" // 允许IP和DOMAIN（域名）
                                        + "([0-9a-z_!~*'()-]+\.)*" // 域名- www.
                                        + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名
                                        + "[a-z]{2,6})" // first level domain- .com or .museum
                                        + "(:[0-9]{1,4})?" // 端口- :80
                                        + "((/?)|" // a slash isn't required if there is no file name
                                        + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
                                        //var re=new RegExp(strRegex); 
                            
                            var rgx = new RegExp(strRegex);
                            
                            if(!rgx.test(value)){
                                return method.error(self,'格式错误！')
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'postal':
                            
                            var rgx = /^\d{6}$/;
                            
                            if(!rgx.test(value)){
                                return method.error(self,'格式错误！')
                            }
                            
                            method.ok(self);
                            
                            break;
                            
                        case 'qq':
                            
                            var rgx = /^\d{5,}$/;
                            
                            if(!rgx.test(value)){
                                return method.error(self,'格式错误，只接受数字！')
                            }
                            
                            method.ok(self);
                            
                            break;
                        
                        case 'suburl':
                            
                            var rgx = /^[\dA-Za-z]+$/;
            		        
		                    if(!rgx.test(value)){
		                        return method.error(self,'URL由字母和数字组成');
		                    }
    		                
		                    if(value.length < 2){
		                        return method.error(self,'URL长度小于2字符！');
		                    }
                            
                            var length = + self.attr('length');
                            
                            if( value.length > length){
                            
		                        return method.error(self,'URL长度超过' + length + '字符！');
		                    }
                            
                            var back = self.attr('back');
                            if(back){
                                var isOk = eval(back + '("' + value + '")');
                                if(!isOk) return method.error(self,'该域名已被注册，请重新输入！');
                            }
                            
                            method.ok(self);
                            
                            break;
                            
                        default: 
                        
                            var rgx = new RegExp(field);
                            
                            if(!rgx.test(value)){
                                return method.error(self,self.attr('msg'))
                            }
                            
                            method.ok(self);
                        break;
                        
                    }
                },
                
                error: function(self,msg){
                    method.isPass = false;
                    self.siblings('.ok').hide();
                    var error = self.siblings('.error');
                    if(msg){
                        error.html('<i></i>'+msg);
                    }
                    error.show();
                },
                
                ok: function(self){
                    self.siblings('.error').hide();
                    self.siblings('.ok').html('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;').show();
                },
                
                isChked: function(){
                    var inputName = {},
                        name = ''; 
                    if(!chInputs.length) return;
                    
                    for(var i = 0, j = chInputs.length; i < j; i++){
                        name = chInputs.eq(i).attr('name');
                        if(typeof inputName[name] === 'undefined'){
                            inputName[name] = chInputs.eq(i).attr('type');
                        }
                    }
                    
                    for(var key in inputName){
                        if( key === undefined) continue;
                        
                        var ishave = $(':' + inputName[key] + '[name='+ key +']');
                        
                        if(ishave.filter(':checked').length) {
                            method.ok(ishave.eq(0).parent());
                            
                        }
                        else{
                            method.error(ishave.eq(0).parent());
                        }
                        
                    }
                },
                
                isOnchage: function(){
                    for(var i = inputsHidden.length - 1; i >= 0; i--){
		                method.blur('',inputsHidden.eq(i));
		            }
                },
                
                chkAll: function(){
                    method.isPass = true;
                    for(var i = inputs.length - 1; i >= 0; i--){
		                method.blur('',inputs.eq(i));
		            }
    		        
		            method.isChked();
		            
		            method.isOnchage();
    		        
                    if(!method.isPass){
                        $(o.form).submit(function(){return false;});
                        var firstError = self.find('.error:visible:first').siblings('input:text').focus().end(),
                            fTop = firstError.offset().top,
                            wTop = $(window).scrollTop();
                        
                        if( fTop < wTop)
                            $(window).scrollTop(fTop - 10);
                        
//                        firstError[0].scrollIntoView(true);    
                        return false;
                    }
                    var callback = o.callback;
                    if(callback) callback();

                }
            };
        
        
        inputs.bind({
            'blur': method.blur,
            'focus': method.focus
        });
        
        inputsHidden.bind({
            'change': method.blur
        });
        
        $(o.sb).bind('click',method.chkAll);
    },
    
    gyTabs: function(){
        this.click(function(e){
            var o = $(e.target);
            if(o.is('a:not(.on)')){
                var ac = o.siblings('.on');
                ac.removeClass('on');
                $(ac.attr('href')).hide();
                o.addClass('on');
                $(o.attr('href')).show();
            }
            return false;
        })
    }
});
