(function($) {

	var $tickerItems = {};
	var $ticker = {};
	var $tickerContainer = {};
	var tickerItemsTotalWidth = 0;
	var settings = {
		speed: 0.05,
		tickerContainerClass: 'ticker-container',
		tickerWidth: 0,
		pauseOnHover: false
	};

	var methods = {
		init: function(options) {
			if(options) {
				$.extend(settings, options);
			}

			$tickerItems = this;
			$ticker = this.parent();

			$ticker.wrap('<div class="'+settings.tickerContainerClass+'">');
			$tickerContainer = $ticker.parent();

			tickerItemsTotalWidth = 0;
			$tickerItems.each(function() {
				tickerItemsTotalWidth += $(this).outerWidth(true);
			});

			$tickerContainer.css({
				position: 'relative',
				overflow: 'hidden'
			});

			$ticker.css({
				position: 'relative',
				width: tickerItemsTotalWidth
			});

			if(settings.tickerWidth > 0) {
				$tickerContainer.css({width: settings.tickerWidth});
			}

			if(tickerItemsTotalWidth > $tickerContainer.width()) {
				$ticker.css({width: tickerItemsTotalWidth*2});
				$ticker.append($tickerItems.clone());

				methods.scrollLeft(tickerItemsTotalWidth, $tickerContainer.width(), settings.speed, function() {
					$ticker.css({left: -(tickerItemsTotalWidth-$tickerContainer.width())});
				});
			}

			if(settings.pauseOnHover) {
				$ticker.mouseenter(function() {
					methods.pause();
				});
				$ticker.mouseleave(function() {
					methods.resume();
				});
			}

			return this;
		},
		scrollLeft: function(length, initialOffset, speed, callback) {
			$ticker.animate({left: '-='+(length-initialOffset)}, (length-initialOffset)/speed, 'linear', function() {
				if(typeof(callback) == 'function') {
					callback();
					methods.scrollLeft(length, 0, speed, callback);
				} else {
					scrollLeft(length, 0, speed);
				}
			});
		},
		pause: function() {
			$ticker.stop();
		},
		resume: function() {
			if(settings.tickerWidth > 0) {
				$tickerContainer.css({width: settings.tickerWidth});
			}

			if(tickerItemsTotalWidth > $tickerContainer.width()) {
				$ticker.css({width: tickerItemsTotalWidth*2});
				$ticker.append($tickerItems.clone());
				
				methods.scrollLeft(tickerItemsTotalWidth, $tickerContainer.width()-parseFloat($ticker.css('left').split('px')[0]), settings.speed, function() {
					$ticker.css({left: -(tickerItemsTotalWidth-$tickerContainer.width())});
				});
			}
		}
	};

	$.fn.ticker = function(method) {
		if(methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else if(typeof(method) === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' +  method + ' does not exist on jQuery.ticker');
		}
	}
})(jQuery);
