﻿;(function($) {

$.ui = $.ui || {};

$.ui.accordion = {};
$.extend($.ui.accordion, {
       defaults: {
               selectedClass: "selected",
               alwaysOpen: true,
               animated: 'slide',
               event: "click",
               header: "a",
               autoheight: true
       },
       animations: {
               slide: function(settings, additions) {
                       settings = $.extend({
                               easing: "swing",
                               duration: 300
                       }, settings, additions);
                       if ( !settings.toHide.size() ) {
                               settings.toShow.animate({height: "show"}, {
                                       duration: settings.duration,
                                       easing: settings.easing,
                                       complete: settings.finished
                               });
                               return;
                       }
                       var hideHeight = settings.toHide.height(),
                               showHeight = settings.toShow.height(),
                               difference = showHeight / hideHeight;
                       settings.toShow.css({ height: 0, overflow: 'hidden' }).show();
                       settings.toHide.filter(":hidden").each(settings.finished).end().filter(":visible").animate({height:"hide"},{
                               step: function(now){
                                       settings.toShow.height((hideHeight - (now)) * difference );
                               },
                               duration: settings.duration,
                               easing: settings.easing,
                               complete: settings.finished
                       });
               },
               bounceslide: function(settings) {
                       this.slide(settings, {
                               easing: settings.down ? "bounceout" : "swing",
                               duration: settings.down ? 1000 : 200
                       });
               },
               easeslide: function(settings) {
                       this.slide(settings, {
                               easing: "easeinout",
                               duration: 700
                       })
               }
       }
});

$.fn.extend({
       accordion: function(settings) {
               if ( !this.length )
                       return this;
       
               // setup configuration
               settings = $.extend({}, $.ui.accordion.defaults, settings);
               
               if ( settings.navigation ) {
                       var current = this.find("a").filter(function() { return this.href == location.href; });
                       if ( current.length ) {
                               if ( current.filter(settings.header).length ) {
                                       settings.active = current;
                               } else {
                                       settings.active = current.parent().parent().prev();
                                       current.addClass("current");
                               }
                       }
               }
               
               // calculate active if not specified, using the first header
               var container = this,
                       headers = container.find(settings.header),
                       active = findActive(settings.active),
                       running = 0;

               if ( settings.fillSpace ) {
                       var maxHeight = this.parent().height();
                       headers.each(function() {
                               maxHeight -= $(this).outerHeight();
                       });
                       var maxPadding = 0;
                       headers.next().each(function() {
                               maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
                       }).height(maxHeight - maxPadding);
               } else if ( settings.autoheight ) {
                       var maxHeight = 0;
                       headers.next().each(function() {
                               maxHeight = Math.max(maxHeight, $(this).outerHeight());
                       }).height(maxHeight);
               }

               headers
                       .not(active || "")
                       .next()
                       .hide();
               active.parent().andSelf().addClass(settings.selectedClass);
               
               
               function findActive(selector) {
                       return selector != undefined
                               ? typeof selector == "number"
                                       ? headers.filter(":eq(" + selector + ")")
                                       : headers.not(headers.not(selector))
                               : selector === false
                                       ? $("<div>")
                                       : headers.filter(":eq(0)");
               }
               
               function toggle(toShow, toHide, data, clickedActive, down) {
                       var finished = function(cancel) {
                               running = cancel ? 0 : --running;
                               if ( running )
                                       return;
                               // trigger custom change event
                               container.trigger("change", data);
                       };
                       
                       // count elements to animate
                       running = toHide.size() == 0 ? toShow.size() : toHide.size();
                       
                       if ( settings.animated ) {
                               if ( !settings.alwaysOpen && clickedActive ) {
                                       toShow.slideToggle(settings.animated);
                                       finished(true);
                               } else {
                                       $.ui.accordion.animations[settings.animated]({
                                               toShow: toShow,
                                               toHide: toHide,
                                               finished: finished,
                                               down: down
                                       });
                               }
                       } else {
                               if ( !settings.alwaysOpen && clickedActive ) {
                                       toShow.toggle();
                               } else {
                                       toHide.hide();
                                       toShow.show();
                               }
                               finished(true);
                       }
               }
               
               function clickHandler(event) {
                       // called only when using activate(false) to close all parts programmatically
                       if ( !event.target && !settings.alwaysOpen ) {
                               active.parent().andSelf().toggleClass(settings.selectedClass);
                               var toHide = active.next();
                               var toShow = active = $([]);
                               toggle( toShow, toHide );
                               return;
                       }
                       // get the click target
                       var clicked = $(event.target);
                       
                       // due to the event delegation model, we have to check if one
                       // of the parent elements is our actual header, and find that
                       if ( clicked.parents(settings.header).length )
                               while ( !clicked.is(settings.header) )
                                       clicked = clicked.parent();
                       
                       var clickedActive = clicked[0] == active[0];
                       
                       // if animations are still active, or the active header is the target, ignore click
                       if(running || (settings.alwaysOpen && clickedActive) || !clicked.is(settings.header))
                               return;

                       // switch classes
                       active.parent().andSelf().toggleClass(settings.selectedClass);
                       if ( !clickedActive ) {
                               clicked.parent().andSelf().addClass(settings.selectedClass);
                       }

                       // find elements to show and hide
                       var toShow = clicked.next(),
                               toHide = active.next(),
                               data = [clicked, active, toShow, toHide],
                               down = headers.index( active[0] ) > headers.index( clicked[0] );
                       
                       active = clickedActive ? $([]) : clicked;
                       toggle( toShow, toHide, data, clickedActive, down );

                       return false;
               };
               function activateHandler(event, index) {
                       // IE manages to call activateHandler on normal clicks
                       if ( arguments.length == 1 )
                               return;
                       // call clickHandler with custom event
                       clickHandler({
                               target: findActive(index)[0]
                       });
               };


               return container
                       .bind(settings.event || "", clickHandler)
                       .bind("activate", activateHandler);
       },
       activate: function(index) {
               return this.trigger('activate', [index]);
       },
       unaccordion: function() {
               return this.find("*").andSelf().unbind().end().end();
       }
});

})(jQuery);
