(function(document) {
	
	window.Transitions = window.Transitions || function() {
		//Silence...
	};
	
	Transitions.prototype.transition_to_background_color = function(el, color) {
	    $(el).animate({backgroundColor: color}, {queue: false});
	};
	
	Transitions.prototype.transition_to_opacity = function(el, opacity) {
	    $(el).animate({opacity: opacity}, {queue: false});
	};
	
})(document);


(function(document) {
	
	window.Cycle = window.Cycle || function(targets) {
		//Check that our target is an instance of jQuery.
		if (!(targets instanceof jQuery))
		    throw 'The target at index: '+ i +' is not a jQuery object.';
		else
		    targets = targets.toArray();
		
		//Check that our target is now a native JS array.
		if (typeof targets !== 'object' && !(targets instanceof Array))
		    throw 'The target is not an array. Target must be an array of elements.';
		
		//Finally make sure targets isn't empty.
		if (targets.length == 0)
		    throw 'Targets empty, aborting...';
		
		//Whew, okay now move onto the fun stuff.
		//If we got ot this point then we should have a normalized javascript array to work with.
		var that = this;
		
		if (typeof arguments[1] != 'undefined' && typeof arguments[1] == 'object')
		    var options = arguments[1];
		
		this.duration = options.duration;
		this.speed = options.speed;
		this.animation = function(element, nextElement, direction, callback) {
		    $(element).fadeOut(that.speed, function() {
		    	$(nextElement).fadeIn(that.speed, function() {
		    		callback.call();
		    	});
		    });
		};
		
		this.targets = targets;
		this.queue = Array();
		this.inAnimation = false;
		this.timeOut = null;
		this.visibleElement = 0;
		
		this.loop();
	};
	
	Cycle.prototype.loop = function() {
	    var that = this;
	    this.timeOut = setTimeout(function() {
	    	that.next();
	    }, this.duration);
	};
	
	Cycle.prototype.animator = function () {
	    //Pause the loop while we animate!
	    clearTimeout(this.timeOut);
	    var that = this;
	    
	    function run() {
	    	var element = $(that.targets[that.queue[0][0]]);
	    	var nextElement = $(that.targets[that.queue[0][1]]);
	    	var direction = that.queue[0][2];
	    	
	    	that.animation(element, nextElement, direction, complete);
	    }
	    
	    function complete() {
	    	that.visibleElement = that.queue[0][1]; //The visible element is now the "next" element.
	    	that.queue.shift(); //Now that we are done with this element, we can shift it off of the top of the stack.
	    	
	    	if (that.queue.length > 0) {
	    		run();
	    		return;
	    	}
	    	
	    	that.inAnimation = false; //No longer animating, lets switch the flag and fire up the loop.
	    	that.loop();
	    }
	    
	    if (this.inAnimation == false) {
	    	this.inAnimation = true;
	    	run();
	    }
	};
	
	Cycle.prototype.next = function() {
	    if (this.queue.length == 0)
	    	var active = this.visibleElement;
	    else
	    	var active = this.queue[this.queue.length-1][1]; //Active should be the last item's index 1, which is the "next element".
	    
	    var next = 0;
	    if (active < this.targets.length - 1)
	    	next = active + 1;
	    else
	    	next = 0;
	    
	    //Push the active element, next element, and direction into the queue.
	    this.queue.push(Array(active, next, 1)); //1 is indicating that the direction is "next".
	    
	    this.animator();
	};
	
	Cycle.prototype.previous = function() {
	    if (this.queue.length == 0)
	    	var active = this.visibleElement;
	    else
	    	var active = this.queue[this.queue.length-1][1]; //Active should be the last item's index 1, which is the "next element".
	    
	    var next = 0;
	    if (active == 0)
	    	next = this.targets.length - 1;
	    else
	    	next = active - 1;
	    
	    //Push the active element, next element, and direction into the queue.
	    this.queue.push(Array(active, next, 0)); //0 is indicating that the direction is "previous".
	    
	    this.animator();
	};
	
	Cycle.prototype.goto = function(id) {
	    if (this.queue.length == 0)
	    	var active = this.visibleElement;
	    else
	    	var active = this.queue[this.queue.length-1][1];
	    
	    var next = 0;
	    for (var i = 0; i < this.targets.length; i++) {
	    	position = i;
	    	if (this.targets[i].id == id)
	    		break;
	    }
	    
	    //Push the active element, next element, and direction into the queue.
	    this.queue.push(Array(active, position, 1)); //1 is indicating that the direction is "next".
	    
	    this.animator();
	};
	
})(document);
