/**
 * Ticker.js
 * 
 * @version 1.0
 * @author Maurice Snip <mauricesnip at hotmail dot com>
 */
function Ticker(el, options) {
	this.el = $(el);
	this.options = options;
	this.ticker = null;
	this.contentWidth = 0;
	this.rewinding = false;
	this.init();
}

Ticker.prototype = {
	/**
	 * Initialize
	 */
	init: function() {
		if(this.el.length) {
			this.options = $.extend({
				template: '<div class="ticker-wrapper"><div class="ticker-clip"></div><div class="ticker-control ticker-rewind"></div><div class="ticker-control ticker-forward"></div></div>',
				autoStart: true,
				speed: 0.03,
				speedMultiplier: 4,
				pauseOnHover: true
			}, this.options || {});
			
			this.createTicker();
			
			if(this.options.autoStart === true) {
				this.start();
			}
		}
	},
	
	/**
	 * Create ticker
	 */
	createTicker: function() {
		var self = this;
		
		this.el.find('li').each(function() {
			self.contentWidth += $(this).outerWidth(true);
		});
		
		this.ticker = $(this.options.template).insertAfter(this.el);
		this.ticker.find('.ticker-clip').css({
			'position': 'relative',
			'overflow': 'hidden'
		}).append(this.el);
		
		this.el.css({
			'position': 'relative',
			'width': this.contentWidth
		});
		
		// Ticker content overflows, prepare to scroll
		if(this.contentWidth > this.ticker.width()) {
			this.el.width(this.contentWidth * 2);
			this.el.append(this.el.find('li').clone().addClass('clone'));
			this.bindEventHandlers();
		}
	},
	
	/**
	 * Bind event handlers
	 */
	bindEventHandlers: function() {
		var self = this;
		
		if(this.options.pauseOnHover === true) {
			this.el.hover(
				function() {
					self.stop();
				},
				function() {
					self.start();
				}
			);
		}
		
		this.ticker.find('.ticker-control').hover(
			function() {
				self.stop();
				self.rewinding = /rewind/.test(this.className);
				self.scroll(self.getScrollOffset(), self.options.speed * self.options.speedMultiplier);
			},
			function() {
				self.stop();
				self.rewinding = false;
				self.start();
			}
		);
	},
	
	/**
	 * Start scrolling
	 */
	start: function() {
		if(this.contentWidth > this.ticker.width()) {
			this.scroll(this.getScrollOffset(), this.options.speed);
		}
	},
	
	/**
	 * Stop scrolling
	 */
	stop: function() {
		this.el.stop();
	},
	
	/**
	 * Scroll animation
	 * 
	 * @param {Number} offset The offset distance in px
	 * @param {Number} divisor The divisor for duration calculation
	 */
	scroll: function(offset, divisor) {
		var self = this;
		var operator = this.rewinding ? '+=' : '-=';
		
		this.el.animate({
			'left': operator + offset
		}, offset / divisor, 'linear', function() {
			self.el.css('left', self.rewinding ? (self.contentWidth * -1) : 0);
			self.scroll(self.contentWidth, divisor);
		});
	},
	
	/**
	 * Calculate the scroll offset
	 * 
	 * @return {Number} The absolute scroll offset
	 */
	getScrollOffset: function() {
		var absLeft = Math.abs(this.el.position().left);
		return this.rewinding ? absLeft : this.contentWidth - absLeft;
	}
};
