$.extend(Function.prototype, {
    use: function() {
		var method = this, args = Array.prototype.slice.call(arguments), object = args.shift();
		return function() {
			return method.apply(object, args.concat(Array.prototype.slice.call(arguments)));
		}
    },
    useEL: function() {
        var method = this, args = Array.prototype.slice.call(arguments), object = args.shift();
        return function(event) {
            return method.apply(object, [event || window.event].concat(Array.prototype.slice.call(arguments)));
        }
    }
});

Rotator = function() {
	this.element = $(Rotator.element);
	
	// set the image src array and reverse it
	// the first image is already displayed, so slice it
	this.imagesSrc = [];
	var self = this;
	$(Rotator.element+' ul a').each(function() {
		self.imagesSrc.push({src: $(this).attr('rel'), link: $(this).attr('href')});
	});
	this.imagesSrc.reverse();
	this.imagesSrc[0].loaded = true;
	this.imagesSrc[0].el = $(Rotator.element+' a.image')[0];
	
	this.current = 0;
	this.next = 1;
	
	this.startTimer(Rotator.initDelay);
	this.preload(this.imagesSrc[this.next]);
};
$.extend(Rotator.prototype, {
	addImage: function(image) {
		var newImage = $('<a class="image" href="'+image.link+'"><img src="'+image.src+'" alt="" /></a>');
		this.element.prepend(newImage);
		this.imagesSrc[this.next].el = newImage;
	},
	advance: function(key) {
		$(this.imagesSrc[this.current].el).fadeOut(Rotator.speed);
		$(this.imagesSrc[this.next].el).fadeIn(Rotator.speed);
		
		if(key) {
			this.current = key;
		} else if(this.current == this.imagesSrc.length-1) {
			this.current = 0;
		} else {
			this.current++;
		}
		this.next = (this.current == this.imagesSrc.length-1) ? 0 : this.next+1;

		this.startTimer();
		if(this.imagesSrc[this.next]) {
			this.preload(this.imagesSrc[this.next])
		}
	},
	startTimer: function(delay) {
	    delay = (delay) ? delay : 0;
		this.timer = setTimeout(function() {
		    setTimeout(function() {
        		$(document).unbind('image:loaded');
        		var nextImage = this.imagesSrc[this.next];
        		if(nextImage) {
        			if(!nextImage.loaded) {
        				$(document).bind('image:loaded', function() { this.addImage(nextImage); }.use(this));
        			} else {
        				if(!nextImage.el) {
        					this.addImage(nextImage);
        				}
        				this.advance();
        			}
        		} else {
        			this.advance(0);
        		}
		    }.use(this), delay)
		}.use(this), Rotator.delay);
	},
	preload: function(img) {
		var image = new Image();
		image.onload = function() {
			img.loaded = true;
			$(document).trigger('image:loaded');
		};
		image.src = img.src;
	}
});
$.extend(Rotator, {
    initDelay: 10000,
	delay: 5000,
	speed: 1000,
	element: '#projectsRotator',
	init: function() {
		Rotator.instance = new Rotator();
	}
});


$(document).ready(Rotator.init);
