/*
 * jquery.bannerFader.js (version 1.0)
 *
 * HTML:
 * <div id="banner"></div>
 *
 * CSS:
 * #banner { width: 800px; height: 300px; }
 *
 * JavaScript:
 * var options {};
 * $('#banner').bannerFader(options);
 *
 * I made this. (SmallSharpTools.com - 2009)
 *
 * License: Creative Commons
 *
 */

(function($) {

    $.fn.bannerFader = function(options) {

        var opts = $.extend({}, $.fn.bannerFader.defaults, options);
        
        var items = [];
        if (opts.items && $.isArray(opts.items) && opts.items.length > 0) {
            var now = new Date();
            for (var i=0;i<opts.items.length;i++) {
                var item = opts.items[i];
                if (item.start && item.end) {
                    var start = new Date(Date.parse(item.start));
                    var end = new Date(Date.parse(item.end));
                    if (start < now && end > now) {
                        items[items.length] = item;
                    }
                }
                else {
                    items[items.length] = item;
                }
            }
        }
        
        return this.each(function() {
            var context = $(this);
            var position = 0;
            var isMoving = false;
            var timeout;
    
            var getMax = function() {
                var result = 0;
                if (items.length > 0) {
                    result = items.length - 1;
                }
                // only allow up to 4 items max
                if (result > opts.maxItems - 1) {
                    result = opts.maxItems - 1;
                }
                // memoize for performance
                getMax = function() { return result; };
                return result;
            };
            
            var changePosition = function(nextPosition) {
                if (isMoving) { return; }
                
                var lastPosition = position;
                position = nextPosition;
                
                if (lastPosition === nextPosition) {
                    return;
                }

                isMoving = true;
                
                // prepare for the move (z-index, opacity, visibility)
                if (lastPosition !== position) {
                    $('.item', context).eq(lastPosition).css('z-index', opts.lowZindex);
                }
                $('.item', context).eq(position).css('z-index', opts.highZindex).hide();

                // execute the move animation
                $('.item', context).eq(position).fadeIn(opts.fadeDelay, function() {

                    // move automatically to the next position
                    clearTimeout(timeout);
                    timeout = setTimeout(function() {
                        move(1);
                    }, opts.transitionDelay);
                    
                    // update the tabs
                    $('.tab', context).removeClass('tabOn').eq(position).addClass('tabOn');

                    // ready for move again
                    isMoving = false;
                    
                    setTimeout(function() {
                    
                        // show the call to action (cta)
                        $('.item .cta', context).eq(position).
                            hide().fadeTo(0, 0).show().
                            fadeTo(opts.fadeDelay, 0.85, function() {
                            
                            // hide the last item
                            if (lastPosition !== nextPosition) {
                                $('.item', context).eq(lastPosition).hide();
                                $('.item .cta', context).eq(lastPosition).hide();
                            }
                        });
                    
                    }, 250);
                });
                
            };

            var move = function(i) {
                var nextPosition = position + i;
                if (nextPosition < 0) {
                    nextPosition = getMax();
                }
                if (nextPosition > getMax()) {
                    nextPosition = 0;
                }

                changePosition(nextPosition);
            };

            var arrowHoverOn = function() {
                $(this).fadeTo(100, 0.66);
            };

            var arrowHoverOff = function() {
                var arrow = this;
                setTimeout(function(){
                    $(arrow).fadeTo(100, 0.33);
                }, 100);
            };

            if (getMax() > 0) {
                var sb = new core.sb();
                sb.append('<div class="arrow_left"></div>');
                sb.append('<div class="arrow_right"></div>');
                
                for (i=0;i<=getMax();i++){
                    //console.log(items[i]);
                    var bg = items[i].bg;
                    var cta = items[i].cta;
                    var link = items[i].link;
                    
                    sb.append('<div class="item" style="background-image: url(');
                    sb.append(bg);
                    sb.append(');">');
                    sb.append('<div class="cta"><a href="');
                    sb.append(link);
                    sb.append('" target="_top" style="background-image: url(');
                    sb.append(cta);
                    sb.append(');">&nbsp;</a></div>');
                    sb.append('</div>');
                }
                
                sb.append('<div class="tabs">');
                for (i=0;i<=getMax();i++){
                    sb.append('<a class="tab"><span>');
                    sb.append(i);
                    sb.append('</span></a>');
                }
                sb.append('</div>');
                
                $(this).html(sb.toString());
                
                // attach behavior
                $('.arrow_left', context).
                    css('z-index', opts.arrowsZindex).
                    fadeTo(0, 0.33).
                    hover(arrowHoverOn, arrowHoverOff).
                    click(function() { move(-1); });
                $('.arrow_right', context).
                    css('z-index', opts.arrowsZindex).
                    fadeTo(0, 0.33).
                    hover(arrowHoverOn, arrowHoverOff).
                    click(function() { move(1); });

                $('.tab:first', context).addClass('tabOn');
                
                // position tabs
                var cWidth = $(context).width();
                var tWidth = $('.tabs', context).width();
                $('.tabs', context).css('left', (cWidth / 2) - (tWidth / 2));
                
                for (i=0;i<=getMax();i++) {
                    var click = function() {
                        var j = i;
                        return function() {
                            changePosition(j);
                        };
                    }();
                    $('.tab', context).eq(i).click(click);
                }
                position = items.length;
                move(1);
            }
        });

    };

    // publicly accessible defaults
    $.fn.bannerFader.defaults = {
        fadeDelay: 750,
        transitionDelay: 6000,
        lowZindex: 10,
        highZindex: 20,
        arrowsZindex: 50,
        tabsZindex: 45,
        maxItems: 10,
        items: {}
    };

    /* imported core features */
    
    var core = {};

    (function() {
        $sb = function(text) {
          this.buffer = [];
          if (text !== null)
          {
            this.append(text);
          }
        };
        
        $sb.prototype.append = function(text) {
          this.buffer[this.buffer.length] = text;
          return this;
        };
        
        $sb.prototype.clear = function() {
          this.buffer = [];
        };
        
        $sb.prototype.toString = function() {
          return this.buffer.join('');
        };
        
        // export function
        core.sb = $sb;
    }());

})(jQuery);
