var Tabs = Class.create();

/**
 * Javascript tabs implemented using Prototype and Scriptaculous.
 * 
 * @author Kieran Hall <khall@rippleffect.com>
 */
Tabs.prototype = 
{
    /**
     * Initialise the class.
     *
     * @param string tabContainerId
     * @param bool ajax
     * @param bool history
     * @param array options
     * @return void
     */
    initialize: function(tabContainerId, ajax, history, options)
    {
        this.tabContainer = tabContainerId; // Set the global tab container by it's ID.
        var ajax          = ajax;
        var history       = history;
        
        this.setOptions(options); // Set the global options
        
        /* Load in other classes, if required */
        if(ajax)
        {
            this.ajax = new Tabs_Ajax(options); // The tabs will load content via AJAX calls.
        }
        else
        {
            this.layers     = true; // The tabs will load content by toggling display styles.
            this.defaultTab = $(this.options.defaultTabId); // Need to activate this tab.
        }
        
        if(history)
        {
            this.history = new Tabs_History(options);
        }
        
        this.bindLinks($(tabContainerId));
        Event.observe(window, 'load', this.initialiseTabs.bind(this));
        
        var contentContainers = $$('#' + this.tabContainer + ' div.' + this.options.tabContentClass);
            
        contentContainers.each(function(div)
        {
        	div.hide();
		});
            
        var t = this.getDefaultTabContainer(this.defaultTab)
        if (t != null) t.show();
        
    },
    
    /**
     * Initialise the tabs.  This method activates the default tab and creates the event 
     * listener on the appropriate anchor tags.
     * 
     * @return void
     */
    initialiseTabs: function()
    {
        if(this.layers)
        {
            /*var contentContainers = $$('#' + this.tabContainer + ' div.' + this.options.tabContentClass);
            
            contentContainers.each(function(div)
            {
                div.hide();
            });
            
            this.getDefaultTabContainer(this.defaultTab).show();*/
    
            $$('#' + this.tabContainer + ' a').each(function(a)
            {
                if(a.getAttribute('rel') == 'tab')
                {
                    Event.observe(a, 'click', this.toggleTab.bindAsEventListener(this));
                }
            }.bind(this));
        }
    },
    
    /**
     * Identifies the corrosponding container to the default tab.
     *
     * @return Element
     */
    getDefaultTabContainer: function(tab)
    {
        if (tab != null)
        {
	        var number            = (tab.previousSiblings().length) + 1; // The deafult tab number.
	        var contentContainers = $$('#' + this.tabContainer + ' div.' + this.options.tabContentClass); // Target containers are divs inside the container with the tabContentClass.
	        var i                 = 1; // The loop starts at 1.
	        var container         = '';
	        
	        this.defaultTab.addClassName('current');
	        contentContainers.each(function(div)
	        {
	            if(i == number)
	            {
	                container = div;
	            }
	            
	            i++;
	        });
	        
	        return container;
		}
		
		return null;
    },
    
    /**
     * Sets the global options to default, unless an array of 
     * options is passed via the constructor.
     *
     * @param array options
     * @return void 
     */
    setOptions: function(options)
    {
        /* Set the default options */
        this.options = 
        {
            animateTransition:  false,          // Applies animation to the changing of a tab.
            defaultTabId:       'default-tab',  // The default tab's identifier.
            tabContentClass:    'tabContent',   // Tab content class.  Only needed when using the layered approach.
            tabRelAttribute:    'tab'           // Tab relationship attribute string.  This replaces the tabs anchor tag with a javascript call.
        }
        
        Object.extend(this.options, options || {}); // Overwrites the defaults with those supplied.
    },
    
    /**
     * Loops through all the anchor tags contained in the tab container 
     * and updated the DOM with the relevant tabbed URLs.
     *
     * @param string container
     * @return void
     */
    bindLinks: function(container)
    {
        var element     = container;
        var anchorNodes = $A(element.getElementsByTagName('a'));
        
        for(var i = 0; i < anchorNodes.length; i++)
        {
            var anchorNode = Element.extend(anchorNodes[i]);
            var ignoreNode = false
            
            /* If the anchor has a javascript href call */
            if(anchorNode.hasAttribute('href'))
            {
                if(anchorNode.getAttribute('href').indexOf('javascript') != -1)
                {
                    ignoreNode = true;
                }
            }
            
            /* If the anchor has a relationship attribute, that is not that of a tab */
            if(anchorNode.hasAttribute('rel'))
            { 
                if(anchorNode.getAttribute('rel').indexOf(this.options.tabRelAttribute) == -1)
                {
                    ignoreNode = true;
                }
            }
            else
            {
                ignoreNode = true;
            }
            
            if(ignoreNode == false)
            {
                if(anchorNode.hasAttribute('href'))
                {
                    var href = anchorNode.getAttribute('href');
                    
                    if(href.length)
                    {
                        href = href.toString();
                        
                        if(href.indexOf('?') != -1)
                        {
                            queryString = href.substr(href.indexOf('?'));
                            href        = href.substr(0, href.indexOf('?')); 
                        }
                    }
                }
                
                anchorNode.href = 'javascript:;';
                
                if(anchorNode.hasAttribute('onclick'))
                {
                    var onClickAction = anchorNode.getAttribute('onclick');
                    
                    if(onclickAction.length != 0)
                    {
                        Event.observe(anchorNode, 'click', function(){onClickAction});
                    }
                }
            }
        }
    },
    
    /**
     * Toggles the currently displayed tab for the tab identified by the event listener.
     *
     * @param string element
     * @return void
     */
    toggleTab: function(element)
    {
        this.unsetCurrentTab();
        
        var tabLi = Event.findElement(element, 'li');
        tabLi.addClassName('current');
        
        if(this.layers)
        {   
            var liNumber          = (tabLi.previousSiblings().length) + 1; // The current tab number.      
            var contentContainers = $$('#' + this.tabContainer + ' div.' + this.options.tabContentClass); // Target containers are divs inside the container with the tabContentClass.         
            var i                 = 1; // The loop starts at 1.
            
            contentContainers.each(function(div)
            {
                if(i == liNumber)
                {
                    div.show();
                }
                
                i++;
            });
        } 
    },
    
    /**
     * Removes the 'current' tab's attributes, rendering it inactive.
     *
     * @return void
     */
    unsetCurrentTab: function()
    {
        var tabLi = $$('#' + this.tabContainer + ' li');
        
        tabLi.each(function(li)
        {
            if(li.hasClassName('current'))
            {
                li.removeClassName('current');
            }
        });
        
        if(this.layers)
        {
            var tabDivContainer = $$('#' + this.tabContainer + ' .' + this.options.tabContentClass );

            tabDivContainer.each(function(div)
            {
                if(div.visible())
                {
                    div.hide();
                }
            });
        }
    }
};




var Tabs_Ajax = Class.create();

/**
 * Ajax functionality for Tabs.
 * 
 * @author Kieran Hall <khall@rippleffect.com>
 */
Tabs_Ajax.prototype = 
{
    initialize: function(options)
    {
    
    }
};




var Tabs_History = Class.create();

/**
 * Implementation of Really Simple History (RSH) for Tabs.
 * 
 * @author Kieran Hall <khall@rippleffect.com>
 */
Tabs_History.prototype = 
{
    initialize: function(options)
    {
    
    }
};