
var ImageRotator = function(){ this.init.apply(this, arguments); }
ImageRotator.prototype = {
    index : 0,
    timer : null,

    defaults: {
        autostart: true,
        start: 0,
        interval : 4000,
        nextButton: 'a.next-img',
        prevButton: 'a.prev-img',
        fadeSpeed: 1100
    },

    init: function(container, images, o) {
        if( images.length < 2 ) return;
        var self = this;
        self.container = container;
        self.images = images;
        self.o = $.extend(self.defaults, o);
        self.index = self.o.start || 0;

        $('<img src="'+self.images[self.index]+'" />').appendTo(self.container)
            .css({
                position: 'absolute',
                display: 'block',
                zIndex: '10'
            });
        
        $(self.o.nextButton).click(function() {
            self.stop();
            self.next();
            return false;
        });
        $(self.o.prevButton).click(function() {
            self.stop();
            self.prev();
            return false;
        });

        self.preloads = [];
        $.each(self.images, function(n, im) {
            if (n <= 1) {
                self.preloads[n] = new Image();
                self.preloads[n].src = self.images[n];
            } else if (n == self.images.length -1) {
                self.preloads[n] = new Image();
                self.preloads[n].src = self.images[n];
            }
            else {
                self.preloads[n] = null;
            }
        });
        
        $(window).load(function() {
            if (self.o.autostart) self.start();
        });
    },

    start: function() {
        var self = this;
        self.playing = true;
        self.timer = setTimeout( function(){self.next()}, self.o.interval);
    },

    next: function() {
        var self = this;
        self.rotate(1);
    },

    prev: function() {
        var self = this;
        self.rotate(-1);
    },

    stop: function() {
        var self = this;
        self.playing = false;
        clearTimeout(self.timer);
    },

    toggle: function() {
        var self = this;
        if( self.playing )
            self.stop();
        else 
            self.start();
    },
    
    rotate: function(c) {
        var self = this;
        var c = (c ? c : 1);
        var next = ((self.index+c) + self.images.length)% self.images.length;
        self.load(next);
    },

    load: function(i) {
        var self = this;

        var $img = $(self.container).find('> img:first-child');
        var src = $img.attr('src');
        
        // Next image source
        self.index = i; 
        
        // Clear out running animations before proceding
        $img.parent().find('img').not(':first-child').each(function() {
            $(this).stop().remove();
        });

        // Clone new image and set z-index so the clone is underneath the current image.
        var newsrc = self.images[self.index];
        var zindex = parseInt($img.css('z-index') || 10);
        var $newimg = $img.clone().attr('src', '').appendTo(self.container).css({opacity: 1});
        $img.css('z-index', zindex+1);

        $(self.container).trigger('rotator-load', [self.index]);

        // Apply transition effect after new image loads.
        $newimg.one('load', function() {
            $newimg.attr('src', this.src);
            $img.animate({
                opacity: 0
            }, self.o.fadeSpeed, function() {
                $img.hide();
                $img.remove();
                if( self.playing ) self.timer = setTimeout( function(){self.next()}, self.o.interval);
            });
            return;
        });
        $newimg.attr('src', newsrc);

        // Preload next one
        nextindex = ((self.index+1) % self.images.length);
        if (!self.preloads[nextindex]) {
            var nextsrc = self.images[nextindex];
            self.preloads[nextindex] = new Image();
            self.preloads[nextindex].src = nextsrc;
        }
    }
}

jQuery.fn.imageRotator = function(images, opts) {
    return this.each(function() {
        var i = new ImageRotator(this, images, opts);
        jQuery(this).data('image-rotator', i);
    });
}


