

var OnceLater = new Class({
    
	Implements: [Options] ,
    
	options: {
        delay: 200 ,
        cover: false ,
        bind: null 
    } ,
    
    iTimer: null ,
    
	initialize: function(options) {
        this.setOptions(options);
    } ,
    
    call : function(fn, args , bind ) {
        if(  !this.iTimer || this.options.cover ) {
            clearTimeout( this.iTimer) ;
            var _this   = this ;
            this.iTimer = setTimeout(function(){
                _this.iTimer    = null ;
                fn.apply(bind || _this.options.bind ,  args ) ;
            }, this.options.delay) ;
            return true ;
        }
        return false ;
    } ,
    
    clear: function(){
        if( this.iTimer ) {
            clearTimeout( this.iTimer ) ;
            this.iTimer = null ;
        }
    }
});

OnceLater.call  = (function(){
    var timer_pool  = {} ;
    return function(tag, fn , options ) {
        if( !options || typeof options != 'object' ) options = {} ;
        Object.merge(options, OnceLater.prototype.options, options);
        if( timer_pool[tag] ||  options.cover ) {
           timer_pool[tag] = setTimeout(function(){
                timer_pool[tag]    = null ;
                fn();
            }, options.delay) ;
        }
    }
})();

var MyValidator = new Class({

	Extends: Form.Validator,

	options: {
		scrollToErrorsOnSubmit: true,
		scrollToErrorsOnBlur: true,
		scrollToErrorsOnChange: false,
        stopOnFailure: false ,
        xhr: true ,
        forceInput: false ,
		scrollFxOptions: {
			transition: 'quad:out',
			offset: {
                x: -160,
				y: -20
			}
		},
        onSubmit: function(evt){} ,
        tip: {
            mix_length : 54 ,
            offset: {
				x: -92 ,
				y: 6
			}
        }
	},
    
    onTip : null ,
    
	initialize: function(form, options) { 
        this.tips   =  {} ;
		this.parent(form, options);
            
        this.onTip    = new OnceLater({
                delay: 100 ,
                cover: false ,
                bind: this 
            }) ;
            
        var _this   = this ;
            
		this.addEvent('onElementValidate',  function( isValid, field, className, warn){
            var validator = this.getValidator(className);
            var err_msg = validator.getError(field) ;
            var tip  = this.getTip( field, className );
        
            if (warn) {
                field.addClass('warning');
                tip.element.addClass('warning');
            } else {
                field.removeClass('warning');
                tip.element.removeClass('warning');
            }
            
            if (  !isValid && err_msg ){
                tip.msgs[className] = err_msg; 
            } else {
                tip.msgs[className] = null ; 
            }
            // console.log(tip.name , this.hasValidator(field, 'ignoreValidation'), sValid, tip.msgs);
            var _msg    = null ;
            for(var i in tip.msgs) if( tip.msgs.hasOwnProperty(i) && tip.msgs[i] ) _msg = tip.msgs[i] ;
            
            if(  _msg ) {
                tip.show(_msg) ;
                if( this.onTip.call(function(){
                    if( this.forceInput ) {
                      field.focus() ;
                    }
                    tip.js_focus    = false ;
                    tip.scroll.toElement(field);
                }) ) {
                    tip.js_focus    = true ;
                }
            } else {
                tip.hide() ;
            }
        });
        
        
        if(  !(options.onError instanceof Function) ) {
            options.onError = function( text ){
                alert( text ) ; 
            }
        }
        
        if( this.options.xhr  ) {
            if( typeof this.options.xhr != 'object' ) {
                this.options.xhr    = {
                    
                } ;
            }
            if( !(this.options.xhr.url instanceof String) ) {
                this.options.xhr.url =  this.element.getAttribute('action') ;
            }
            
            this.mask    = new Mask(document.body, {
                'class' : 'form_xhr_mask' ,
                style:{
                    'background-color' : '#aaa',
                    'opacity': 0.6
                }
            }) ;
            
            if( !this.options.xhr.url || this.options.xhr.url.trim()== '' ) {
                this.options.xhr.url = String(window.location) ;
            }
            
            this.request    = new Request(  this.options.xhr) ;
            
            this.request.addEvent('request', function(xhr) {
                _this.mask.show();
            });
            
            this.request.addEvent('complete', function(xhr) {
                _this.mask.hide();
                var  o = null ;
                try{
                    o = JSON.decode( this.response.text );
                }catch(e){}
                if( !o ) {
                    options.onError.call( _this, this.response.text ) ;
                } else {
                    if( options.onComplete instanceof Function ) {
                        options.onComplete.call( _this, o ) ;
                    } else {
                        options.onError.call( _this, this.response.text ) ;
                    }
                }
            });
        } else {
            this.request    = null ;
        }
        
        this.addEvent('onFormValidate', function(valid, form, evt){
                evt.stop();
                if ( evt && valid  ) { // && _this.options.stopOnFailure 
                    if( options.onSubmit  instanceof Function){
                        options.onSubmit.call(this, evt);
                    } else if( this.request ) {
                        evt.stop() ;
                        var str = this.element.toQueryString().trim() ,
                            data = Object.toQueryString(this.options.xhr.extraData) ;

                        if (str) str += "&" + data;
                        else str = data;
                        
                        this.request.send({
                            data: str + '&ajax_call=1'
                        });
                    }
                }
        } ) ;
        
	} ,
    
    iTimer : null ,
    
    getTip:function(field, className) {
        var uid = Slick.uidOf(field);
        if(  !this.tips.hasOwnProperty(uid) ) {
            var tip =  {
                element : new Element('div', {
                    'class': 'validator-tip display_none'
                })  ,
                display: false ,
                iTimer: null ,
                js_focus: false ,
                name: field.getAttribute('name') ,
                uid: uid ,
                parent: document.body ,
                msgs : {}
            } ;
            
            
            var par = document.id(field).getParent() ;
            while (par != document.body && par.getScrollSize().y == par.getSize().y){
                par = par.getParent();
            }
            tip.scroll = new Fx.Scroll(par, this.options.scrollFxOptions);
        
            tip.fx  = new Fx.Morph( tip.element , {
                duration: 200 ,
                // transition: Fx.Transitions.Sine.easeOut ,
                onComplete: function(){
                    if( !tip.display ) {
                        tip.element.addClass('display_none');
                        tip.element.set('text', '');
                    }
                }
            }) ;
            
            tip.setPosition    = function(){
                    var pos = field.getCoordinates();
                    var _pos   = document.id(tip.parent).getCoordinates();
                    tip.element.setStyles({
                        'left' : (pos.left + _this.options.tip.offset.x - _pos.left ),
                        'top': (pos.top + pos.height + _this.options.tip.offset.y - _pos.top  ) 
                    }); 
            }
            
            var _this   = this ;
            tip.show    = function(_msg){
                tip.display = true ;
                
                if( tip.iTimer ) {
                    clearTimeout( tip.iTimer ) ;
                    tip.fx.cancel();
                }
                
                tip.iTimer  = setTimeout( function() {
                   //  console.log('show');
                    tip.iTimer  = null ;
                    if( tip.element.hasClass('display_none') ) {
                        tip.setPosition() ;
                        tip.element.removeClass('display_none');
                        
                        for(var i = _this.options.tip.mix_length -_msg.length ; i > 0; i--) {
                            _msg = '&nbsp;' + _msg ;
                        }
                        tip.element.set('html', _msg );
                        tip.fx.start({
                            'opacity': [ 0.1, 0.9] 
                        });
                    }
                    field.highlight() ;
                    
                }, 200 ) ;
            };
            
            tip.hide    = function() {
                // console.log('hide');
                tip.display = false ;
                if( tip.iTimer ) {
                    clearTimeout( tip.iTimer ) ;
                    tip.fx.cancel();
                }
                tip.iTimer  = setTimeout( function() {
                    if( !tip.element.hasClass('display_none') ) {
                        tip.fx.start({
                            'opacity': [ 0.9, 0.1 ] 
                        });
                    }
                }, 200 );
            };
            
            field.addEvent('focus', function(){
                if( ! tip.js_focus  ) {
                    tip.hide() ;
                }
            });
            for(var par =  document.id(field).getParent() ; par && par != document.body; par = par.getParent() ) {
                if( (par.getStyle('position') == 'relative' || par.getStyle('position')  == 'absolute') && String(par.getStyle('left')) !='' ){
                    tip.parent = par ;
                    break ;
                }
            }
            document.id(tip.parent).adopt( tip.element );
            this.tips[uid]     =tip ;
        } else {
            tip =   this.tips[uid]  ;
        }
        return tip ;
    }
    
});

var Rotator = new Class({
        
	Implements: [Options] ,
    
	options: {
        children_path : 'a' ,
        delay: 4444 ,
        fx: {
            duration: 666 
        } ,
        bullet : {
            width: 14 ,
            height: 12 ,
            top : -8
        }
    } ,
    
    iTimer: null ,
    index: 0 ,
    container : null ,
    force_rotate: false ,
    on_rotate: false ,
    
	initialize: function(element, options) {
        this.container  = document.id(element);
        this.setOptions(options);
        this.children   =  this.container.getElements(this.options. children_path);
        this.buildBullets();
        this.setStyle() ;
        if(  this.children.length <= 1 ) {
            return ;
        }
        this.rotate() ;
    } ,
    
    
    buildBullets: function() {
	    this.container.setStyle('display', 'block');
        var height  = this.options.bullet.height ;
        var width   = this.options.bullet.width *  this.children.length ;
        var top     =  this.container.getHeight() - height + this.options.bullet.top ;
        var left    = 0 - ( width / 2 ) ;
        var styles  = {
                'position': 'absolute' ,
                'top': top ,
                'height' : height ,
                'width': width ,
                'font-size': ( this.options.bullet.height - 2) ,
                'line-height': ( this.options.bullet.height - 2) ,
                'z-index': 9999 ,
                'margin-left': left , 
                'left': '50%'
            } ;
         /*
            var mask    = new Element('div', {
                'class': 'rotator-bullets-mask' ,
                'styles': styles 
            })  ;
            mask.setStyles({
                'background': '#fff' ,
                'opacity': 0.2
            });
            this.container.adopt( mask ) ;
            */
        this.bullets    = new Element('div', {
            'class': 'rotator-bullets' ,
            'styles': styles 
        });
        
        this.children.each(function(el, i) {
            
            el.setStyle('display', 'none') ;
            
            var bu  = new Element('a', {
                'href': 'javascript:void(0)' ,
                'class': 'rotator-bullet' ,
                'styles' : {
                    'text-decoration': 'none' ,
                    'display': 'block' ,
                    'width': this.options.bullet.width ,
                    'font-size': ( this.options.bullet.height - 2) ,
                    'line-height': ( this.options.bullet.height - 2) ,
                    'height': this.options.bullet.height ,
                    'float': 'left',
                    'margin': 0 ,
                    'padding': 0 ,
                    'position': 'relative' , 'top': 0 , 'left': 0 ,
                    'background-image': 'url(/sliderimg/bullets.png)' ,
                    'background-repeat': 'no-repeat' ,
                    'background-position': '50% 0px' 
                }
            });
            
            var fx = null ;
            var _this   = this ;
            var fx_options    = {
                onComplete: function() {
                    _this.on_rotate = false ;
                    // console.log('onComplete', _this.index  , i );
                    if( _this.index  == i ) {
                       // console.log('complate', i, _this.on_rotate );
                        if( !_this.force_rotate ) {
                            _this.rotate() ;
                        }
                    } else {
                        el.setStyle('display', 'none') ;
                    }
                }
            } ;
            Object.merge(fx_options, this.options.fx );
            fx = new Fx.Morph(el,  fx_options) ;
        
            bu.addEvents({
                'click': function(evt){
                    _this.rotate(i) ;
                }
            });
            el.addEvents({
                'fadeIn':function() {
                    _this.on_rotate = true ;
                    fx.cancel();
                    el.setStyle('display', 'block') ;
                    fx.start({
                        opacity:[ 0, 1]
                    });
                    bu.addClass('rotator-bullet-over') ;
                    bu.setStyle( 'background-position',  '50% -12px' );
                    _this.index = i ;
                } ,
                'fadeOut': function() {
                    _this.on_rotate = true ;
                    fx.cancel();
                    fx.start({
                        opacity:[ 1, 0 ]
                    });
                    bu.removeClass('rotator-bullet-over') ;
                    bu.setStyle( 'background-position',  '50% 0px' );
                }
            }) ;
            
            this.bullets.adopt(bu) ;
        }, this) ;
        this.container.adopt( this.bullets ) ;
    } ,
    
    rotate : function( _index ) {
        //  console.log('rotate', this.on_rotate , _index);
        
        if( this.on_rotate ) {
            return ;
        }
        
        if( typeof _index != 'undefined'  ) {
            var now = this.index ;
            var next    = _index ;
            this.children[now].fireEvent('fadeOut') ;
            this.children[next].fireEvent('fadeIn') ;
            this.force_rotate = true ;
        }

        if( this.iTimer ) {
            clearTimeout(this.iTimer) ;
        }
        
        var _this   = this ;
        this.iTimer = setTimeout(function(){
            this.iTimer = null ;
            var now = _this.index ;
            var next    = now + 1 ;
            if( next >= _this.children.length ) {
                next    = 0 ;
            }
            _this.force_rotate  = false ;
            _this.children[now].fireEvent('fadeOut') ;
            _this.children[next].fireEvent('fadeIn') ;
        },  this.options.delay  ) ;
    } ,
    
    setStyle: function(){
        var height =   this.container .getHeight() ;
         this.container.setStyles({
            'position': 'relative' ,
            'top': 0 ,
            'left': 0
        }) ;
        this.children.setStyles({
            'opacity':0,
	        'display':'none' ,
            'position': 'absolute' 
        }) ;
        this.children[0].fireEvent('fadeIn');
    }
    
});


