/*
 * Fancy Accordion
 * ---
 * Magic and JavaScript combined to suit deep nav.
 *
 * (C) 2009 MyNorth Media
 * michael@traversemagazine.com
 */

(function($) {
  $.fn.fancyAccordion = function(settings) {
    var config = {
      'activeClass': 'active',
      'activeLinkClass': 'activeLink',
      'clickDrag': true,
      'disableParentLinks': true,
      'hideSpeed': 400,
      'hideSiblings': true,
      'showSpeed': 300,
      'subIndicator': '<span class="subIndicator">+</span>',
      'subSelector': '> ul'
    };

    if (settings) $.extend(config, settings);

    function subItemSort(a, b) {
      var $ai = $(a).data('startIndex');
      var $bi = $(b).data('startIndex');

      if ($ai > $bi) return  1;
      if ($ai < $bi) return -1;

      return 0;
    };

    function showSub($li) {
      // Sort the jQuery array, push changes to the DOM
      $li.find(config.subSelector).find('> li').sort(subItemSort).each(function() {
        $li.find(config.subSelector).append(this);
      });

      if (config.hideSiblings) {
        $li.parent().find('li').each(function() {
          $(this).removeClass(config.activeClass);
          $('> a', this).removeClass(config.activeLinkClass);
          $(config.subSelector, this).slideUp(config.hideSpeed);
        });
      }

      $li.addClass(config.activeClass);
      $li.find('> a').addClass(config.activeLinkClass);

      if ($li[0] === $li.parent().find(':first-child')[0]) {
        $li.find(config.subSelector).slideDown(config.showSpeed);
      } else {
        $li.fadeOut(500, function() {
          $(this).prependTo($(this).parent()).fadeIn(250, function() {
            $(this).find(config.subSelector).slideDown(config.showSpeed);
          });
        });
      }

      /* to keep it simple, use this...
      $li.addClass(config.activeClass);
      $li.find(config.subSelector).show();
      */

    };

    function hideSub($li) {
      $li.removeClass(config.activeClass);
      $li.find(config.subSelector).slideUp(config.hideSpeed, function() {
        // close all subs
        $li.find(config.subSelector).each(function() {
          $(this)
            .find('li').removeClass(config.activeClass)
            .find(config.subSelector).hide();
        });
      });
    };


    this.each(function() {

      if (config.clickDrag) {
        /* Disable text selection and allow dragging */
        $(this)
          .css({'MozUserSelect': 'none'})
          .bind('selectstart' + '.disableTextSelect' , function() { return false; })
          .bind('mousedown'   + '.disableTextSelect' , function() { return false; })
      }

      $(this).find('> li').each(function(i) {
        $(this).data('startIndex', i);

        // hide sub menus and THEN test for existence (wtf, right?)
        if ($(config.subSelector, this).hide().length) {
          $(this).find('> a')
            .click(function(e) {
              var $li = $(this).parent();
              ($li.hasClass(config.activeClass)) ? hideSub($li) : showSub($li);
              e.preventDefault();
            });

          $(config.subIndicator)
            .appendTo($(this).find('> a'))
            .click(function(e) {
              window.location = $(this).parent().attr('href');
              e.stopPropagation();
            });
        }
      });

      $(this).find('li.' + config.activeClass).each(function() {
        var $li = $(this);

        $li.find(config.subSelector).find('> li').sort(subItemSort).each(function() {
          $li.find(config.subSelector).append(this);
        });

        if (config.hideSiblings) {
          $li.parent().find('li').each(function() {
            $(this).removeClass(config.activeClass);
            $(config.subSelector, this).hide();
          });
        }

        $li.addClass(config.activeClass);
        $li.find('> a').addClass(config.activeLinkClass);

        if ($li[0] === $li.parent().find(':first-child')[0]) {
          $li.find(config.subSelector).slideDown(config.showSpeed);
        } else {
          $li.hide(function() {
            $(this).prependTo($(this).parent()).show(function() {
              $(this).find(config.subSelector).show();
            });
          });
        }

      });

    });

    return this;

  };
})(jQuery);

