var Tabber = Class.create({

    /**
     * Constructor method that sets up a tabber.  The options parameter is a hash that specifies
     * the following options (all of which have associated default values):
     *
     * options.id: The id of the element containing the tabber and the only required option
     * options.tabsClass: The class name assigned the container element around the tabs
     * options.contentClass: The class name assigned to the container element around the content
     * options.activeTabClass: The class name to apply to an active tab
     * options.activeContentClass: The class name to apply to an active content area
     * options.defaultTab: The default tab shown (count, not index)
     *
     * Care should be taken to note that this is a Prototype 1.6 hash; not simply a JS object
     * acting as a hash.
     *
     * @param    options        The options hash as specified in the function description
     * @return    object        Returns a Tabber JS Object
     */
    initialize: function(options){
        this.options = $H({ id: null,
                            tabsClass: "tab-nav",
                            contentClass: "tab-content",
                            activeTabClass: "tabber-active",
                            activeContentClass: "tabber-content-active",
                            defaultTab: 1}).update(options);

        if(this.options.get("id") == null || $(this.options.get("id")) == undefined){
            throw("You have specified an invalid tabber id");
        }
        this.tabber = $(this.options.get("id"));
        this.tabContainer = $(this.options.get("id") + '-' + this.options.get("tabsClass"));
        this.contentContainer = $(this.options.get("id") + '-' + this.options.get("contentClass"));
        this.constructTabPanel();
        this.tabs = this.tabContainer.childElements();
        this.content = this.contentContainer.childElements();
        if(this.tabs.length != this.content.length){
//            if(this.tabs.length > this.content.length) throw("Not all tabs have content items");
//            if(this.tabs.length < this.content.length) throw("Too many content items for the number of tabs");
        }
        this.tabber.observe("click", this.tabClickHandler.bindAsEventListener(this));
        this.currentIndex = this.options.get("defaultTab") - 1;
        this.activateTab(this.tabs[this.currentIndex]);
        this.activateContent(this.currentIndex);
        if (this.tabber.hasClassName('tabber-primary')) {
            this.enablePrimaryTabs();
            this.handlePrimaryTabs();
        }

    },

    /**
     * Creates a template for the reformmated tabs
     */
    tabTemplate: new Template('<li class="#{clazz}"><a>#{tabValue}</a></li>'),

    /**
     * Formats Tab Panel from component output into TabPanel template
     */
    constructTabPanel: function() {
        var tempChildElements = this.tabber.childElements();
        var tempTabs = tempChildElements.findAll(function(el) {
            return el.hasClassName('tempTab');
         });
        var tempContents = tempChildElements.findAll(function(el) {
            return el.hasClassName('tempTabContent');
         });
        tempTabs.each(function(el) {
            el.removeClassName('tempTab');
            var tab = {
                clazz: el.classNames(),
                tabValue: el.innerHTML
            };
            var newListItem = this.tabTemplate.evaluate(tab);
            this.tabContainer.insert({bottom: newListItem});
            el.remove();
        }.bind(this));

        tempContents.each(function(el) {
            var id = el.id;
            var newContentItem = el.removeClassName('tempTabContent').remove();
            var tabContentClassNames = el.classNames();
            this.contentContainer.insert({bottom: newContentItem});
            newContentItem.setAttribute('id', id);
            newContentItem.addClassName('tab-content-item');
            newContentItem.addClassName(tabContentClassNames);
        }.bind(this));
        this.tabber.show();
    },

    /**
     * Watches for clicks on any of the tab elements and determines which tab was clicked
     */
     tabClickHandler: function(e){
         var el;
         if(e.element().up().up() == this.tabContainer){
            el = e.element().up();
         } else if(e.element().up().up().up() == this.tabContainer){
             el = e.element().up().up();
         } else{
             el = e.element();
         }
        //var el = (e.element().up().up() == this.tabContainer) ? e.element().up() : e.element();
        if((el.up() == this.tabContainer) || (el.up().up() == this.tabContainer) || (el.up().up().up() == this.tabContainer)){
            var tabIndex = this.getTabIndex(el);
//            if(tabIndex == null){
//                throw("Could not determine the tab index");
//            }
            this.activateTab(el);
            this.activateContent(tabIndex);
            this.currentIndex = tabIndex;
        }
        if (this.tabber.hasClassName('tabber-primary')) this.handlePrimaryTabs();
     },

    /**
     * Allows for programatic clicking of tabs 
     */
    forceClick: function(tabIndex) {
           var el = this.tabs[tabIndex];
           this.activateTab(el);
           this.activateContent(tabIndex);
           this.currentIndex = tabIndex;

       },
    

    /**
     * Activates a tab and ensures that no other tabs are shown as active state.
     *
     * @param el     The element object that was clicked to activate
     */
    activateTab: function(el){
        this.tabs[this.currentIndex].removeClassName(this.options.get("activeTabClass"));
        el.addClassName(this.options.get("activeTabClass"));

    },

    /**
     * Activates a content area and forcibly hides the other content areas
     *
     * @param tabIndex    The index of the tab that was activated
     */
    activateContent: function(tabIndex){
        var tmpContent = this.content[tabIndex];
        this.content[this.currentIndex].removeClassName(this.options.get("activeContentClass"));
        tmpContent.addClassName(this.options.get("activeContentClass"));
    },


    /**
     * Gets the index of the clicked tab
     *
     * @param tab        The tab that was clicked
     * @return int    The index of the tab that was clicked
     */
    getTabIndex: function(tab){
        var length = this.tabs.length;
        for(var i=0; i<length; i++){
            if(tab == this.tabs[i]){
                return i;
            }
        }
        return null;
    },

    enablePrimaryTabs: function() {
        var tabNumber = this.tabs.length;
        if (tabNumber == 2) this.primaryTabType = 'double';
        if (tabNumber == 3) this.primaryTabType = 'triple';
        this.tabs.each(function(tab, i) {
            tab.addClassName('tab'+i);
        });
        if (this.primaryTabType == 'double') {
            this.tabContainer.parentNode.addClassName('primary-double');
            this.primaryEndcapsImg = '../img/theme1/components/tabPanel/primary-endcaps.png';
            this.primaryBackgroundOff = '../img/theme1/components/tabPanel/primary-tab-bg-off.png';
        }
        if (this.primaryTabType == 'triple') {
            this.tabContainer.parentNode.addClassName('primary-triple');
            this.primaryEndcapsImg = '../img/theme1/components/tabPanel/primary-endcaps.png';
            this.primaryBackgroundOff = '../img/theme1/components/tabPanel/primary-tab-bg-off.png';
        }
    },
    handlePrimaryTabs: function() {
        if (this.primaryTabType == "double") {
            if (this.currentIndex == 0) {
                this.resetPrimaryTabs();
                this.tabContainer.parentNode.setStyle({
                    backgroundImage: 'url(' + this.primaryEndcapsImg + ')'
                });
                if (this.tabber.hasClassName('type1')) this.tabContainer.parentNode.setStyle({
                    backgroundPosition:'0 0'
                }) ;
                if (this.tabber.hasClassName('type2')) this.tabContainer.parentNode.setStyle({
                    backgroundPosition:'0 -35px'
                }) ;
            }
            if (this.currentIndex == 1) {
                this.resetPrimaryTabs();
                this.tabContainer.setStyle({
                    backgroundImage: 'url(' + this.primaryEndcapsImg + ')'
                });
                if (this.tabber.hasClassName('type1')) this.tabContainer.setStyle({
                    backgroundPosition:'100% 0'
                }) ;
                if (this.tabber.hasClassName('type2')) this.tabContainer.setStyle({
                    backgroundPosition:'100% -35px'
                }) ;
            }
        }

        if (this.primaryTabType == "triple") {
            var activeImage = "../img/theme1/components/tabPanel/articles-tabber.png";
            if (this.currentIndex == 0) {
                this.resetPrimaryTabs();
                this.tabContainer.parentNode.setStyle({
                    backgroundImage: 'url(' + this.primaryEndcapsImg + ')'
                });
                if (this.tabber.hasClassName('type3')) this.tabContainer.parentNode.setStyle({
                    backgroundPosition:'0 -70px'
                }) ;
                this.tabContainer.setStyle({
                    backgroundImage: 'url(' + activeImage + ')'
                });
                if (this.tabber.hasClassName('type3')) this.tabContainer.setStyle({
                    backgroundPosition:'0 0'
                }) ;
            }
            if (this.currentIndex == 1) {
                this.resetPrimaryTabs();
                this.tabContainer.setStyle({
                    backgroundImage: 'url(' + activeImage + ')'
                });
                if (this.tabber.hasClassName('type3')) this.tabContainer.setStyle({
                    backgroundPosition:'0 -35px'
                }) ;
            }
            if (this.currentIndex == 2) {
                this.resetPrimaryTabs();
                this.tabContainer.setStyle({
                    backgroundImage: 'url(' + activeImage + ')'
                });
                if (this.tabber.hasClassName('type3')) this.tabContainer.setStyle({
                    backgroundPosition:'0 -70px'
                }) ;
            }
        }
        
        this.tabs[this.currentIndex].childElements().reduce().addClassName('active');
    },
    resetPrimaryTabs: function() {
        this.tabs.each(function(tab) {
            tab.childElements().reduce().removeClassName('active');
        }.bind(this));
        this.tabContainer.parentNode.setStyle({
            background: 'url(' + this.primaryBackgroundOff + ') no-repeat 0 0'
        });
        this.tabContainer.setStyle({
            background: 'url(' + this.primaryBackgroundOff + ') no-repeat 100% 0'
        });
    }
});