(function ($) {
  $.fn.slideshow = function (options) {

    /* this sets the defaults and somehow puts them into options. whatever. */
    var defaults = {
      speed: 1000, 		// any number
      duration: 4000, 		// any number
      automatic: true, 		// true, false
      pages: '', 			// a jQuery object containing anchors
      page_changes: 'onclick'		// onclick
    };
    var options = $.extend(defaults, options);


    /* this is what of the plugin is executed */
    return this.each(function () {

      var container = $(this);
      var children = $(this).children('a');

      // find current slide
      var active = container.find('.active');
      if (active.length == 0) {
        active = container.children(':first');
        active.addClass('active');
        $(active).show();
      }

      // find current link
      if (options.pages) {
        var pages = $(options.pages).find('a');
        pages.eq(children.index(active)).addClass('active');
      }

      // hide slides
      children.each(function () {
        $(this).not(active).css({
          'opacity': 0
        });
      });

      // start automatic slideshow
      if (options.automatic) {
        active.animate({ 'opacity': 1 }, options.speed);
        var interval = setInterval(function () { transition(container); }, options.duration);
      }

      // pages onclick
      if (options.page_changes == 'onclick') {
        pages = $(options.pages).find('a');
        pages.each(function () {
          $(this).click(function (e) {
            // stop slideshow, switch to selected slide
            e.preventDefault();
            clearInterval(interval);
            if ($(this).text() != $(options.pages).find('a.active').text()) {
              var page = $(this);
              transition(container, page);
            }
            // restart slideshow
            if (options.automatic) {
              interval = setInterval(function () { transition(container); }, options.duration);
            }
          });
        });
      }

    });


    /* these are the functions used in the return */

    function transition(container, page) {

      // sine the initial slide state is hidden for everything, once a transition occurs we need to show everything. 
      container.children().each(function () { $(this).show(); });

      // find current slide
      var active = container.find('.active');
      // find next slide
      if (page) {
        var next = container.children().eq($(options.pages).find('a').index(page));
      } else {
        var next = active.next();
        if (next.length == 0) {
          next = container.children(':first');
        }
      }


      // fade transition
      active.css('z-index', 0);
      next
					.css('z-index', 1)
					.animate({ 'opacity': 1 }, options.speed, function () {
					  active
							.animate({ 'opacity': 0 }, (options.speed / 4))
							.removeClass('active')
						;
					})
					.addClass('active')
				; // fade transition

      // pages transition
      if (options.pages) {

        // pages transition
        var pages = $(options.pages).find('a');
        var currPage = $(options.pages).find('a.active');
        if (page) {
          var nextPage = page;
        } else {
          var nextPage = pages.eq(pages.index(currPage) + 1);
          if ((pages.index(currPage) + 1) >= pages.length) {
            nextPage = pages.eq(0);
          }
        }
        currPage.removeClass('active');
        nextPage.addClass('active');

      } // page transition

    } // function transition()

  }; // slideshow plugin
})(jQuery);

