/*

 * jQuery Carousel Plugin v1.0

 * http://richardscarrott.co.uk/posts/view/jquery-carousel-plugin

 *

 * Copyright (c) 2010 Richard Scarrott

 *

 * Dual licensed under the MIT and GPL licenses:

 * http://www.opensource.org/licenses/mit-license.php

 * http://www.gnu.org/licenses/gpl.html

 *

 * Requires jQuery v1.4+

 *

 */



// prototypal inheritance

if (typeof Object.create !== 'function') {

	Object.create = function (o) {

		function F() {}

		F.prototype = o;

		return new F();

	};

}



(function($) {

	// ie alias

	var headache = $.browser.msie && $.browser.version.substr(0,1)<9;



	// carousel

	var Carousel = {

		settings: {

			itemsPerPage: 1,

			itemsPerTransition: 1,

			noOfRows: 1,

			pagination: true,

			nextPrevLinks: true,

			speed: 'normal',

			easing: 'swing'

		},

		init: function(el, options) {
			 

			if (!el.length) {return false;}

			this.options = $.extend({}, this.settings, options);

			this.itemIndex = 0;	

			this.container = el;

			this.runner = this.container.find('ul');

			this.items = this.runner.children('li');

			this.noOfItems = this.items.length;

			this.setRunnerWidth();

			if (this.noOfItems <= this.options.itemsPerPage) {return false;} // bail if there are too few items to paginate

			this.insertMask();

			this.noOfPages = Math.ceil((this.noOfItems - this.options.itemsPerPage) / this.options.itemsPerTransition) + 1;

			if (this.options.pagination) {this.insertPagination();}

			if (this.options.nextPrevLinks) {this.insertNextPrevLinks();}

			this.updateBtnStyles();

		},

		insertMask: function() {

			this.runner.wrap('<div class="mask" />');

			this.mask = this.container.find('div.mask');



			// set mask height so items can be of varying height

			var maskHeight = this.runner.outerHeight(true);

			this.mask = this.container.find('div.mask');

			this.mask.height(maskHeight);

		},

		setRunnerWidth: function() {

			this.noOfItems = Math.round(this.noOfItems / this.options.noOfRows);

			var width =  this.items.outerWidth(true) * this.noOfItems;

			this.runner.width(width);

		},

		insertPagination: function() {

			var i, links = [];

			this.paginationLinks = $('<ol class="pagination-links" />');

			for (i = 0; i < this.noOfPages; i++) {

				links[i] = '<li><a href="#item-' + i + '">' + (i + 1) + '</a></li>';

			}

			this.paginationLinks

				.append(links.join(''))

				.appendTo(this.container)

				.find('a')

					.bind('click.carousel', $.proxy(this, 'paginationHandler'));

		},

		paginationHandler: function(e) {

			this.itemIndex = e.target.hash.substr(1).split('-')[1] * this.options.itemsPerTransition;

			this.animate();

			return false;

		},

		insertNextPrevLinks: function() {

			this.prevLink = $('<a href="#" class="prev"></a>')

								.bind('click.carousel', $.proxy(this, 'prevItem'))

								.appendTo(this.container);

			this.nextLink = $('<a href="#" class="next"></a>')

								.bind('click.carousel', $.proxy(this, 'nextItem'))

								.appendTo(this.container);

		},

		nextItem: function() {

			this.itemIndex = this.itemIndex + this.options.itemsPerTransition;

			this.animate();

			return false;

		},

		prevItem: function() {

			this.itemIndex = this.itemIndex - this.options.itemsPerTransition;

			this.animate();

			return false;

		},

		updateBtnStyles: function() {

			if (this.options.pagination) {

				this.paginationLinks

					.children('li')

						.removeClass('current')

						.eq(Math.ceil(this.itemIndex / this.options.itemsPerTransition))

							.addClass('current');

			}



			if (this.options.nextPrevLinks) {

				this.nextLink

					.add(this.prevLink)

						.removeClass('disabled-next').removeClass('disabled-prev');

				if (this.itemIndex === (this.noOfItems - this.options.itemsPerPage)) {

					this.nextLink.addClass('disabled-next');

				} 

				else if (this.itemIndex === 0) {

					this.prevLink.addClass('disabled-prev');

				}

			}

		},

		animate: function() {

			var nextItem, pos;

			// check whether there are enough items to animate to

			if (this.itemIndex > (this.noOfItems - this.options.itemsPerPage)) {

				this.itemIndex = this.noOfItems - this.options.itemsPerPage; // go to last panel - items per transition

			}

			if (this.itemIndex < 0) {

				this.itemIndex = 0; // go to first

			}

			nextItem = this.items.eq(this.itemIndex);

			pos = nextItem.position();

			

			if (headache) {

				this.runner

					.stop()

					.animate({left: -pos.left}, this.options.speed, this.options.easing);

			}

			else {

				this.mask

					.stop()

					.animate({scrollLeft: pos.left}, this.options.speed, this.options.easing);

			}

			this.updateBtnStyles();

		}

	};



	// bridge

	$.fn.carousel = function(options) {

		return this.each(function() {

			var obj = Object.create(Carousel);

			obj.init($(this), options);

			$.data(this, 'carousel', obj);

		});

	};

})(jQuery);
