/* 
 *  jQuery Carousel plugin
 *  by Zach Waugh
 *  v1.0 - 1/12/2009
 * 
 */

(function($){
	// Private vars
	var isAnimating = false;
	var carousel; // current carousel object
	
	// Public functions
	$.fn.carousel = function(options)
	{	
		$(this).each(function(){
			// Default settings, can be overridden when function is called
			var settings = $.extend({
				next: 'a.next',
				previous: 'a.previous',
				page: 'a.page',
				item: 'li',
				items: '.carousel_items',
				container: '.carousel_container',
				duration: 750,
				padding: 0,
				paginated: false,
				perpage: false,
				controls: false,
				easing: 'easeInOutQuad',
				horizontal: true
			}, options);
			
			$(this).addClass('has_carousel');
			
			if(settings.horizontal)
			{
				initHorizontal(this, settings);
			}
			else
			{
				initVertical(this, settings);
			}
		});
	};
	
		// -----------------
		// Private functions
		// -----------------
		
		// Initialize horizontal carousel vars
		function initHorizontal(carousel, settings)
		{	
			settings.width = calculateWidth(carousel, settings);
		
			// check if using in paginated mode
			if(settings.paginated)
			{
				// Get number of items per "page"
				var perpage;
			
				if(!settings.perpage)
				{
					itemsize = $(carousel).find(settings.items).children(settings.item).innerWidth();
					perpage = Math.round(width / itemsize);
				}
				else
				{
					perpage = settings.perpage;
				}
			
				total = $(carousel).find(settings.items).children(settings.item).size();
			
				// Figure out how many pages are needed
				// Based on total / x, where x = items per page
				var pages = Math.ceil(total / perpage);
				
				// Add controls if more than one page and controls == true
				if (settings.controls && pages > 1)
				{
					buildControls();
				}
			}
			
			// Store settings on carousel jQuery object
			$(carousel).data('settings', settings);
			
			// Bind events
			$(carousel).find(settings.previous).click(previousPage);
			$(carousel).find(settings.next).click(nextPage);
		}
		
		// Initialize carousel vars
		function initVertical(carousel, settings)
		{	
			// Calculate height of displayed area
			var height = $(carousel).find(settings.container).css('height');
		
			// Width not set in CSS in IE6/IE7
			if (height == 'auto')
			{
				height = $(carousel).find(settings.container).innerHeight() + settings.padding;
			}
			else
			{
				height = parseFloat(height) + settings.padding;
			}
			
			settings.height = height;
		
			// Get number of items per "page"
			if(settings.paginated)
			{
				var perpage;
				if(!settings.perpage)
				{
					itemsize = $(carousel).find(settings.items).children(settings.item).innerHeight();
					perpage = Math.round(height / itemsize);
				}
				else
				{
					perpage = settings.perpage;
				}

				total = $(carousel).find(settings.items).children(settings.item).size();

				// Figure out how many pages are needed
				// Based on total / x, where x = items per page
				var pages
			  pages = Math.ceil(total / perpage);

				// Add controls if more than one page and controls == true
				if (settings.controls && pages > 1)
				{
					buildControls();
				}
			}

			$(carousel).data('settings', settings);
			$(carousel).find(settings.previous).click(previousPage);
			$(carousel).find(settings.next).click(nextPage);
		}
		
		// Bind events
		function bindEvents()
		{
			$(carousel).find(settings.previous).click(previousPage);
			$(carousel).find(settings.next).click(nextPage);

			// $(carousel).find(settings.page).click(function(){
			// 	if(!$(this).hasClass('active'))
			// 	{
			// 		slideTo($(carousel).find(settings.page).index(this));
			// 	}
			// 
			// 	return false;
			// });
	
			// $(carousel).find(settings.items).find(settings.item).click(function(){
			// 	var content = $(this).next('div').html();
			// 	$(this).parents(settings.items).find('a.bordered_img').removeClass('selected');
			// 	$(this).addClass('selected');
			// 	$(this).parents(carousel).next('.related_content').html(content);
			// 	return false;
			// });
		}
		
		// build HTML for controls in javascript
		function buildControls()
		{
			var controls = '<div class="controls">\n<a href="" class="previous inactive"></a>';
			for(var i = 0; i < pages; i++) {
				if (i === 0)
				{
					controls += '<a href="" class="page active"></a>\n';
				}
				else
				{
					controls += '<a href="" class="page"></a>\n';
				}
			}
			controls += '<a href="" class="next"></a>\n</div>';
			
			// Add controls node to DOM
			$(carousel).prepend(controls);
		}
			
		function previousPage(event)
		{
			// Prevent clicking while animating
			if(isAnimating)
			{
				return false;
			}
			
			// Figure out which carousel to operate on
			var carousel = $(this).parents('.has_carousel');
			var settings = $(carousel).data('settings');
			
			if (settings.horizontal && $(carousel).find(settings.items).css('left') != '0px')
			{
				slideLeft(carousel, settings);
			}
			
			if (!settings.horizontal && $(carousel).find(settings.items).css('top') != '0px')
			{
				slideUp(carousel, settings);
			}

			return false;
		}
		
		function nextPage(event)
		{
			// Prevent clicking while animating
			if(isAnimating || $(this).hasClass('disabled'))
			{
				return false;
			}
			
			// Figure out which carousel to operate on
			var carousel = $(this).parents('.has_carousel');
		  var settings = $(carousel).data('settings');
			
			if(settings.horizontal)
			{ 
				slideRight(carousel, settings);
			}
			else
			{
				slideDown(carousel, settings);
			}
			
			return false;
		}
		
		// slideTo
		// slide to a particular page in the current carousel
		function slideTo(page)
		{
			var current_page = currentPage();
			if(page < current_page)
			{
				slideLeft((current_page - page) * settings.width);
			}
			else
			{
				slideRight((page - current_page) * settings.width);
			}
		}
		
		// Horizontal - slideLeft: previous()
		function slideLeft(carousel, settings)
		{
			isAnimating = true;
			var width = calculateWidth(carousel, settings);
			
			$(carousel).find(settings.items).animate({left: '+=' + width + 'px'}, {duration: settings.duration, easing: settings.easing, complete: function(){
				isAnimating = false;
				
				$(carousel).find(settings.next).removeClass('disabled');
				
				if(settings.paginated)
				{
				  selectPage();	
				}
				
				if ($(carousel).find(settings.items).css('left') == '0px')
				{
					$(carousel).find(settings.previous).addClass('disabled');
				}
			}});
		}
	
		// Horizontal - slideRight: next()
		function slideRight(carousel, settings)
		{
			isAnimating = true;
			
			var width = calculateWidth(carousel, settings);
			
			$(carousel).find(settings.items).animate({left: '-=' + width + 'px'}, {duration: settings.duration, easing: settings.easing, complete: function(){
				isAnimating = false;
				
				$(carousel).find(settings.previous).removeClass('disabled');
				
				if(settings.paginated)
				{
					selectPage();
				}
				
				// Figure out if last item is outside the bounds of the current window
				// if not, make next disabled
				var position = $(carousel).find(settings.item + ':last').position();
				var left = parseFloat($(carousel).find(settings.items).css('left')) * -1;
				
				if (position.left <= (left + width))
				{
					$(carousel).find(settings.next).addClass('disabled');
				}
			}});
		}
		
		// Vertical - slideUp: previous()
		function slideUp(carousel, settings)
		{
			isAnimating = true;
			$(carousel).find(settings.items).animate({top: '+=' + settings.height + 'px'}, {duration: settings.duration, easing: settings.easing, complete: function(){
				isAnimating = false;
				
				$(carousel).find(settings.next).removeClass('disabled');
				
				if(settings.paginated)
				{
					selectPage();
				}
				
				if ($(carousel).find(settings.items).css('top') == '0px')
				{
					$(carousel).find(settings.previous).addClass('disabled');
				}
			}});
		}
	
		// Vertical - slideDown: next()
		function slideDown(carousel, settings)
		{
			isAnimating = true;
			$(carousel).find(settings.items).animate({top: '-=' + settings.height + 'px'}, {duration: settings.duration, easing: settings.easing, complete: function(){
				isAnimating = false;
				
				$(carousel).find(settings.previous).removeClass('disabled');
				
				if(settings.paginated)
				{	
					selectPage();
				}
				
				
				var position = $(carousel).find(settings.item + ':last').position();
				var top = parseFloat($(carousel).find(settings.items).css('top')) * -1;
				
				if (position.top < (top + settings.height))
				{
					$(carousel).find(settings.next).addClass('disabled');
				}
			}});
		}
	
		// selectPage:
		// handles highlighting which page is active
		function selectPage()
		{
			var page = currentPage();
			$(carousel).find(settings.page).removeClass('active');
			$(carousel).find(settings.page).slice(page, page + 1).addClass('active');
		}
	
		// currentPage:
		// calculates which page we're on
		function currentPage()
		{
			var left = $(carousel).find(settings.items).css('left');
			var page = 0;
			
			if (left != 'auto')
			{
				var position = Math.abs(left.substr(0, left.length - 2));
				page = position / settings.width;
			}

			return page;
		}
		
		function calculateWidth(carousel, settings)
		{
			var width = $(carousel).find(settings.container).css('width');

			// Width not set in CSS in IE6/IE7
			if (width == 'auto')
			{
				width = $(carousel).find(settings.container).innerWidth() + settings.padding;
			}
			else
			{
				width = parseFloat(width) + settings.padding;
			}
			
			return width;
		}
		
})(jQuery);