/*


	jQuery plugin: simpleCarousel
	Author: Ian Hart

	What?
	=====
	It's a super, simple, magical carousel!


	How?
	====
		- See HTML/CSS examples below.
		- $('.simple-carousel') doesn't have to be a <ul> element (but if not, make sure you specify an appropriate scrollItemSelector - see Options).
		- Rather than hard-coding the Previous and Next links, I recommend appending them with JavaScript before initiating this plugin.
		- A ".disabled" CSS class will be applied to Previous and Next links when appropriate.

		HTML example:

			<ul class="simple-carousel">
				<li><img src="../img/my-image-1.jpg" /> My Image 1</li>
				<li><img src="../img/my-image-2.jpg" /> My Image 2</li>
				<li><img src="../img/my-image-3.jpg" /> My Image 3</li>
				<li><img src="../img/my-image-4.jpg" /> My Image 4</li>
				<li><img src="../img/my-image-5.jpg" /> My Image 5</li>
			</ul>
			<a href="#" class="prev">Previous</a>
			<a href="#" class="next">Next</a>
			
		CSS example (horizontal scrolling):
		
			ul.simple-carousel		{ width:400px; }
			ul.simple-carousel li	{ width:200px; float:left; }

		CSS example (vertical scrolling):

			ul.simple-carousel		{ height:200px; }
			ul.simple-carousel li	{				} // IMPORTANT! Using overflow:auto here causes jerky animation in Firefox 3 and 3.5. Use width:100% and float:left instead.
			a.disabled				{ color:#bbb;   } 

		JS example:

			$('.simple-carousel').simpleCarousel({
				orientation : 'v'
			});


	Options
	=======
	orientation : Specify 'v' for vertical scrolling. Any other value will result in horizontal scrolling.
	nextSelector : A string representing the selector for the next link.
	prevSelector : A string representing the selector for the previous link.
	scrollItemSelector : A string representing the child elements in "this".
	scrollItems : Number of items to scroll.


	Dependencies
	============
	- jQuery 1.3.2 or higher (jquery.com)


*/
(function($){
	$.fn.simpleCarousel = function(settings){
		var G = {
			config : {
				orientation 		: 'h',
				nextSelector 		: '#nxt',
				prevSelector 		: '#prv',
				scrollItemSelector 	: 'li',
				scrollItems 		: 4,
				carouselSpeed : 'slow'
			},
			$this : this
		};
		
		if(settings){ $.extend(G.config, settings); }


		function init(el){
		
			var wrapper, totalWidth, parent, totalItems, $el;
			
			G.$this.each(function()
			{
				$el = this;
				totalItems = $(this).find(G.config.scrollItemSelector).length;
				
				if (totalItems <= G.config.scrollItems)
					$('div.ctrl').css('visibility','hidden');
							
				totalWidth = 0;
			
				$(this)
				.data({
					'simpleCarousel' : {
						'currentItem' : 1,
						'totalItems'  : totalItems,
						'prevLink'    : '',
						'nextLink'    : ''
					}
				})
				.css({
					'overflow' : 'hidden',
					'position' : 'relative'
				});

				// If horizontal scrolling, create a wrapper (we'll be scrolling it).
				if(G.config.orientation !=='v')
				{
					$(this).find(G.config.scrollItemSelector).each(function(i){
						totalWidth += $(this).outerWidth(true);
					});

					wrapper = $('<div class="carousel-container"></div>').css({
						'width'    : $(this).outerWidth()
						,'overflow' : 'hidden'
						,'height' : G.config.carouselHeight
						
					});
	
					$(this).css({
						'width'    : totalWidth,
						'position' : 'absolute', // Remove relative positioning for IE6.
						'left' : 0
					})
					.wrap(wrapper);
				}
				
				parent = (G.config.orientation==='h') ? $(this).parent().parent() : $(this).parent();
				
				$(this).data().simpleCarousel.prevLink = parent.find(G.config.prevSelector);
				$(this).data().simpleCarousel.nextLink = parent.find(G.config.nextSelector);
	
				// Next.
				parent.find(G.config.nextSelector)
				.data({
					'simpleCarousel' : {
						'carousel' : $el
					}
				})
				.click(function(e){
					e.preventDefault();
					
					var $el = $($(this).data().simpleCarousel.carousel),
						data = $el.data().simpleCarousel;
					  
					  var moreToGo = true;

            if ((data.totalItems - data.currentItem) <= G.config.scrollItems)
              moreToGo = false;
					
					if(data.currentItem < data.totalItems && moreToGo){
						data.currentItem += G.config.scrollItems;
						data.currentItem = (data.currentItem > data.totalItems) ? data.totalItems : data.currentItem;
	
						doScroll($el, data);						
						disableLinks(this, data);						
						data.currentItem = (data.currentItem>(data.totalItems-G.config.scrollItems)) ? (data.totalItems-(G.config.scrollItems-1)): data.currentItem;
					}
					
				});
				
				// Prev.
				parent.find(G.config.prevSelector)
				.data({
					'simpleCarousel' : {
						'carousel' : $el
					}
				})
				.click(function(e){
					e.preventDefault();
					
					var $el = $($(this).data().simpleCarousel.carousel),
						data = $el.data().simpleCarousel;
	
					if(data.currentItem > 1){
						data.currentItem -= G.config.scrollItems;		
						data.currentItem = (data.currentItem < 0) ? 1 : data.currentItem;
	
						doScroll($el, data);
						disableLinks(this, data);
					}
					
				})
				.addClass('disabled'); // Disable previous link initially.

				
			});
		
		}
		
		
		function doScroll($el, data){
		
			if(G.config.orientation === 'h'){

				var w = 0;
				$el.find(G.config.scrollItemSelector+':lt('+(data.currentItem-1)+')').each(function(){
					w += $(this).outerWidth(true);
				});

				$el.animate({
					'left' : w-(w*2)
				}, {duration: G.config.carouselSpeed});
			
			}
			else{
			
				$el.animate({
					'scrollTop' : Math.ceil($el.find(G.config.scrollItemSelector+':nth-child('+data.currentItem+')').position().top) + $el.scrollTop()
				}, {duration: G.config.carouselSpeed});
			
			}
		
		}
		
		
		function disableLinks(el, data){
		
			var $nav = $(el).parent();
      var moreToGo = true;

      if ((data.totalItems - data.currentItem) <= G.config.scrollItems)
        moreToGo = false;
    
			if(data.currentItem >= data.totalItems || !moreToGo){
				data.nextLink.addClass('disabled');
			}
			else{
				data.nextLink.removeClass('disabled');
			}
		
			if(data.currentItem <= 1){
				data.prevLink.addClass('disabled');
			}
			else{
				data.prevLink.removeClass('disabled');
			}		
		}		
		init(this);
		return this;	
	};

})(jQuery);
