var validatorMap={
  'required':['本项必填',function(element,v){
   return v!=null && v!='';
  }],
  'number':['请录入数值',function(element,v){
   return !isNaN(v) && !/^\s+$/.test(v);
  }],
   'msn':['请输入MSN',function(element,v){
    return v == null || v == '' ||/\S+@\S+/.test(v);
  }],
  'email':['请录入正确的Email地址',function(element,v){
   return v == null || v == '' ||/(\S)+[@]{1}(\S)+[.]{1}(\w)+/.test(v);
  }],
  'url':['请录入正确的网址',function(element,v){
   return v==null || v=='' || /^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*)(:(\d+))?\/?/i.test(v);
  }],
  'area':['请选择完整的地区',function(element,v){
    return  element.getElements('select').every(function(sel){
      var selValue=sel.get('value');
      sel.focus();
      return selValue!=''&&selValue!='_NULL_';
    });
  }]
 };

var validate = function(_form) {
    if (!_form) return true;
    var formElements = _form.match('form') ? _form.getElements('[vtype]') : [_form];
    var err_log = false;
    var _return = formElements.every(function(element) {
        var vtype = element.get('vtype');
        if (!vtype) return true;
        if (!element.isDisplay() && (element.getAttribute('type') != 'hidden')) return true;
        var valiteArr = vtype.split('&&');
        if (element.get('required')) {
            valiteArr = ['required'].combine(valiteArr.clean());
        }
        return vtype.split('&&').every(function(key) {
            if (!validatorMap[key]) return true;
            var _caution = element.getNext('.caution');
            var cautionInnerHTML = element.get('caution') || validatorMap[key][0];
            if (validatorMap[key][1](element, element.get('value'))) {
                if (_caution && _caution.hasClass('error')) {
                    _caution.destroy();
                }
                return true;
            }
            if (!_caution || ! _caution.hasClass('caution')) {
                new Element('span', {
                    'class': 'error caution notice-inline',
                    'html': cautionInnerHTML
                }).inject(element,'after');
                element.removeEvents('blur').addEvent('blur', function() {
                    if (validate(element)) {
                        if (_caution && _caution.hasClass('error')) {
                            _caution.destroy();
                        }
                        element.removeEvent('blur', arguments.callee);
                    }
                });
            } else if (_caution && _caution.hasClass('caution') && _caution.get('html') != cautionInnerHTML) {
                _caution.set('html', cautionInnerHTML);
            }
            if(element.type!='hidden'&&element.isDisplay()&&!err_log)err_log=element;
            return false;
        });
    });
    if(_form.match('form')&&err_log){try{err_log.focus();}catch(e){}}
    return _return;
};


function selectArea(sel,path,depth){
    var sel=$(sel);
    if(!sel)return;

    var sel_value=sel.value;
    var sel_panel=sel.getParent();
    var selNext=sel.getNext();
    var areaPanel= sel.getParent('*[package]');
    var hid=areaPanel.getElement('input[type=hidden]');
    var curOption=$(sel.options[sel.selectedIndex]);

    var setHidden=function(sel){
        var rst=[];
        var sel_break = true;

        if (curOption && !curOption.get('has_c')){

            var _currChliSpan = sel.getNext('.x-region-child');
            if (_currChliSpan){
                _currChliSpan.destroy();
            }

        }

        var sels=areaPanel.getElements('select');
        sels.each(function(s){
          if(s.get('value')!= '_NULL_' && sel_break){
              rst.push($(s.options[s.selectedIndex]).get('text'));
          }else{
            sel_break = false;
          }
        });

        if(sel.value != '_NULL_'){
            areaPanel.getElement('input').value = areaPanel.get('package')+':'+rst.join('/')+':'+sel.value;
        }else{
            areaPanel.getElement('input').value =function(sel){
                          var s=sels.indexOf(sel)-1;
                          if(s>=0){
                             return areaPanel.get('package')+':'+rst.join('/')+':'+sels[s].value;
                          }
                          return '';
            }(sel);
        }
        hid.retrieve('onselect',function(){})(sel);
    };
    if(sel_value=='_NULL_'&&selNext&&(selNext.get('tag')=='span' && selNext.hasClass('x-areaSelect'))){
        sel.getNext().empty();
        setHidden(sel);
    }else{
        /*nextDepth*/
        if(curOption.get('has_c')){
          new Request({
                url:Shop.url.region + '?path='+path+'&depth='+depth+'&t='+(new Date()),
                onSuccess:function(response){
                    if(selNext &&
                        (selNext.get('tag')=='span'&& selNext.hasClass('x-region-child'))){
                        var e = selNext;
                    }else{
                        var e = new Element('span',{'class':'x-region-child'}).inject(sel_panel);
                    }
                    function timeTag(){
                        if(areaPanel.getElement('input')){
                            clearInterval(timeobj);
                            setHidden(sel);
                            if(response){
                                e.set('html',response);
                                if(hid){
                                   hid.retrieve('sel'+depth,function(){})();
                                   hid.retrieve('onsuc',function(){})();
                                }
                            }else{
                                sel.getAllNext().destroy();
                                setHidden(sel);
                                hid.retrieve('lastsel',function(){})(sel);
                            }
                        }else{
                            areaPanel.getElement('input');
                        }
                   }
                    var timeobj= timeTag.periodical(100);
                }
            }).get();

        }else{
            sel.getAllNext().destroy();
            setHidden(sel);

            if(!curOption.get('has_c')&&curOption.value!='_NULL_')
            hid.retrieve('lastsel',function(){})(sel);
        }
    }
}





(function(){

var disabled = 'disabled', ajaxName = '_ajax', attr = 'rel';

var Sync =this.Sync = new Class({
       Extends:Request.HTML,
       options:{
           syncCache:false,
           disabled:disabled,
           loadtip:'loading',
           tipCls:'-tip',
           ajaxTip:'ajax-tip',
           tipHidden:false, //'success'
           position:'before',
           evalScripts:true
       },
       initialize: function(target,options){
            this.sponsor = target;
           if(target)options = this._getOptions(target,options);
           this.parent(options);
       },
       _getOptions:function(target,options){
           try{var _options= JSON.decode(target.get('data-ajax-config'))||{};
           }catch(e){var _options= {};}

           var dataForm,opt, options = options || {},
               isSubmit= target.type ==='submit' ? true :false;

           if(isSubmit)dataForm =this.dataForm= target.getParent('form') || {};
           if(isSubmit)
               opt = {data:dataForm,url:dataForm.action,method:dataForm.method ||'post'};
           else
               opt = {url:target.get('href'),method:'get'};

           _options = Object.merge(opt,options,target.retrieve('_ajax_config',{}),_options);
           return _options;
       },
       _nearText : function(elem){
            var el =elem,node;
            while(elem){
                node = elem.firstChild;
                if(typeOf(node)==='whitespace')node = node.nextSibling;
                if(node && node.nodeType===3)return $(elem);
                elem = node;
            }
            return el;
       },
       _defaultState:function(){
           this.sponsor && this.sponsor.removeClass(this.options.disabled).retrieve('default:state',function(){})();
           return this;
       },
       onFailure: function(){
           this._defaultState().parent();
       },
       _validate:function(elem){
           var checkElems =elem.getElements('[vtype]');
           if(!!checkElems.length && !checkElems.every(validate)) return false;
           return true;
       },
       _getCache:function(sponsor) {
           return sponsor.retrieve('ajax:cache',false);
       },
       _clearCache:function(sponsor){
           sponsor.eliminate('ajax:cache');
       },
       _setCache: function(sponsor,value) {
           sponsor && sponsor.store('ajax:cache',value);
       },
       _progressCache:function(sponsor){
           var cache = this._getCache(sponsor);
           if(cache) return cache.success(cache.response.data) || true;
       },
       success:function(text,xml){
           this.response.data = text;
           if((/text\/jcmd/).test(this.getHeader('Content-type')))
           return this._jsonSuccess(text);

           if (['update','append','filter'].some(function(n){return this.options[n]},this))
           return this.parent(text,xml);

           this.onSuccess(this.processScripts(text), xml);
       },
       _jsonSuccess:function(text){
           try {var json = this.response.json = JSON.decode(text);
           } catch (e){var json = null;}
           this.onSuccess(json);
       },
       onSuccess:function(text){
           this._defaultState();
           if(this.response.json)this._progress(text);
           this._setCache(this.sponsor,this);
           this.parent(arguments);
       },
       _progress:function(cmd){
           if(!cmd)return;
           ['error','success'].each(function(v,k){
               var redirect = cmd['redirect'], m = cmd[v];
               if(!!k && m && redirect)location.href = redirect;
                   if (this.options.inject && m){
                   if(v!=this.options.tipHidden)return this._injectTip(v,m);
                   this._clearTip(v,m);
           }
           if(m) return Message(m,v);
           },this);
       },
       _clearTip:function(){
           if(!this.inject || !this.tipElem)return;
           this.tipElem.destroy();
       },
       _injectTip:function(cls,html){
           var options = this.options,inject = this.inject = document.id(options.inject),
               position = options.position ,ajaxTip = options.ajaxTip,
               tipCls  = options.tipCls,cls = cls + tipCls, tipBox;

               if(!inject)return;
           tipBox = inject.getParent();
               if(tipBox && (this.tipElem = tipBox.getElement('.'+ajaxTip)))
           return this.tipElem.set('html',html);
           new Element('div',{'class':cls+' '+ajaxTip}).set('html',html).inject(inject,position);
       },
       _request:function(sponsor){
           if(!sponsor)return this;
           sponsor.addClass(this.options.disabled);
           var obj = {'INPUT':'value','BUTTON':'text'}, key, btnText,btn;
           if(key = obj[sponsor.tagName]){
               btnText = sponsor.get(key);
               btn = this._nearText(sponsor).set(key,this.options.loadtip);
           }
           if(sponsor.retrieve('default:state')) return this;
           sponsor.store('default:state',function(){
               btn && btn.set(key,btnText);
           });
           return this;
       },
       _isCheck:function(elem,options){
           var options = options || {},
               dataElem = this.dataForm || options.data || this.options.data;

           if(typeOf(dataElem)==='element' && !this._validate(dataElem)) return false;
           return true;
       },
       send:function(options){
           var target = this.sponsor;
           if(target){
            if(target.hasClass(this.options.disabled)||!this._isCheck(target,options))return;
            if(this.options.syncCache && this._progressCache(target))return;
           }
           this._request(target).parent(options);
       }
});


var async =function(elem,event,_form){
       if(elem.hasClass(disabled)) return false;

       if(_form){
           if(!validate(_form)) {
               elem.removeClass(disabled);
               return false;
           }
           if(!elem.get('isDisabled'))
           return elem.addClass(disabled);
       }
       if(sync = elem.retrieve('ajax:cache',false))return sync.send();
       sync = new Sync(elem).send();
};


var Ex_Event_Group = this.Ex_Event_Group ={_request:{fn:async}};

var nearest = function(elem,type,value){
       var i = 3, el;
       for(;i;i--){
           if(!elem || elem.nodeType===9)return el;
           if(elem.type==='submit' || ($(elem).get && $(elem).get(type))) return elem;
           elem = elem.parentNode;
       }
       return el;
};

$(document.documentElement || document.body).addEvent('click',function(e){
       var target = $(e.target), elem;
       if((elem = nearest(target,attr))){
           if(elem.type==='submit' && elem.get(attr)!=='_request')return async(elem,e,elem.getParent('form'));

           var type = elem.get(attr), eventType = Ex_Event_Group[type];
           if(eventType){
               var fn= eventType['fn'], loader = eventType['loader'];
               e.preventDefault();
               if(loader){Ex_Loader(type,function(){fn && fn(elem,e);});}
               else {fn && fn(elem,e);}
           }
       }

});

})();

