var Fabtabs = Class.create();
Fabtabs.prototype = {
	periodicalExecuter : 0,
	initialize : function(element) {
		this.element = $(element);
		this.hasEffectLib = String.prototype.parseColor != null;
		this.state = "idle";
		this.options = Object.extend({
			showEffect: null,
			hideEffect: null,
			showEffectOptions: {},
			hideEffectOptions: {},
			rotate: false,
			rotateInterval: 5.0
		}, arguments[1] || {});
		this.toc = $A($(element).getElementsByTagName('a') );
		this.menu = this.toc.findAll(function(item) {
			return $(item).rel == "bookmark";
		});
		this.previousControl = this.toc.detect(function(item) {
			return $(item).rel == "previous";
		});
		this.nextControl = this.toc.detect(function(item) {
			return $(item).rel == "next";
		});;
		this.show(this.getInitialTab());
		this.menu.each(this.setupTab.bind(this));
		if (this.options.rotate) {
			Event.observe(this.previousControl, 'click', this.previous.bindAsEventListener(this), false);
			Event.observe(this.nextControl, 'click', this.next.bindAsEventListener(this), false);
			this.periodicalExecuter = new ExtendedPeriodicalExecuter(this.doSlideshow.bind(this), this.options.rotateInterval * 1000, 'rotateTimer');
			this.start();
		}
	},
	
	setupTab : function(elm) {
		Event.observe(elm, 'click', this.activate.bindAsEventListener(this), false)
	},
	
	activate : function(evt) {
		var elm = Event.findElement(evt, "a");
		Event.stop(evt);
		if (this.periodicalExecuter) {
			this.pause();
		}
		if (this.state != "running") {
			this.show(elm);
			this.menu.without(elm).each(this.hide.bind(this) );
		}
	},
	
	hide : function(elm) {
		$(elm).removeClassName('active-tab');
		if (this.options.hideEffect) {
			$(this.tabID(elm)).visualEffect(this.options.hideEffect, this.options.hideEffectOptions);
		} else {
			$(this.tabID(elm)).removeClassName('active-tab-body');
		}
    },

	show : function(elm) {
		this.indexPosition = (this.menu.indexOf(elm) );
		$(elm).addClassName('active-tab');
		$(this.tabID(elm)).addClassName('active-tab-body');
		if (this.options.showEffect) {
			$(this.tabID(elm)).visualEffect(this.options.showEffect, { beforeStart: this.runningState.bind(this), afterFinish: this.idleState.bind(this) } );
		}
	},
	
	/* Slideshow Rotate */
	doSlideshow : function() {
		var nextTab = (this.menu[this.indexPosition + 1]) ? this.menu[this.indexPosition + 1] : this.menu.first();
		this.show(nextTab);
		this.menu.without(nextTab).each(this.hide.bind(this) );
	},
	
	previous : function(evt) {
		Event.stop(evt);
		this.pause();
		var previousHref = (this.menu[this.indexPosition - 1]) ? this.menu[this.indexPosition - 1] : this.menu.first();
		this.previousControl.href = previousHref;
		if (this.state != "running") {
			this.show(previousHref);
			this.menu.without(previousHref).each(this.hide.bind(this) );
		}
	},
	
	next : function(evt) {
		Event.stop(evt);
		this.pause();
		var nextHref = (this.menu[this.indexPosition + 1]) ? this.menu[this.indexPosition + 1] : this.menu.last();
		this.nextControl.href = nextHref;
		if (this.state != "running") {
			this.show(nextHref);
			this.menu.without(nextHref).each(this.hide.bind(this) );
		}
	},
	
	/* Slideshow Timer Controllers */
	start : function() {
		this.periodicalExecuter.start();
	},
	stop : function() {		
		this.periodicalExecuter.stop();
	},
	pause : function() {
		this.periodicalExecuter.pause();
	},
	resume : function() {
		this.periodicalExecuter.resume();
	},

	/* Effect State Management */
	idleState : function() {
		this.state = "idle";
	},
	
	runningState : function() {
		this.state = "running";
	},

	tabID : function(elm) {
		return elm.href.match(/#(\w.+)/)[1];
	},

	getInitialTab : function() {
		if (document.location.href.match(/#(\w.+)/)) {
			var loc = RegExp.$1;
			var elm = this.menu.find(function(value) { return value.href.match(/#(\w.+)/)[1] == loc; });
			return elm || this.menu.first();
		} else {
			return this.menu.first();
		}
	}
}