/**
 * @author Ryan Johnson <http://saucytiger.com/>
 * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
 * @package LivePipe UI
 * @license MIT
 * @url http://livepipe.net/control/tabs
 * @require prototype.js, livepipe.js
 */

if(typeof(Prototype) == "undefined")
	throw "Control.Tabs requires Prototype to be loaded.";
if(typeof(Object.Event) == "undefined")
	throw "Control.Tabs requires Object.Event to be loaded.";

Control.Tabs = Class.create({
    initialize: function(tab_list_container, options) {

        if (!$(tab_list_container))
            throw "Control.Tabs could not find the element: " + tab_list_container;
        this.activeContainer = false;
        this.activeLink = false;
        this.containers = $H({});
        this.links = [];
        Control.Tabs.instances.push(this);
        this.options = {
            beforeChange: Prototype.emptyFunction,
            afterChange: Prototype.emptyFunction,
            hover: false,
            linkSelector: 'li a',
            setClassOnContainer: false,
            activeClassName: 'active',
            defaultTab: 'first',
            autoLinkExternal: true,
            targetRegExp: /#(.+)$/,
            showFunction: Element.show,
            hideFunction: Element.hide
        };
        Object.extend(this.options, options || {});
        (typeof (this.options.linkSelector == 'string')
			? $(tab_list_container).select(this.options.linkSelector)
			: this.options.linkSelector($(tab_list_container))
		).findAll(function(link) {
		    //return (/^#/).exec(link.href.replace(window.location.href.split('#')[0], ''));
		    // HACK TO FIX BASE URL PROBLEM
		    var url = link.href;
		    if (url.indexOf("#") != 0) {
		        url = url.substring(url.indexOf("#"), url.length);
		    }
		    return (/^#/).exec(url);
		}).each(function(link) {
		    this.addTab(link);
		} .bind(this));
        this.containers.values().each(Element.hide);
        if (this.options.defaultTab == 'first')
            this.setActiveTab(this.links.first());
        else if (this.options.defaultTab == 'last')
            this.setActiveTab(this.links.last());
        else
            this.setActiveTab(this.options.defaultTab);
        var targets = this.options.targetRegExp.exec(window.location);
        if (targets && targets[1]) {
            targets[1].split(',').each(function(target) {
                this.setActiveTab(this.links.find(function(link) {
                    return link.key == target;
                }));
            } .bind(this));
        }
        if (this.options.autoLinkExternal) {
            $A(document.getElementsByTagName('a')).each(function(a) {
                if (!this.links.include(a)) {
                    var clean_href = a.href.replace(window.location.href.split('#')[0], '');
                    if (clean_href.substring(0, 1) == '#') {
                        if (this.containers.keys().include(clean_href.substring(1))) {
                            $(a).observe('click', function(event, clean_href) {
                                this.setActiveTab(clean_href.substring(1));
                            } .bindAsEventListener(this, clean_href));
                        }
                    }
                }
            } .bind(this));
        }
    },
    addTab: function(link) {
        this.links.push(link);
        
        // HACK to FIX BASE URL ISSUE
        var url = link.href;
        if (url.indexOf("#") != 0) {
            url = url.substring(url.indexOf("#"), url.length).replace('#', '');
        }
        link.key = url; // link.getAttribute('href').replace(window.location.href.split('#')[0], '').split('/').last().replace(/#/, '');
        var container = $(link.key);
        if (!container)
            throw "Control.Tabs: #" + link.key + " was not found on the page."
        this.containers.set(link.key, container);
        link[this.options.hover ? 'onmouseover' : 'onclick'] = function(link) {
            if (window.event)
                Event.stop(window.event);
            this.setActiveTab(link);
            return false;
        } .bind(this, link);
    },
    setActiveTab: function(link) {
        if (!link && typeof (link) == 'undefined')
            return;
        if (typeof (link) == 'string') {
            this.setActiveTab(this.links.find(function(_link) {
                return _link.key == link;
            }));
        } else if (typeof (link) == 'number') {
            this.setActiveTab(this.links[link]);
        } else {
            if (this.notify('beforeChange', this.activeContainer, this.containers.get(link.key)) === false)
                return;
            if (this.activeContainer)
                this.options.hideFunction(this.activeContainer);
            this.links.each(function(item) {
                (this.options.setClassOnContainer ? $(item.parentNode) : item).removeClassName(this.options.activeClassName);
            } .bind(this));
            (this.options.setClassOnContainer ? $(link.parentNode) : link).addClassName(this.options.activeClassName);
            this.activeContainer = this.containers.get(link.key);
            this.activeLink = link;
            this.options.showFunction(this.containers.get(link.key));
            this.notify('afterChange', this.containers.get(link.key));
        }
    },
    next: function() {
        this.links.each(function(link, i) {
            if (this.activeLink == link && this.links[i + 1]) {
                this.setActiveTab(this.links[i + 1]);
                throw $break;
            }
        } .bind(this));
    },
    previous: function() {
        this.links.each(function(link, i) {
            if (this.activeLink == link && this.links[i - 1]) {
                this.setActiveTab(this.links[i - 1]);
                throw $break;
            }
        } .bind(this));
    },
    first: function() {
        this.setActiveTab(this.links.first());
    },
    last: function() {
        this.setActiveTab(this.links.last());
    }
});
Object.extend(Control.Tabs,{
	instances: [],
	findByTabId: function(id){
		return Control.Tabs.instances.find(function(tab){
			return tab.links.find(function(link){
				return link.key == id;
			});
		});
	}
});
Object.Event.extend(Control.Tabs);