(function($) {  $.fn.easySlider = function(options){    // default configuration properties    var defaults = {      prevId: 'prevBtn',             // id of the element to apply prev rules to      nextId: 'nextBtn',             // id of the element to apply next rules to      prevText: 'Previous',          // text for autogenerated prev link      nextText: 'Next',              // text for autogenerated next link      autogeneratePagination: false, // will automatically generate pagination links      orientation: '',               // 'vertical', 'fade', or anything else will assume horizontal      speed: 800,                    // duration of a transition      autoplayDuration: 0,           // auto-play if non-zero, this is the time between transitions      restartDuration: 2500,         // time to restart autoplay after a user interupts and autoplay      loop: false,                   // loop around the content      hoverPause: 0,                 // when hovering, the time between transitions      hover: false,                  // on hover instead of onclick      easing: null,                  // jQuery animation settings 'linear' or 'swing' (default)      pauseable: false,              // pause autoplay when hovering the image      pauseButtons: false,           // hovering over the cuttons will pause as well      beforeTransition: null,        // callback before transitioning      afterTransition: null          // callback after transitioning    };    var options = $.extend(defaults, options);    return this.each(function() {      // Setup Measurements and Options      var obj = $(this),          totalSlides  = $("li", obj).length,          slideWidth   = obj.width(),          slideHeight  = obj.height(),          lastSlide    = totalSlides-1,          current      = 0;      // States      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;      // Autogenerate Pagination      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>');      }      // Important Elements      var $ul   = $("ul", obj),          $next = $("#"+options.nextId),          $prev = $("#"+options.prevId);      // Loop - Duplicate the First Slide onto the end      if (loop) {        $ul.append( $("li:first", obj).clone() );        totalSlides += 1;        lastSlide += 1;      }      // Horizontal - Make them float left and set the width of the ul (for all slides)      if (horizontal) {        $("li", obj).css('float','left');        $ul.css('width', totalSlides * slideWidth);      }      // Fade - Hide all but the first slide so they can fadeIn from nothing      if (fade) {        $ul.find("li:not(:first)").hide();      }      // Reusable Closure to pause the autoplay timer      var pauseFunc = function() {        clearInterval(interval);        clearTimeout(restart);      }      // Reusable Closure to restart the autoplay timers using the restartDuration      var restartFunc = function() {        restart = setTimeout(function() {          interval = setInterval(auto, autoplayDuration);        }, restartDuration);      };      // Pauseable (should be autoplay only, but would have no effect otherwise)      // On Hover: cancel the autoplay timers      // On Leave: restart the autoplay timers      if ( pauseable && autoplay ) {        $(obj).hover(pauseFunc, restartFunc);        if ( buttonsPause ) {          $next.hover(pauseFunc, restartFunc);          $prev.hover(pauseFunc, restartFunc);        }      }      // Add Actions to Next and Prev Buttons      // If Not Hover Mode made it click(), if it is Hover Mode, make it hover()      // When in autoplay mode make next/prev reset the autoplay timers      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;          }        );      }      //      // Enclosed Slide Animation      //      // This handles all of the sliding/faiding animation      // @param dir the direction "next" or "prev"      // @param cb the callback function      //      function animate(dir, cb) {        // Before Transition, Guarantee        if ( beforeTransition ) {          beforeTransition( current, $ul.find('li:eq('+current+')'), $ul );        }        // After Transition, Guarantee        // Setup the next have        // NOTE: That current will be the new value when this is called        // due to it being a closure!        var newcb = function() {          if ( cb != null ) {            ( hoverPause == 0 ) ? cb() : setTimeout(cb, hoverPause);          }          if ( afterTransition ) {            afterTransition( current, $ul.find('li:eq('+current+')'), $ul );          }        }        // cur, nex, and update "current"        // cur is the old current slide, the slide we are currently on        // nex is the new current slide, the slide we are transitioning too        // current is a global value that gets updated right here        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;        // Special Case for looping        // If at the end and going forward, instantaneous jump to the first slide        // If at the start and going backward, instantaneous jump to the last slide        // NOTE: The instantaneous jump is an animate() so jQuery handles it in tune        // with the rest of the animations, and is -1 (not 0) time so its instant.        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);          }        }        // Dispatch jQuery Animation for the transition        // Slide horizontally, vertically, or fade        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);          });        }        // Correctly show the Next/Prev links        // When looping they always show, so we can ignore that        // If at the end, hide the next link        // If at the start, hide the previous link        // Any other case we can show both links        if ( !loop ) {          if ( nex <= 0 ) {            $prev.fadeOut();          } else if ( nex >= lastSlide ) {            $next.fadeOut();          } else {            $next.fadeIn();            $prev.fadeIn();          }        }      };      //      // Autoplay      //      // Note that autoplayDuration already has the transitionDuration      // added to it (to prevent doing the addition over and over).      // However that means that the first invokation would take      // autoplayDuration+transitionDuration.  We remove that extra      // wait by first doing a single setTimeout with the correct      // time, followed by the correct setInterval.      //      if ( autoplay ) {        var auto = function() {          animate('next');          if ( !loop && current>=lastSlide ) {            clearInterval(interval);          }        }        restart = setTimeout(function() {          auto();          interval = setInterval(auto, autoplayDuration);        }, autoplayDuration-speed);      }      // Initially Hide both buttons      $next.hide();      $prev.hide();      // Finally, Display the Next Link if more then one slide      if (totalSlides>1) {        $next.fadeIn();        if(loop) { $prev.fadeIn(); }      }    });  };})(jQuery);
