(function($, undefined) {
    $.widget('ui.tabmenu', $.ui.tabs, {

        options: {
            active: null,
            collapsible: false,
            event: "click",
            fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }

            // callbacks
            activate: null,
            beforeActivate: null,
            beforeLoad: null,
            load: null
        },

        _eventHandler: function(event) {
            var that = this,
                    options = that.options,
                    active = that.active,
                    clicked = $(event.currentTarget),
                    clickedIsActive = clicked[ 0 ] === active[ 0 ],
                    collapsing = clickedIsActive && options.collapsible,
                    toShow = collapsing ? $() : that._getPanelForTab(clicked),
                    toHide = !active.length ? $() : that._getPanelForTab(active),
                    tab = clicked.closest("li"),
                    eventData = {
                        oldTab: active,
                        oldPanel: toHide,
                        newTab: collapsing ? $() : clicked,
                        newPanel: toShow
                    };

            event.preventDefault();


            if (tab.hasClass("ui-state-disabled") ||
                // tab is already loading
                    tab.hasClass("ui-tabs-loading") ||
                // can't switch durning an animation
                    that.running ||
                // click on active header, but not collapsible
                    ( clickedIsActive && !options.collapsible ) ||
                    ($.inArray(clicked.get()[0], this.dummy_anchors) != -1) ||
                // allow canceling activation
                    ( that._trigger("beforeActivate", event, eventData) === false )) {
                clicked[ 0 ].blur();
                return;
            }


            options.active = collapsing ? false : that.anchors.index(clicked);

            that.active = clickedIsActive ? $() : clicked;
            if (that.xhr) {
                that.xhr.abort();
            }

            if (!toHide.length && !toShow.length) {
                throw "jQuery UI Tabs: Mismatching fragment identifier.";
            }

            if (toShow.length) {
                // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
                that.load(that.anchors.index(clicked), event);

                clicked[ 0 ].blur();
            }

            if (clicked.attr("menu-level") == 0) {
                this.dummy_anchors.each(function () {
                    $(this).parent().removeClass("ui-tabs-active");
                    $(this).data("tab-active", false);
                })
            }

            that._toggle(event, eventData);
        },

        _processNestedTabs: function (list, level) {
            var self = this, fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
            var curr_lis = $(" > li:has(a[href])", list);
            $.merge(this.lis, curr_lis);

            var curr_anchors = curr_lis.map(function() {
                return $("a", this)[ 0 ];
            });

            $.merge(this.anchors, curr_anchors);

            curr_anchors.each(function(i, a) {
                var href = $(a).attr("href"),
                        hrefBase = href.split("#")[ 0 ],
                        selector,
                        panel,
                        baseEl;
                $(a).attr("menu-level", level);
                // For dynamically created HTML that contains a hash as href IE < 8 expands
                // such href to the full page url with hash and then misinterprets tab as ajax.
                // Same consideration applies for an added tab with a fragment identifier
                // since a[href=#fragment-identifier] does unexpectedly not match.
                // Thus normalize href attribute...
                if (hrefBase && ( hrefBase === location.toString().split("#")[ 0 ] ||
                        ( baseEl = $("base")[ 0 ]) && hrefBase === baseEl.href )) {
                    href = a.hash;
                    a.href = href;
                }


                // inline tab
                if (fragmentId.test(href)) {
                    // remote tab
                    // prevent loading the page itself if href is just "#"
                    selector = href;

                    var ul = $(a).next();
                    if (ul && ul.prop("tagName") == "UL") {
                        self.dummy_anchors.push(a);
                        self.nestedLists.push(ul);
                        var parent = $(a).parent();
                        $(a).data("tab-active", false);
                        ul.menu({
                            select: function(event, ui) {
                                $(a).data("tab-active", true);
                                $(this).hide();

                            }
                        }).popup({
                            open: function(event, ui) {
                                parent.removeClass('ui-tabs-active');
                            },
                            close: function (event, ui) {
                                if ( $(a).data("tab-active")) {
                                    parent.addClass("ui-tabs-active");
                                } else {
                                    parent.removeClass("ui-tabs-active");
                                }
                            }
                         }).css("position", "absolute").zIndex(1000);
                        self._processNestedTabs(ul, level+1);

                    } else {
                        panel = self.element.find(self._sanitizeSelector(selector));

                    }


                } else if (href && href !== "#") {
                    var id = self._tabId(a);
                    selector = "#" + id;
                    panel = self.element.find(selector);
                    if (!panel.length) {
                        panel = self._createPanel(id);
                        panel.insertAfter(self.panels[ i - 1 ] || self.list);
                    }
                    // invalid tab href
                } else {
                    self.options.disabled.push(i);

                }

                if (panel && panel.length) {
                    self.panels = self.panels.add(panel);
                }
                if (selector) {
                    $(a).attr("aria-controls", selector.substring(1));
                }
            });
        },
        _processTabs: function() {
            this.list = this.element.find("ol,ul").eq(0);
            this.nestedLists = $([]);
            this.lis = $([]);
            this.anchors = $([]);
            this.dummy_anchors = $([]);
            this.panels = $([]);
            this.c = $([]);
            this._processNestedTabs(this.list, 0);
        }
    });
})(jQuery);
