/*
	Filename: tabs.js
	
	[Description]
		Contains the Tabs Class to create professional tab-based interfaces.
	[/Description]
	
	Contains: Class Tabs
	
	[Summary]
		Tabs ::: Custom Class for creating tab-based interfaces 
	[/Summary]
*/
/*
	Class: Tabs
	
	[Description] 
		Allows to create professional tab-based interfaces with many additional controls, like the scrolling effect,
		the autoresizing, the opening tab and more. Note that in the Tabs namespacing, the 'tabs' represent
		the contents while the 'sections' represent the handlers (the list items).
	[/Description]
	
	Extends: 
	
	Constructor: new Tabs(element, options)
	
	[Properties] 
		element - the container element
		options - the Tabs options. See below
	[/Properties]
	
	[Options]
		effect : the transition effect used to change the tabs. Can be 'scroll' or 'fix'
		autoresize : if true the tabs will be autoresized. Default is true.
		scrollOptions : the additional Fx.Scroll options
		opening : the tab which will be activated at first. Default is 0.
		openingEffect : the opening effect, 'scroll' or 'fix' (default). Can be different from the 'effect' option.
		names : an object containing the class names of the sections represent the Tabs interface. See below.
	[/Options]
	
	>> names:
	[List]
		[li] wrapper: the class name of the wrapper which contains the tabs. Default is 'tabs'
		[li] sections: the class name of the list element that contains the sections. Deafukt is 'sections'
		[li] tab: the class name of the elements represent the tabs. Default is 'tab'
	[/List]

    [Events]
		onOpen : function fired if the 'opening' option is a number represents a tab. The tab element and its position will be passed as arguments.
		onChange : function fired when an user changes to another tab. The tab element, the section and the tab position will be passed as arguments.
	[/Events]
	
	[Example]
		> var tabs = new Tabs('main', {
		>	autoresize: false,
		>	opening: 2,
		>	openingEffect: 'scroll',
		>	effect: 'fix',
		>	onChange: function(tab, section, i) {
		>		this.sections.removeClass('active');
		>		section.addClass('active');
		>	}
		> });
	[/Example]
*/
var Tabs = new Class({
	
	Implements: [Events, Options],
	
	options: {
		effect: 'scroll',
		autoresize: true,
		names: {
			wrapper: 'tabs',
			sections: 'sections',
			tab: 'tab'
		},
		scrollOptions: {},
		onChange: $empty,
		onOpen: $empty,
		opening: 0,
		openingEffect: 'fix'
	},
	
	initialize: function(element, options) {
		this.main = $(element);
		this.setOptions(options);
		this.wrapper = this.main.getElement('.' + this.options.names.wrapper);
		this.sections = this.main.getElement('ul.' + this.options.names.sections).getElements('li');
		this.tabs = this.wrapper.getElements('.' + this.options.names.tab);
		
		this.wrapper.setStyles({'overflow': 'hidden'});
		
		this.tabs.each(function(tab, i) {
			tab.store('height', tab.getHeight());
		}, this);
		
		this.fx = new Fx.Scroll(this.wrapper, this.options.scrollOptions);
		
		if($int(this.options.opening) && this.sections[this.options.opening]) { 
			this.goTo(this.sections[this.options.opening], this.options.opening, this.options.openingEffect);
			this.fireEvent('onOpen', [this.sections[this.options.opening], this.options.opening]);	
		}
		
		this.sections.each(function(section, i) {
			section.addEvent('click', this.goTo.bind(this, [section, i]));
		}, this);
	},
	
	goTo: function(section, i, effect) {
		var tab = this.tabs[i], height = tab.retrieve('height'), count = i, method = false, eff = this.options.effect;
		
		if(effect) this.options.effect = effect;
		
		if(eff == 'scroll' && !this.fx.timer)
			method = 'start';
		else if(eff == 'fix')
			method = 'set';
		
		if(method) {
			this.fireEvent('onChange', [tab, section, count]);
			if(this.options.autoresize) $$(this.wrapper, tab).setStyle('height', height);
			this.fx[method](0, tab.getPosition(this.wrapper).y.toInt());
		}
		
		if(effect)	this.options.effect = eff;
	}

});