;(function($) {
$.widget("ui.smoothTabs", {
    $nav: null,
    $lis: null,
    $tabs: null,
    $panels: null,
    init: function()
    {
        this.$nav = this.element.children('ul:first');
        this.$lis = this.$nav.children('li:has(a[id])');
		this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
		this.$panels = $([]);

        var self = this, o = this.options;

        /**
         * Get tab panels
         */
        this.$tabs.each(function(i, a)
        {
            if ($(a).attr('id').substr(0, 7) === 'select-')
            {
                var id = $(a).attr('id').substr(7);
                var $panel = $('#' + id);

                if ($panel.length)
                {
			        a.href = '#' + id;
                    self.$panels = self.$panels.add($panel);
                }
            }
        });

		/**
		 * attach necessary classes for styling if not present
		 */
		this.$nav.addClass(o.navClass);
		this.$panels.each(function() {
			$(this).addClass(o.panelClass);
		});

        /**
         * Selected tab
         */
        if (o.selected === undefined)
        {
            var selected = self.$lis.filter('.' + o.selectedClass);
            if (selected.length)
            {
                o.selected = self.$lis.index(selected.eq(0));
            }
        }

        /**
         * first tab selected by default
         */
		o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0;

        /**
         * highlight selected tab
         */
		this.$panels.addClass(o.hideClass);
		this.$lis.removeClass(o.selectedClass);

        if (o.selected !== null)
        {
		    this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
			this.$lis.eq(o.selected).addClass(o.selectedClass);

            /**
             * Force outer div height for animation
             */
            this.$nav.siblings(':first').css({ height: this.getSelectedHeight() });
        }

        /**
         * tab click event
         */
        this.$tabs.bind('click', function()
        {
			var $li = $(this).parents('li:eq(0)'),
				$hide = self.$panels.filter(':visible'),
				$show = $(this.hash);

			// If tab is already selected
			if ($li.hasClass(o.selectedClass))
			{
				this.blur();
				return false;
			}

            /**
             * Update selected tab
             */
			self.options.selected = self.$tabs.index(this);

			// stop possibly running animations
			self.$panels.stop();

            /**
             * Show new tab
             */
            if ($show.length && $hide.length)
            {
                $li.addClass(o.selectedClass)
				    .siblings().removeClass(o.selectedClass);

                /**
                 * Here is where the "smoothing" magic happens;
                 * First, fade out the tab panel to hide
                 */
                $hide.fadeOut('fast' , function()
                {
                    $hide.addClass(o.hideClass);

                    /**
                     * Second, show the tab to show but set the opacity to 0
                     * in order to accurately calculate the new height
                     */
                    $show.show().css({ opacity: 0 });

                    /**
                     * Third, animate the tabs outer container height to the new height
                     */
                    self.$nav.siblings(':first').animate({ height: self.getSelectedHeight() }, function()
                    {
                        /**
                         * Finally, hide the tab to show, reset the opacity to 1,
                         * and fade in it's content
                         */
                        $show.hide().css({ opacity: 1 }).fadeIn('normal', function()
                        {
                            $(this).removeClass(o.hideClass)
                        });
                    });
                });
            }

			// Prevent IE from keeping other link focussed when using the back button
			// and remove dotted border from clicked link. This is controlled in modern
			// browsers via CSS, also blur removes focus from address bar in Firefox
			// which can become a usability and annoying problem with tabsRotate.
			if ($.browser.msie)
				this.blur();

			return false;
        });
    },

    getSelectedHeight: function()
    {
        return this.$panels.eq(this.options.selected).outerHeight(true);
    }
});

$.ui.smoothTabs.defaults = {
	// CSS classes
	navClass: 'ui-tabs-nav',
	selectedClass: 'ui-tabs-selected',
	unselectClass: 'ui-tabs-unselect',
	disabledClass: 'ui-tabs-disabled',
	panelClass: 'ui-tabs-panel',
	hideClass: 'ui-tabs-hide'
};

})(jQuery);

