(function($) {

	$.fn.easySlider = function(options) {

		var defaults = {
			prevId : 'prevBtn',
			nextId : 'nextBtn',
			prevText : 'Previous',
			nextText : 'Next',
			autogeneratePagination : false,
			orientation : '',
			speed : 800,
			autoplayDuration : 0,
			restartDuration : 2500,
			loop : false,
			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 = $("li", 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, 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).after(
								'<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>');
					}
					var $ul = $("ul", obj), $next = $("#" + options.nextId), $prev = $("#"
							+ options.prevId);
					if (loop) {
						$ul.append($("li:first", obj).clone());
						totalSlides += 1;
						lastSlide += 1;
					}
					if (horizontal) {
						$("li", obj).css('float', 'left');
						$ul.css('width', totalSlides * slideWidth);
					}
					if (fade) {
						$ul.find("li: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, $ul.find('li:eq('
									+ current + ')'), $ul);
						}
						var newcb = function() {
							if (cb != null) {
								(hoverPause == 0) ? cb() : setTimeout(cb,
										hoverPause);
							}
							if (afterTransition) {
								afterTransition(current, $ul.find('li: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) ? $ul.animate( {
									marginTop : 0
								}, -1) : $ul.animate( {
									marginLeft : 0
								}, -1);
							} else if ((dir == "prev") && (cur == 0)) {
								(vertical) ? $ul.animate( {
									marginTop : (totalSlides - 1) * slideHeight
											* -1
								}, -1) : $ul.animate( {
									marginLeft : (totalSlides - 1) * slideWidth
											* -1
								}, -1);
							}
						}
						if (horizontal) {
							$ul.animate( {
								marginLeft : (nex * slideWidth * -1)
							}, speed, easing, newcb);
						} else if (vertical) {
							$ul.animate( {
								marginTop : (nex * slideHeight * -1)
							}, speed, easing, newcb);
						} else {
							var curli = 'li:eq(' + cur + ')';
							var nexli = 'li:eq(' + nex + ')';
							$ul.find(curli).fadeOut("slow", function() {
								$ul.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);
