var DoolaoTabs = Class.create();

DoolaoTabs.prototype = {
    initialize: function(contentTarget) {
        //no element to update with new content
        if (typeof contentTarget != "string") {
            alert("No target given");
            return false;
        }
        var defaults = {
            //list of tabs that will be observed for clicks
            //the list constists of objects. the objects need to have
            //the members "id" and "src", where the "id" is a valid
            //element in the html and the "src" is the source from
            //which the new content is loaded. it can be a url or
            //another element in the html.
            //if it is an url, the member "parameter" will be passed
            //on to prototypes ajax-request class
            tabList: [],
            //css-class for a selected tab
            classNameSelected: "selected",
            //css-class for a deselected tab
            classNameDeselected: "deselected",
            //css-class that is assigend to the content-element while the new content is loaded
            classNameLoading: "loading",
            //css-class for a mouseover (may be empty)
            classNameMouseover: "",
            //replace content with loading gif?
            replaceContentWhileLoading: true,
            //link to loading gif
            replaceImage: '/images/layout/ajax-loader.gif',
            //parameter for an ajax-request for content,
            parameter: "",
            //save the activated tab in a cookie?
            //name will be the id of contentTarget, value will be the id of the tab
            saveActiveTab: false,
            //execute this funtion upon successfully loading all tabs
            onTabsLoaded: null,
            //execute this funtion every time a tab is changed
            onChange: null
        };
        this.options = Object.extend(defaults, arguments[1] || {});
        //no tabs given
        if (this.options.tabList.length == 0) {
            alert("No tabs to click on given");
            return false
        }

        //store content-element as a prototype extended element
        this.contentTarget = $(contentTarget);
        //bind the function that will be called when a tab is clicked
        this.eventClick = this.clickOnTab.bindAsEventListener(this);

        //go through all given tabs and check that they exists and, if they do, observe them for clicks
        for (var i=0; i<this.options.tabList.length; ++i) {
            var tab = this.options.tabList[i];
            var tmpElement = $(tab.id);
            if (!tmpElement) {
                alert(tab.id + " is not a valid element");
                return false;
            } else if (tab.doNotActivate != true) {
                Event.observe(tab.id, "click", this.eventClick);
                if (this.options.classNameMouseover != "") {
                    //check for mouseovers and add a css-class to the tab
                    Event.observe(tab.id, "mouseover", function (e) {
                        var tmpElement = Event.element(e);
                        //only give the mouseover-class to an element if it is not selected
                        if (!tmpElement.hasClassName(this.options.classNameSelected)) {
                            tmpElement.addClassName(this.options.classNameMouseover);
                        }
                    }.bind(this));
                    //check for mouseouts and remove a css-class from the tab
                    Event.observe(tab.id, "mouseout", function (e) {
                        var tmpElement = Event.element(e);
                        tmpElement.removeClassName(this.options.classNameMouseover);
                    }.bind(this));
                }
            }
        }

        //call callback
        if (this.options.onTabsLoaded != null) {
            this.options.onTabsLoaded();
        }
    },

    //function for a click on a tab
    clickOnTab: function(e) {
        //get the clicked tab
        var element = $(Event.findElement(e, 'div'));
        if (element.hasClassName(this.options.classNameSelected)) {
            //the currently active tab was clicked, nothing to do
            return false;
        } else {
            //some tab, not the current one, was clicked. go through all known tabs
            this.focusTab(element);
        }
    },

    focusTab: function(element) {
        element = $(element);

        for (var i=0; i<this.options.tabList.length; ++i) {
            var tab = this.options.tabList[i];
            if ($(tab.id).hasClassName('selected')) {
                var saveTo = tab.src;
            }
        }

        for (var i=0; i<this.options.tabList.length; ++i) {
            //get the tab-element
            var tab = this.options.tabList[i];
            var tmpElement = $(tab.id);

            //this tap was clicked
            if ((tab.id == element.id) && (tab.doNotActivate != true)) {
                var srcElement = $(tab.src);

                //activate it
                tmpElement.addClassName(this.options.classNameSelected);
                tmpElement.removeClassName(this.options.classNameDeselected);
                //remove mouseover-class (it looks more responsive)
                tmpElement.removeClassName(this.options.classNameMouseover);

                //Check if the activation should be saved
                //Idiotic smarty can not work with '-' in array indicies, so
                //replace them with an underscore
                if (this.options.saveActiveTab) {
                    Cookie.set(this.contentTarget.id.replace(/-/g, "_"), tmpElement.id.replace(/-/g, "_"), 14);
                }

                //See if the content needs to be reverted
                var saveToElement = $(saveTo);
                if (saveToElement) {
                    var tmpHTML = this.contentTarget.innerHTML;
                    this.contentTarget.innerHTML = '';
                    saveToElement.innerHTML = tmpHTML;
                }

                //see if the content is in the html, if it is, show it
                if (srcElement) {
                    var srcHTML = srcElement.innerHTML;
                    srcElement.innerHTML = '';
                    this.contentTarget.innerHTML = srcHTML;
                } else {
                    //assign the loading class to the content
                    this.contentTarget.addClassName(this.options.classNameLoading);
                    //check wether to replace content or not
                    if (this.options.replaceContentWhileLoading) {
                        this.contentTarget.update('<img src="' + this.options.replaceImage + '" />');
                    }
                    //the content has to be loaded with ajax.
                    new Ajax.Request(tab.src, {
                        parameters: tab.parameter,
                        method: 'post',
                        //bind the function so "this" is accessible
                        onComplete: function (transport) {
                            this.contentTarget.removeClassName(this.options.classNameLoading);
                            this.contentTarget.innerHTML = transport.responseText;
                            transport.responseText.evalScripts();
                        }.bind(this)
                    });
                }
            } else {
                //this tab was not clicked. deactivate it
                tmpElement.addClassName(this.options.classNameDeselected);
                tmpElement.removeClassName(this.options.classNameSelected);
            }
        }

        //call callback
        if (this.options.onChange != null) {
            this.options.onChange(element);
        }
    },

    switchToTab: function(tabId) {
        this.focusTab(tabId);
    },

    loadContent: function(url) {

        if (typeof arguments[1] != "undefined") {
            var parameter = arguments[1];
        } else {
            var parameter = "";
        }

        this.contentTarget.addClassName(this.options.classNameLoading);
        new Ajax.Request(url, {
            parameters: parameter,
            method: 'post',
            //bind the function so "this" is accessible
            onComplete: function (transport) {
                this.contentTarget.removeClassName(this.options.classNameLoading);
                this.contentTarget.innerHTML = transport.responseText;
            }.bind(this)
        });
    }
}