/*!
* jQuery Header Toggle plugin
* Version 1.1
* @requires jQuery v1.2.3 or later
*
* 1.0 Change log:
*   Initial version
* 1.1 Change log:
*   Added global/expand methods ($.fsa_HeaderToggle_expand and $.fsa_HeaderToggle_collapse)
*   Added scoping through "groups" so that each time the plugin is called, a new group is created.
*   This facilitates maintaining your own hierarchives and allows separation of 'toggleall' button functionality by group.
*/

(function($) {
    if (!$.FSA) {
        $.FSA = new Object();
    };

    var divCount = 0;
    var groupCount = -1;
    var groups = [];
    var expandedState = "expanded";
    var collapsedSate = "collapsed";
    var groupAttribute = "togglegroup";

    var ltIE8 = ($.browser.msie && $.browser.version < 8);

    // global $ methods for expand/collapse
    $.fsa_HeaderToggle_expand = function(options) {
        if (options && options.toggleall != undefined) {
            $(options.toggleall).click();
        }
        else if (options && options.groupnumber != undefined) {
            if (groups.length > options.groupnumber) {
                toggleGroupState(options.groupnumber, collapsedSate);
            }
        }
        else {
            $('.togglediv').each(function() {
                var $this = $(this);
                if ($this.attr("state") == collapsedSate) {
                    $this.click();
                }
            });
        }
    };

    $.fsa_HeaderToggle_collapse = function(options) {
        if (options && options.toggleall != undefined) {
            $(options.toggleall).click();
        }
        else if (options && options.groupnumber != undefined) {
            if (groups.length > options.groupnumber) {
                toggleGroupState(options.groupnumber, expandedState);
            }
        }
        else {
            $('.togglediv').each(function() {
                var $this = $(this);
                if ($this.attr("state") == expandedState) {
                    $this.click();
                }
            });
        }
    };

    $.fsa_HeaderToggle_getGroups = function() {
        return groups;
    };

    function toggleGroupState(group, state) {
        for (var i = 0; i < groups[group].length; i++) {
            if (groups[group][i].attr("state") == state)
                groups[group][i].click();
        }
    }

    $.FSA.HeaderToggle = function(el, options) {
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;

        // Access to jQuery and DOM versions of element
        base.$el = $(el);
        base.el = el;

        // Add a reverse reference to the DOM object
        base.$el.data("FSA.HeaderToggle", base);

        base.init = function() {
            base.options = $.extend({}, $.FSA.HeaderToggle.defaultOptions, options);
        };

        // Run initializer
        base.init();

        // Create a div, add a span to the div, and insert the header into the div after the span.
        // First, figure out if the body is a sibling, or if we need to traverse up
        var found = false;
        var $parent = null;
        var level = 0;
        while (!found && level < 10) {
            if ($parent == null) {
                if (base.$el.next("." + base.options.bodyclass).length == 0) {
                    $parent = base.$el.parent();
                    level++;
                }
                else {
                    found = true;
                }
            }
            else {
                if ($parent.next("." + base.options.bodyclass).length == 0) {
                    $parent = $parent.parent();
                    level++;
                }
                else {
                    found = true;
                }
            }
        }

        var divId = "togglediv" + divCount.toString();
        var spanId = "togglespan" + divCount.toString();
        var $divInsert = $("<div class='togglediv' id='" + divId + "'></div>");
        var $spanInsert = $("<span id='" + spanId + "'></span>");

        if ($parent != null) {
            $divInsert.insertAfter($parent);
            $spanInsert.appendTo($divInsert);
            $parent.appendTo($divInsert);
        }
        else {
            $divInsert.insertAfter(base.$el);
            $spanInsert.appendTo($divInsert);
            base.$el.appendTo($divInsert);
        }

        $spanInsert.addClass("toggleicon");
        $spanInsert.addClass(base.options.expandclass);
        $divInsert.attr("state", "collapsed");

        // Add a click event to the div.  This will simply toggle the class of the span and slideToggle the body element
        $divInsert.click(function() {
            if ($spanInsert.hasClass(base.options.expandclass)) {
                $spanInsert.addClass(base.options.collapseclass).removeClass(base.options.expandclass);
                $divInsert.attr("state", "expanded");
                $(this).next("." + base.options.bodyclass).slideToggle(base.options.slidespeed);
            }
            else {
                $spanInsert.addClass(base.options.expandclass).removeClass(base.options.collapseclass);
                $divInsert.attr("state", "collapsed");
                $(this).next("." + base.options.bodyclass).slideToggle(base.options.slidespeed);
            }
        });

        $divInsert.attr(groupAttribute, groupCount);
        groups[groupCount][divCount] = $divInsert;
        divCount++;
    };

    $.FSA.HeaderToggle.defaultOptions = {
        bodyclass: 'togglebody',
        expandclass: "expandicon",
        collapseclass: "collapseicon",
        toggleall: '.togglebutton',
        expandtext: 'Expand All',
        collapstext: 'Collapse All',
        slidespeed: 600
    };

    $.fn.fsa_HeaderToggle = function(options) {
        groupCount++;
        divCount = 0;
        groups[groupCount] = [];
        var extendOptions = $.extend({}, $.FSA.HeaderToggle.defaultOptions, options);
        $('.' + extendOptions.bodyclass).hide();
        var $btn = $(extendOptions.toggleall);
        $btn.addClass('expand');
        $btn.attr(groupAttribute, groupCount);
        if ($btn.is("input"))
            $btn.val(extendOptions.expandtext);
        else
            $btn.text(extendOptions.expandtext);

        // Attach a button click to the toggle item.
        // Track the state on the DOM element and act accordingly.
        $btn.click(function() {
            var $this = $(this);
            var group = $this.attr(groupAttribute);
            if ($this.is(".expand")) {
                if ($this.is("input"))
                    $this.val(extendOptions.collapstext);
                else
                    $this.text(extendOptions.collapstext);
                $this.removeClass("expand").addClass("collapse");
                toggleGroupState(group, collapsedSate);
            }
            else {
                if ($this.is("input"))
                    $this.val(extendOptions.expandtext);
                else
                    $this.text(extendOptions.expandtext);
                $this.removeClass("collapse").addClass("expand");
                toggleGroupState(group, expandedState);
            }

            return false;
        });

        return this.each(function() {
            (new $.FSA.HeaderToggle(this, options));
        });
    };

    // This function breaks the chain, but returns
    // the FSA.HeaderToggle if it has been attached to the object.
    $.fn.getFSA_HeaderToggle = function() {
        this.data("FSA.HeaderToggle");
    };
})(jQuery);

