var Marquee = (function() {
	function bindControls(controls) {
		var self = this;
		controls.click(function(e) {
			var target = $(e.target);
			if(target[0].nodeName == 'LI') {
				self.rotate(target.index());
			}
			return false;
		});
	}
	
	function bindPlayPause(playPause) {
		var self = this;
		playPause.click(function(e) {
			self.togglePlay();
			return false;
		});
	}
	
	return function(elements, options) {
		if(elements.length) {
			var self = this;
			
			this.elements = elements;
			this.options = jQuery.extend({}, this.defaults, options);
			
			this.elements.each(function(index, element) {
				self.container = jQuery(element),
				self.marquee = self.container.find('> ul'),
				self.items = self.marquee.find('> li'),
				self.currentIndex = 0,
				self.playing = false;
			});
			
			this.options.speed = (((this.options.speed >= 10) ? 1 : ((this.options.speed < 1) ? 10 : (10 - this.options.speed))) * 500);
			
			if(this.options.showControls) {
				var numItems = this.items.length,
				controlsContainer = jQuery('<ul>').addClass('controls'),
				controls = [], i = 0, playPause;
				
				for(i; i < numItems; i++) {
					controls.push(i + 1);
				}
				
				controls = '<li>' + controls.join('</li><li>') + '</li>';
				playPause = jQuery('<li>' + (this.options.autoplay ? this.options.pauseText : this.options.playText) + '</li>').addClass('playPause');
				
				controlsContainer.append(controls, playPause);
				this.container.append(controlsContainer);
				
				bindControls.call(this, controlsContainer);
				bindPlayPause.call(this, playPause);
			}
			
			this.animations[this.options.animation].init.call(this);
			
			if(this.options.autoplay) {
				this.playing = true;
				this.rotate(this.currentIndex);
			}
			
		} else {
			jQuery.error('Elements array supplied to Marquee is empty. Double check your selector.');
		}
	}
})();

Marquee.prototype = {
	defaults: {
		speed: 5, // 1 = slowest, 10 = fastest
		delay: 5, // number of seconds between rotations
		autoplay: true,
		animation: 'fade', // slide or fade... for now
		showControls: true,
		playText: 'play',
		pauseText: 'pause'
	},
	
	togglePlay: function() {
		if(this.playing) {
			this.playing = false;
			this.container.find('.playPause').text(this.options.playText);
			clearTimeout(this.timer);
		} else {
			this.playing = true;
			this.container.find('.playPause').text(this.options.pauseText);
			this.rotate(this.currentIndex);
		}
	},
	
	rotate: function(index) {
		var self = this;
		clearTimeout(this.timer);
		
		if(this.playing) {
			index = ((index == this.items.length) ? 0 : ((index > this.items.length) ? this.items.length - 1 : index));
			var time = (this.options.delay * 1000) + ((this.currentIndex == index) ? 0 : this.options.speed);
			this.timer = setTimeout(function() { self.rotate(++index); }, time);
		}
		
		this.animations[this.options.animation].animate.call(this, index);
		this.currentIndex = index;
	}
}

Marquee.prototype.animations = {
	slide: {
		init: function() {
			this.items.each(function() {
				jQuery(this).css({
					float: 'left'
				});
			});
			
			var firstItem = jQuery(this.items[0]).clone(true);
			
			this.marquee.css({
				width: ((this.items.length + 1) * this.marquee.width())
			}).append(firstItem);
		},
		
		animate: function(index) {
			if(this.currentIndex == 0) {
				this.marquee.css({
					marginLeft: 0
				});
			}
			
			if(this.currentIndex == (this.items.length - 1) && index == 0) {
				this.marquee.stop().animate({
					marginLeft: ((this.container.width() * this.items.length) * -1) + 'px'
				}, this.options.speed);
			} else {
				this.marquee.stop().animate({
					marginLeft: ((this.container.width() * index) * -1) + 'px'
				}, this.options.speed);
			}
		}
	},
	
	fade: {
		init: function() {
			var self = this;
			this.items.each(function(i) {
				jQuery(this).css({
					position: 'absolute',
					top: 0,
					left: 0,
					zIndex: (i == 0) ? self.items.length : 0
				});
			});
		},
		
		animate: function(index) {
			var self = this;

			var controls = self.container.find('.controls');
			var activeClass = "marquee-active-nav";
			controls.find("li").each(function(i){
				li = $(this);
				if( i == index )
					li.addClass(activeClass);
				else
					li.removeClass(activeClass);
					
			});

			jQuery(this.items[index]).stop().animate({
				opacity: 1
			}, this.options.speed, function() {
				jQuery(this).css({
					zIndex: self.items.length
				});
			}).siblings().stop().animate({
				opacity: 0
			}, this.options.speed, function() {
				jQuery(this).css({
					zIndex: 0	
				});
			});
			
			
		}
	}
}

