/*
*  Enhanced Easy Slider
*
*  Built off of the Easy Slider - jQuery plugin
*  written by Alen Grakalic
*  http://cssglobe.com/post/3783/jquery-plugin-easy-image-or-content-slider
*
*  enhancements by Joseph Pecoraro
*  email: joepeck02@gmail.com
*  http://blog.bogojoker.com | http://bogojoker.com/easySlide/
*
*  further enhancements by Neil Merton
*  email: neilmerton@gmail.com
*
*  The Easy Slider Copyrights:
*  Copyright (c) 2009 Alen Grakalic (http://cssglobe.com)
*  Dual licensed under the MIT (MIT-LICENSE.txt)
*  and GPL (GPL-LICENSE.txt) licenses.
*
*  Built for jQuery library
*  http://jquery.com
*
*  $Id$
*
*/

(function($)
{
	$.fn.easyslider = function(options)
	{
		var defaults = {
			prevId: 'prevBtn',
			nextId: 'nextBtn',
			prevText: 'Previous',
			nextText: 'Next',
			autogeneratePagination: true,
			beforePagination: '<div id="osCarouselButtons">',
			afterPagination: '</div>',
			orientation: '',
			speed: 750,
			autoplayDuration: 12500,
			restartDuration: 2500,
			loop: true,
			hoverPause: 0,
			hover: false,
			easing: null,
			pauseable: false,
			pauseButtons: false,
			beforeTransition: null,
			afterTransition: null
		};
		var options = $.extend(defaults, options);
		return this.each(function()
		{
			var obj = $(this),
				totalSlides = $("dd", obj).length,
				slideWidth = obj.width(),
				slideHeight = obj.height(),
				lastSlide = totalSlides - 1,
				current = 0;
			var vertical = (options.orientation == 'vertical'),
				fade = (options.orientation == 'fade'),
				horizontal = (!vertical && !fade),
				autogen = options.autogeneratePagination,
				bpage = options.beforePagination,
				apage = options.afterPagination,
				pauseable = options.pauseable,
				loop = options.loop,
				speed = options.speed,
				easing = options.easing,
				hover = options.hover,
				hoverPause = options.hoverPause,
				buttonsPause = options.pauseButtons,
				restartDuration = options.restartDuration,
				autoplayDuration = Math.max(options.autoplayDuration, 25) + speed,
				autoplay = (options.autoplayDuration > 0),
				beforeTransition = options.beforeTransition,
				afterTransition = options.afterTransition;
				interval = null,
				restart = null;
			if (autogen)
			{
				$(obj).append(bpage + '<span id="' + options.prevId + '"><a href=\"javascript:void(0);\">' + options.prevText + '</a></span> ' + '<span id="' + options.nextId + '"><a href=\"javascript:void(0);\">' + options.nextText + '</a></span>' + apage);
			}
			var $dl = $("dl", obj),
				$next = $("#" + options.nextId),
				$prev = $("#" + options.prevId);
			if (loop)
			{
				$dl.append($("dd:first", obj).clone());
				totalSlides += 1;
				lastSlide += 1;
			}
			if (horizontal)
			{
				$("dd", obj).css('float', 'left');
				$dl.css('width', totalSlides * slideWidth);
			}
			if (fade)
			{
				$dl.find("dd:not(:first)").hide();
			}
			var pauseFunc = function()
			{
				clearInterval(interval);
				clearTimeout(restart);
			}
			var restartFunc = function()
			{	
				restart = setTimeout(function(){interval = setInterval(auto, autoplayDuration);}, restartDuration);
			}
			if (pauseable && autoplay)
			{
				$(obj).hover(pauseFunc, restartFunc);
				if (buttonsPause)
				{
					$next.hover(pauseFunc, restartFunc);
					$prev.hover(pauseFunc, restartFunc);
				}
			}
			if (!hover)
			{
				$next.click(function()
				{
					if (autoplay)
					{
						pauseFunc();
						if (!buttonsPause) restartFunc();
					};
					animate("next");
				});
				$prev.click(function()
				{
					if (autoplay)
					{
						pauseFunc();
						if (!buttonsPause) restartFunc();
					};
					animate("prev");
				});
			}
			else
			{
				var hoverNext = false,
					hoverPrev = false,
					isAnimating = false;
				$next.hover(function()
				{
					var tfunc = arguments.callee;
					hoverNext = true;
					if (!isAnimating)
					{
						isAnimating = true;
						animate("next", function()
						{
							isAnimating = false;
							if (hoverNext) { tfunc(); }
						});
					}
				},
				function()
				{
					hoverNext = false;
				});
				$prev.hover(function()
				{
					var tfunc = arguments.callee;
					hoverPrev = true;
					if (!isAnimating)
					{
						isAnimating = true;
						animate("prev", function()
						{
							isAnimating = false;
							if (hoverPrev) { tfunc(); }
						});
					}
				},
				function()
				{
					hoverPrev = false;
				});
			}
			function animate(dir, cb)
			{
				if (beforeTransition)
				{
					beforeTransition(current, $dl.find('dd:eq(' + current + ')'), $ul);
				}
				var newcb = function()
				{
					if (cb != null)
					{
						(hoverPause == 0) ? cb() : setTimeout(cb, hoverPause);
					}
					if (afterTransition)
					{
						afterTransition(current, $dl.find('dd:eq(' + current + ')'), $ul);
					}
				}
				var cur = current;
				if (loop)
				{
					if (dir == 'next')
					{
						current = (current == lastSlide) ? 1 : current + 1;
					}
					else
					{
						current = (current == 0) ? lastSlide - 1 : current - 1;
					}
				}
				else
				{
					if (dir == "next")
					{
						current = (current >= lastSlide) ? lastSlide : current + 1;
					}
					else
					{
						current = (current <= 0) ? 0 : current - 1;
					}
				}
				var nex = current;
				if (loop)
				{
					if ((dir == "next") && (cur == lastSlide))
					{
						(vertical) ? $dl.animate({ marginTop: 0 }, -1) : $dl.animate({ marginLeft: 0 }, -1);
					}
					else if ((dir == "prev") && (cur == 0))
					{
						(vertical) ? $dl.animate({ marginTop: (totalSlides - 1) * slideHeight * -1 }, -1) : $dl.animate({ marginLeft: (totalSlides - 1) * slideWidth * -1 }, -1);
					}
				}
				if (horizontal)
				{
					$dl.animate({ marginLeft: (nex * slideWidth * -1) }, speed, easing, newcb);
				}
				else if (vertical)
				{
					$dl.animate({ marginTop: (nex * slideHeight * -1) }, speed, easing, newcb);
				}
				else
				{
					var curli = 'dd:eq(' + cur + ')';
					var nexli = 'dd:eq(' + nex + ')';
					$dl.find(curli).fadeOut("slow", function()
					{
						$dl.find(nexli).fadeIn("slow", newcb);
					});
				}
				if (!loop)
				{
					if (nex <= 0)
					{
						$prev.fadeOut();
					}
					else if (nex >= lastSlide)
					{
						$next.fadeOut();
					}
					else
					{
						$next.fadeIn();
						$prev.fadeIn();
					}
				}
			};
			if (autoplay)
			{
				var auto = function()
				{
					animate('next');
					if (!loop && current >= lastSlide)
					{
						clearInterval(interval);
					}
				}
				restart = setTimeout(function()
				{
					auto();
					interval = setInterval(auto, autoplayDuration);
				}, autoplayDuration - speed);
			}
			$next.hide();
			$prev.hide();
			if (totalSlides > 1)
			{
				$next.fadeIn();
				if (loop) { $prev.fadeIn(); }
			}
		});
	};
})(jQuery);