/*****************************************************************************
 *
 * Copyright © 2010 Simon Robb
 *
 * All rights reserved
 *
 ****************************************************************************/

(function ($) {
	$.fn.Carousel = function (params) {
		var defaults = {
			initialIndex: 0,			// The panel to start on by index
			autoCycle: true,			// Begin scrolling on init
			cycleInterval: 8000,		// How long between scrolls
			panelWidth: '1000',			// Width of a panel
			panelHeight: '100',			// Height of a panel
			direction: 'horizontal',	// Direction of scroll
			panelsVisible: 1,			// Number of panels visible at once
			length: 700					// Length of animation
        };
        
        var settings = {};
        settings = $.extend({}, defaults, params);
		
        // return this;
        return this.each(function (i) {
            var $$ = $(this);
			settings.element = $$;

		   	var car = new Carousel (settings);
		
			// Store the carousel for public interaction
			$$.data ('carousel', car);
		});
	};
	
	/**
	 * The class constructor
	 * @constructor
	 */
	window.Carousel = function (settings) {
		/**
		 * Class settings
		 */
		this._settings = settings;
		
		/**
		 * Member variables
		 */
		this._panels = this._settings.element.find ('li');
		this._index = 0;
		this._value = 0;
		this._count = this._panels.length;
		
		// Ensure that overflow is hidden
		this._settings.element.css ('overflow', 'hidden');
		
		// Functionality
		var car = this;
		this._settings.nextButton.click (function () {car.next(); car.stop ()});
		this._settings.prevButton.click (function () {car.previous(); car.stop ()});
		
		// Show the initial panel
		if (this._settings.initialValue) {
			index = 0;
			$.each (this._panels, function (i,panel) {
				if ($(panel).attr ('value') == car._settings.initialValue)
					index = i;
			});
			this.goto (index, true);
		} else {
			this.goto (this._settings.initialIndex, true);
		}
		
		// Begin cycling if necessary
		if (this._settings.autoCycle)
			this.play ();
	};
	
	Carousel.prototype = {
		next: function () {
			if (this._index >= this._count - 1 - this._settings.panelsVisible + 1) {
				this.first ();
			} else {
				this.goto (this._index + 1);
			}
		},
		
		previous: function () {
			if (this._index <= 0) {
				this.last ();
			} else {
				this.goto (this._index - 1);
			}
		},
		
		first: function () {
			this.goto (0);
		},
		
		last: function () {
			this.goto (this._count - this._settings.panelsVisible);
		},
		
		goto: function (i, noAnimate) {
			var firstVisibleItem = $('li:visible', this._panels.parent()).eq (0);

			if (this._settings.direction == 'vertical') {
				var margin = -1 * i * this._settings.panelHeight;
				var params = { 'marginTop': margin };
			} else {
				var margin = -1 * i * this._settings.panelWidth;
				var params = { 'marginLeft': margin };
			}
			
			if (noAnimate)
				firstVisibleItem.eq(0).css (params);
				
			else
				firstVisibleItem
					.stop ()
					.animate (
						params,
						this._settings.length
					);
			
			// Update class index
			this._index = i;
			
			// Update class value
			this._value = $(this._panels[i]).attr ('value');
			
			// Reflect change in paging
			if (this._settings.pagingControl) 
				this._settings.pagingControl
					.find ('li')
					.removeClass ('current')
					.eq (i)
					.addClass ('current');
		},
		
		play: function () {
			var car = this;
			
			// Reset if necessary
			this.stop ();
				
			this._timer = setInterval (function () { car.next (); }, this._settings.cycleInterval);
		},
		
		stop: function () {
			if (this._timer)
				clearInterval (this._timer);
		},
		
		getIndex: function () {
			return this._index;
		},
		
		getValue: function () {
			return this._value;
		},
		
		recount: function () {
			this._count = $('li:visible', this._panels.parent ()).length;
			
			// If there are fewer items than the number being shown
			if (this._count < this._settings.panelsVisible)
				this._count = this._settings.panelsVisible;
				
			return this._count;
		}
	};
})(jQuery);

