/* Copyright (c) 2009 Alexandre Plennevaux (alexandre AT pixeline DOT be || http://www.pixeline.be)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
* 
* See http://www.pixeline.be/experiments/simplyTabs/
*/

/**
Creates a tabbed interface out of a link of in-page anchors. 
If the anchor's target element does not exist, the tab is not created.

In order to achive the "tabbification", the plugin simply uses css classes. The css styling takes care of showing/ hiding. So that the designers can do most (if not all) of the tweaking inside the CSS stylesheet.

Designed for minimal fuzz.

Look 'n feel: A basic CSS is provided but you can customize the look completely.

* @example jQuery('#tabbedContainer').simplyTabs();
* @name simplyTabs
* @version r1 _ 01.03.2009
* @type jQuery
* @param Object	settings	hash with options, described below.
*		tabsNavMenuSelector - class of the menu to be used for the tabs detection & navigation (default : 'ul.tabsNavMenu' )
*       tabsNavMenuClass - class given to the tabs navigation menu (default: 'tab-menu')
*       tabsPanelClass - class given to the tab panels (default: 'tab-panel')
*       tabsNavMenuItemClass - class given to the menu items anchor elements (default: 'tab-menu-item')
*       visibleTabClass - class given to the active tab (default: 'tab-visible')
*       invisibleTabClass - class given to the inactive tabs ( default: 'tab-hidden')
*       selectedTab - tab selected on launch - 0-based, according to the anchor order in the html markup. (default: 0 (first tab))
*       selectedTabClass - class given to the active tab (default: 'tab-menu-item-selected')
*       onShow - callback function triggered after a tab is displayed (default: null)
*
* @return jQuery
* @cat Plugins/simplyTabs
* @author Alexandre Plennevaux (alexandre AT pixeline DOT be || http://www.pixeline.be)


*/
(function($)
{
    $.fn.simplyTabs = function(options)
    {

        // build main options before element iteration
        var opts = $.extend({}, $.fn.simplyTabs.defaults, options);
        // iterate and reformat each matched element
        return this.each(function()
        {

            var $tabContainer = $(this).addClass('simplyTabs');
            // build element specific options
            var o = $.meta ? $.extend({}, opts, $tabContainer.data()) : opts;

            if ($(o.tabsNavMenuSelector, $tabContainer).length > 0)
            {
                var $menu = $(o.tabsNavMenuSelector);
                $menu.addClass(o.tabsNavMenuClass);
                $('a', $menu).addClass(o.tabsNavMenuItemClass).each(function(index)
                {
                    var $thisMenuItem = $(this);
                    // check if this anchor targets an existing identifier
                    var panelSelector = this.hash;
                    var $panel = $(panelSelector);
                    if ($panel.length)
                    {
                        // if so, turn the element into a tab panel
                        $panel.addClass(o.tabsPanelClass);
                        // ... the link into a tab activator
                        $thisMenuItem.addClass(o.tabsNavMenuItemClass);
                        if (index == o.selectedTab)
                        {
                            $panel.addClass(o.visibleTabClass);
                            $thisMenuItem.addClass(o.selectedTabClass);
                        } else
                        {
                            $panel.addClass(o.invisibleTabClass);
                        }
                    }
                });
                // then assign tab (des)activation behavior to anchors
                $('a.' + o.tabsNavMenuItemClass).bind('click.simplyTabs', function(e)
                {
                    e.preventDefault();
                    var $this = $(this);
                    // switch panel
                    var selectedPanel = this.hash;

                    var $tabContainer = $(this).parents('.simplyTabs');
                    $('.' + o.tabsPanelClass, $tabContainer).removeClass(o.visibleTabClass).addClass(o.invisibleTabClass);
                    $(selectedPanel).addClass(o.visibleTabClass);
                    // update menu
                    $('a.' + o.tabsNavMenuItemClass, $tabContainer).removeClass(o.selectedTabClass);
                    $this.addClass(o.selectedTabClass);

                    if (jQuery.isFunction(o.onShow))
                    {

                        o.onShow.apply(this);

                    }

                });
            }
        });
    };

    //
    // plugin defaults
    //
    $.fn.simplyTabs.defaults = {
        tabsNavMenuSelector: 'ul.tabsNavMenu'
        , tabsNavMenuClass: 'tab-menu'
        , tabsPanelClass: 'tab-panel'
        , tabsNavMenuItemClass: 'tab-menu-item'
        , visibleTabClass: 'tab-visible'
        , invisibleTabClass: 'tab-hidden'
        , selectedTab: 0
        , selectedTabClass: 'tab-menu-item-selected'
        , onShow: null
    };
    //
    // end of closure
    //
})(jQuery);
