/*
 * Gx.Tabpanel
 */

Gx.Tabpanel = new Class({
	Implements: [Chain, Events, Options],
	//Extends: Container.Widget,
	options: {
		//
		onWaitSelect: $empty,
		//
		onInitSelect: $empty,
		//
		onPrfxSelect: $empty,
		//
		onPofxSelect: $empty,
		
		waitSelect: {},
		initSelect: {},
		prfxSelect: {},
		pofxSelect: {},
	
		//
		transition: Fx.Transitions.Linear,
		duration: 300
	},
	initialize: function(container, options) {
		this.setOptions(options);
		this.container = $(container);
		this.tab = this.container.getElements('div.tab');
		this.panel = this.container.getElements('div.panel').setOpacity(0);
		this.tabcontent = this.container.getElement('div.tabcontent');
		
		// 
		this.index = null;
		
		// If an index is in the table below, so if the 
		// panel has already been selected at least once
		this.already = [];

		// Create options 'Hash' for the properties wait, init, prfx and pofx
		['wait', 'init', 'prfx', 'pofx'].each(function(p) {
			this.options[p + 'Select'] = new Hash(this.options[p + 'Select']);
		}, this);

		// Add events to the buttons tab
		this.tab.each(function(element, index) {
			new Gx.Button.Simple(element).addEvent('click', this.click.bind(this, index));
		}, this);

		// Create a new fact with currently no element
		this.fx = new Fx.Elements(null, {
			transition: this.options.transition,
			duration: this.options.duration,
			link: 'cancel'
		});
	},
	click: function(index) {
		this.select(index);
	},
	setNone: function() {
		this.panel.each(function(panel) {
			if (panel != this.panel[this.index])
				panel.setNone();
		}, this);
	},
	/*
	 *
	 */
	call: function(type) {
		this.fireEvent(type, this.index);
		
		if ($type(fn = this.options[type].get(this.index)) == 'function') {
			fn.bind(this)();
			return this;
		}

		return false;
	},
	/* 
	 *
	 */
	change: function() {
		// Deselect all and select the current tab (to replace toggle button)
		if (this.tab.length) {
			this.tab.each(function(tab) { tab.removeClass('selected'); });
			this.tab[this.index].addClass('selected');
		}
		
		// Send pre fx event
		this.call('prfxSelect');

		// Preparing for animation
		var elements = [this.tabcontent, this.panel[this.index]],
			height = this.panel[this.index].getSize().y;
			effect = {0: {'height': height}, 1: {'opacity': 1}};

		// If the value of initialization and go or the browser is IE
		if (this.initialize || Browser.Engine.trident) {
			this.already.push(this.index);
			this.tabcontent.setStyle('height', height);
			this.panel[this.index].setOpacity(1);
			this.call('pofxSelect');
			this.setNone();
		// Start animation
		} else {
			// If a tab is already selected
			this.panel.each(function(panel) {
				if (panel.getOpacity() != 1)
					return;
				
				elements.push(panel);
				effect[2] = {'opacity': 0};
			}, this);

			// Show tab with an opacity
			this.fx.elements = elements;
			this.fx.start(effect).chain((function() {
				this.call('pofxSelect');
				this.setNone();
			}).bind(this));
		}
	},
	/*
	 *
	 */
	select: function(index, initialize) {
		// If index is greater than the number of panel 
		// or smaller than zero and yet already selected
		if (!(index < this.panel.length || index > 0) || this.index == index)
			return this;

		// 
		this.initialize = initialize || false;
		
		// Update the index, we no longer need the above
		this.index = index;
		
		// Show panel
		this.panel.setBlock();
		
		// 
		if (!this.already.contains(this.index)) {
			this.call('initSelect');
 			this.already.push(this.index);
		}

		//
		if (fn = this.call('waitSelect')) {
			fn.chain((function() {
				this.change();
			}).bind(this));
		} else {
			this.change();
		}
	
		return this;
	}
});
