/*
 * theTeam UI YACarousel 0.1
 *
 * Copyright (c) 2010 theTeam (http://www.theteam.co.uk/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 *
 * Depends:
 *    ui.core.js
 */
if(typeof console == 'undefined') window.console = {log:function(){}};
(function($) {
    var ttYACarouselClasses =
        'tt-yacarousel ' +
        'ui-widget';
    $.widget("tt.yacarousel", {
    
        $slides : null,
        
        $controls_area : null,
        $selectors : null,
        $left_arrow : null,
        $right_arrow : null,
        $old_slide : null,
        $new_slide : null,
        
        old_slide_index : null,
        new_slide_index : null,
        timer : 0,
        
    _init: function() {
            var o = this.options, self = this;
                
            // save a reference to the slides elements
            this.$slides = this.element.find( o.slides ).addClass('tt-yacarousel-slide').css({'width':o.width, 'height':o.height});
                
            // add our specific classes and style
            this.element.addClass(ttYACarouselClasses).css({'width':o.width, 'height':o.height});
            // create the controls area
            var controls_area_html = '<div class="tt-yacarousel-controls">';
            if(o.arrows) controls_area_html += '<a class="tt-yacarousel-left-arrow" href="#">&#60;</a>';
            controls_area_html += '<ul class="tt-yacarousel-selectors">';
            this.$slides.each(function(index){
                ++index;
                controls_area_html += '<li><a href="javascript:;">' + index + '</a></li>';
            });
            controls_area_html += '</ul>';
            if(o.arrows) controls_area_html += '<a class="tt-yacarousel-right-arrow" href="#">&#62;</a>';
            controls_area_html += '</div>';
            
            // generate the DOM and inject it in the carousel
            this.$controls_area = $(controls_area_html).appendTo(this.element);
            this.$controls_area.width(o.width);
            // attach events to the selectors
            this.$selectors = this.element.find("ul.tt-yacarousel-selectors a");
            if(o.arrows){
                this.$right_arrow = this.$controls_area.find("a.tt-yacarousel-right-arrow");
                this.$left_arrow = this.$controls_area.find("a.tt-yacarousel-left-arrow");
                this.$right_arrow.click(function(){
                    console.log("right arrow click");
                    self.next();
                });
                this.$left_arrow.click(function(){
                    console.log("left arrow click");
                    self.previous();
                });
                
            }
            // click
            this.$selectors.click(function(){
                index = self.$selectors.index(this);
                self.activate(index, 'selector');
            });
            // the extender could need some init code
            this._trigger('init', 0, {slides: this.$slides, controls: this.$controls_area});
            this.activate(0,'init');
    },

        complete : function(){
            console.log("complete " + this.old_slide_index + " " + this.new_slide_index);
            // set the active slide
            this.$slides.removeClass('tt-yacarousel-slide-active');
            if(this.$new_slide !== null) this.$new_slide.addClass('tt-yacarousel-slide-active');
            // reset the timer
            this._setTimer();
        },

        activate : function(index, type){
            var o = this.options, self = this;
            // complete the previous activation
            this.complete();
            // set new slide / old slide variables
            this.$old_slide = this.$new_slide || $();
            this.old_slide_index = this.$slides.index(this.$old_slide);
            this.$new_slide = $(this.$slides[index]);
            this.new_slide_index = index;
            
            if(this.$old_slide[0] == this.$new_slide[0]) return this;
            
            // set the active selector
            this.$selectors.parent().removeClass('tt-active');
            $(this.$selectors[index]).parent().addClass('tt-active');
            this._trigger('activate',0,{
                'new_slide' : this.$new_slide,
                'new_index' : this.new_slide_index,
                'old_slide' : this.$old_slide,
                'old_index' : this.old_slide_index,
                'slides' : this.$slides,
                'type' : type
            });
            return this;
        },

        index : function(){
            return this.new_slide_index;
        },

        cycle : function(){
            var index = this.index();
            var next_index = this.options.next_index(index, this.$slides.length);
            this.activate( next_index, 'cycle' );
        },

        next : function(){
            var index = this.index();
            console.log('next ' + index);
            var next_index = this.options.next_index(index, this.$slides.length);
            this.activate( next_index, 'next' );
        },
        
        previous : function(){
            var index = this.index();
            var previous_index = this.options.previous_index(index, this.$slides.length);
            this.activate( previous_index, 'previous' );
        },

        _setTimer : function(){
            // prepare the timer for the automatic cycling
            clearTimeout(this.timer);
            this.timer = setTimeout($.proxy(this.cycle, this), this.options.interval);
        },
        
        destroy: function(){
            // avoid recursion problems
            if(this.destroying) return;
            this.destroying = true;
            this.element.removeClass(ttYACarouselClasses);
            this.$selectors.remove();
            
            // unbind the widget to the DOM element
            $.widget.prototype.destroy.apply(this, arguments);
        }
    });
    

    $.extend($.tt.yacarousel, {
    version: "0.1",
    defaults: {
            slides: "> li",
            interval: 3000,
            width: 700,
            height: 300,
            arrows: true,
            
            init: function(event, options){
                options.slides.css({display:'block', 'opacity': 0});
            },

            activate: function(event, options){
                var self = $(this);
                var fade_events = {
                    fadeOut: function(slide, callback){
                        if(slide.length < 1) return callback();
                        console.log('fadeOut');
                        slide.stop().animate({opacity:0},{
                            queue : false,
                            duration : 500,
                            complete : callback
                        });
                        return false;
                    },
                    fadeIn: function(slide, callback){
                        if(slide.length < 1) return callback();
                        console.log('fadeIn');
                        slide.stop().animate({opacity:1},{
                            queue : false,
                            duration : 500,
                            complete : callback
                        });
                        return false;
                    }
                };
                // stops all other animations, and bring them to the end
                options.slides.stop(true, true);
                
                fade_events.fadeOut(options.old_slide, function(){
                    fade_events.fadeIn(options.new_slide, function(){
                        // at the end of the activation we need to call "complete"
                        self.yacarousel("complete");
                    });
                });
            },

            
            /* helpers to calculate the index  */
            next_index : function(current_index, slides_count){
                return (current_index + 1)  % slides_count;
            },
            
            previous_index : function(current_index, slides_count){
                return (current_index - 1) < 0 ? (slides_count - 1) : (current_index - 1);
            }
    }
    });

})(jQuery);
