/*
 * This is a jQuery widget which can take a div and slide the list items inside of it from left to right.
 * The structure of the slidable element and its contents should be as follows:
 * <div id="slider">
 *   <ul>
 *     <li>item 1</li>
 *     <li>item 2</li>
 *     ...
 *   </ul>
 * </div>
 * 
 * Each list item should be floated left, and the padding & margin on the ul and each li should be 0.
 * Example usage:
 *   $("slider").createSlider({ animationSpeed: 2000, pauseDuration: 5000 })
 *
 * This widget works by making <ul> as wide as all of its children put together, and then scrolling that ul
 * left and right. The parent div has overflow:hidden to finish the visual effect.
 * 
 * Author: Phil Crosby (philc@ooyala.com)
 * Copyright 2010 Ooyala
 */
(function($) {

  // The default options.
  var defaultOptions = {
    animationSpeed: 500,
    autoTransition: false,
    pauseDuration: 2000,
    navPanel: null,
    // A callback which is invoked every time this slider transitions to a new panel. The first argument
    // to this callback is the index of the panel being transitioned to.
    onTransition: null,
    // A callback which is invoked each tiem the user explicitly clicks on a navigation link.
    onNavClick: null
  };

  var options = { };

  /*
   * Initializes the slider effect on the current jQuery element.
   */
  $.fn.createSlider = function(userOptions) {
    options = jQuery.extend(defaultOptions, userOptions);  
    
    var div = $(this);
    var ul = $("ul", this);
    var listItems = $("li", div);
    $(listItems[0]).addClass("active");

    // Resize this container to fit the size of its children
    div.width(listItems.width());
    div.height(listItems.height());
    ul.width(listItems.width() * listItems.length);

    div.data("selectedChildIndex", 0);

    createNavigation(div);
    highlightNavigationItem(0);

    div.css("overflow", "hidden");
  };

  /*
   * Creates the navigation buttons (one per "slide") if the navPanel has been provided
   */
  function createNavigation(element) {
    if (!options.navPanel)
      return;
    var navPanel = $(options.navPanel);
    var listItems = $("li", element);
    var createClickHandler = function(element, childIndex) {
      return function(event) {
        if (options.onNavClick)
          options.onNavClick();
        event.preventDefault();
        element.stopAutoTransition();
        slideToChild(element, childIndex);
      };
    };
    for (var i = 0; i < listItems.length; i++) {
      $(document.createElement("a"))
        .html("&bull;")
        .attr("href", "#")
        .appendTo(navPanel)
        .click(createClickHandler(element, i));
    }
  }

  /*
   * Adds the CSS class "selected" to the <a> of the currently selected item within navPanel.
   */
  function highlightNavigationItem(index) {
    if (!options.navPanel)
      return;
    var navItems = $("a", $(options.navPanel));
    navItems.removeClass("selected");
    navItems.eq(index).addClass("selected");
  }

  /*
   * Begins the automatic transitions. After the delay defined by options.pause has elapsed, the next element
   * will be transitioned to.
   */
  $.fn.beginAutoTransition = function() {
    options.autoTransition = true;
    var element = $(this);
    element.slideToNext();
  }

  function slideToChild(element, i) {
    var li = $("li", element).eq(i);
    var offset = li.width() * -i;
    var ul = $("ul", element);
    ul.animate({ marginLeft: offset }, { duration: options.animationSpeed });
    element.data("selectedChildIndex", i);
    highlightNavigationItem(i);
    if (options.onTransition)
      options.onTransition(i);
  }

  /*
   * The index of the currently showing panel.
   */
  $.fn.selectedChildIndex = function() { return $(this).data("selectedChildIndex"); }

  /*
   * Stops the autotransition sequence after it's been started.
   */
  $.fn.stopAutoTransition = function() {
    var element = $(this);
    clearTimeout(element.data("autoTransitionTimeout"));
    options.autoTransition = false;
  }

  $.fn.slideToNext = function() {
    var element = $(this);
    var i = element.data("selectedChildIndex");
    if (i >= $("li", element).length - 1)
      return;
    i += 1;
    slideToChild(element, i);
    clearTimeout(element.data("autoTransitionTimeout"));
    if (options.autoTransition) {
      var timeout = setTimeout(function() { element.slideToNext(); }, options.pauseDuration);
      element.data("autoTransitionTimeout", timeout);
    }
  };

})(jQuery);