(function($) {

	// imageSwap7 jQuery object constructor
	$.fn.imageSwap7 = function(opts) {

		// get "real" options merging defaults and 
		// opts given by user
		var options = $.extend($.imageSwap7.defaults, opts);

		// Spawn a light7box for every element we are calling this on
		return this.each(function(){
			new $.imageSwap7(this, options)
		});

	}; // $.fn.imageSwap7()


 	// imageSwap7 constructor
	$.imageSwap7 = function (opts) {
		
		// Global options for this boxView, right into the object
		this.options = $.extend({}, $.imageSwap7.defaults, opts);
		this.init();

	}; // $.imageSwap7()


	$.imageSwap7.defaults = {

        // Swap the image every swapTime ms.. If the image is not ready yet,
        // retry after retryTime
        swapTime : 3000,
        retryTime : 250,

        // Duration (in ms) of all of the animations
        animationsLenght: 750,
		
		debug : 'false'

	};

	$.imageSwap7.prototype = {
		init : function() {
		    var self = this;
            
            self.log("# Called init");
            
            self.swapTimer = null;
            self.retryTimer = null;
            self.img = $(self.options.selector)[0];
            self.imgs = [];
            self.currentIndex = 0;
            self.n = self.options.images.length;

            for (var i = self.n-1; i >= 0; i--) {
                self.log("# Read image " + self.options.images[i]);
                self.imgs[i] = {img: new Image(), url: self.options.images[i], loaded: false, downloading: false, error: false};
            }

            // Start loading the first image
            self.loadImage(0);
            self.startSwapTimer();
	    },
	    
	    loadImage : function(index) {
	        var self = this,
	            obj = self.imgs[index],
	            url = obj.url;

            // Dont ever try to overwrite an onload even while the image
            // is already loading .... EVER!
            if (obj.downloading == true) {
                self.log("# Already downloading "+url+", let it alone! ");
                return;
            }

            obj.downloading = true;
	        
	        self.log("# LoadImage img "+index+" :: "+url);
	        
	        obj.img.onerror = function() {
				obj.img.onerror = null;
				obj.img.onload = null;
				obj.loaded = true;
				obj.downloading = false;
				obj.error = true;
				self.log("# Error loading the image "+obj.url);
                self.imageLoaded(index);
			};

            if (typeof obj.img.onload != "function") 
    			obj.img.onload = function() {
    				obj.img.onerror = null;
    				obj.img.onload = null;
    				obj.loaded = true;
    				obj.downloading = false;
    				self.log("# Here we are! Image "+url+" loaded!");
                    self.imageLoaded(index);
    			};

            // Finally set up the .src attr, so the download can begin
            obj.img.src = url;

            self.log("# LoadImage done: waiting for "+url+" to get here.")
	        
	    },

        imageLoaded : function (index) {
            var self = this;

            // Loaded an image, we load the next one
            for (var i=0; i<self.n; i++) 
                if (self.imgs[i].loaded == false) {
                    self.loadImage(i);
                    return;
                }
            
            self.log("# ImageLoaded: seems there's nothing to load.");

        },
	    
	    startSwapTimer : function () {
	        var self = this;
	        if (self.swapTimer) clearTimeout(self.swapTimer);
            self.swapTimer = setTimeout(function() { self.swapImage (); }, self.options.swapTime);
	    },
	    
	    swapImage : function () {
	        var self = this,
	            newImg = self.imgs[self.currentIndex];
	        
	        self.log("# SwapImage to index "+self.currentIndex);
	        
	        if (newImg.loading == false) {
	            self.loadImage(self.currentIndex);
	            return;
	        }

            // Image error? Try the next
            if (newImg.error == true) {
                self.log("# Error with image "+newImg.url+", trying the next one.");
    	        self.currentIndex = (self.currentIndex < self.n-1) ? self.currentIndex+1 : 0;
                self.swapImage();
                return;
            }
	        
	        // Image not loaded yet?? Slow connection? Retry soon
	        if (newImg.loaded == false) {
	            self.startRetryTimer();
	            return;
	        }
	        
	        self.log("# Swapping "+self.img.src+" with "+newImg.img.src);

            $(self.img).fadeOut(self.options.animationsLength, function() {
    	        self.img.src = newImg.img.src;
            }).fadeIn(self.options.animationsLength);
	        
	        self.currentIndex = (self.currentIndex < self.n-1) ? self.currentIndex+1 : 0;
	            
	        self.startSwapTimer();
	    },
	    
	    startRetryTimer : function () {
	        var self = this;
	        self.log("# Starting retry timer .. ");
	        if (self.retryTimer) clearTimeout(self.retryTimer);
            self.retryTimer = setTimeout(function() { self.swapImage(); }, self.options.retryTime);
	    },

	    log : function(w) {
	        if (this.options.debug == "false")
                return;

            if (typeof console == "undefined") {
                if ($("#debug_foo").attr('id') == null) 
                    $("body").append("<div id='debug_foo' style='position: absolute; right:2px; bottom: 2px; border: 1px solid red; font-size: 1.1em;'></div>");
                $("#debug_foo").append("<div>"+w+"</div>");
            } else {
                console.log(w);
            }
	    } // log()
    }; // prototype

})(jQuery)
