/**
 * Permet de rendre un menu en effet "tab".
 * 
 * @param {Object} container
 * @param {Object} options
 */
var tabbize = Class.create({
	initialize: function( container, options ){
		this.container = $( container );
		this.options = Object.extend({
			tag			: 'li',			// Nom des tag enfants
			treeTag		: 'ul',			// Nom du tag container
			selectFirstElement:	false,	// Sélection automatique du 1er élement
			selectClass	: 'select',		// Nom de la class
			multipleSelect: false,		// Possibilité de sélectionner plusieurs onglets
			toggleSelect: false,		// Effect de sélection/désélection
			
			init		: null,			// Fonction utilisateur d'initialisation
			
			/**
			 * @TODO:
			 */
			dontObserve	: [],			// Tableau des éléments de la nav à ne pas observer
			
			beforeClick	: null,			// Fonction utilisateur a appeler avant le click
			onClick		: null			// Fonction utilisateur a appeler lors du click
		}, options || {});
		
		// Récupère tous les enfants du container
		this.childrens = Element.findChildren( this.container, false, false, this.options.tag);
				
		// Initialisation
		if( null !== this.options.init ) {
			this.options.init( this.childrens, this );
		}
		
		// Observateur
		this.childrens.each( function( e ){
			if (false === this._isDontObserved(e)) {
				e.observe('click', this.clicked.bindAsEventListener(this));
			}
		}.bind(this));
				
		// 1er élement ?
		if( this.options.selectFirstElement ) {
			this.clicked( this.childrens[0] );
		}		
	},
	
	/**
	 * Fonction privée appelée lors d'un clic sur un élement
	 * 
	 * @param {Object} element
	 */
	clicked: function( e )
	{
        if( true === e instanceof Element ) {
			var element = e;
		} else {
			var element = Event.findElement( e, 'li' );
			e.stop();
        }
		
		element = $( element );
				
		if( this.options.beforeClick) {
			this.options.beforeClick( element, this.getStateElement( element ) , this );
		}
		
		if (false === this.options.multipleSelect) {
			var options = this.options;
			this.childrens.each(function(e){
				if (e.hasClassName(options.selectClass)) {
					e.removeClassName(options.selectClass);
				}
			});
		}
		
		if (element.hasClassName(this.options.selectClass) && this.options.toggleSelect) {
			element.removeClassName(this.options.selectClass);
		}
		else {
			element.addClassName(this.options.selectClass);
		}
		
		if( this.options.onClick) {
			this.options.onClick( element, this.getStateElement( element ) , this );
		}
	},
	
	/**
	 * Permet de savoir l'état de l'élément element
	 * 
	 * @param {Object} element
	 * @return {Bool} returne 0 si l'élement n'est pas sélectionné, sinon, retourne 1.
	 */
	getStateElement: function( element )
	{
        var state = 1;
		
		if ($(element).hasClassName(this.options.selectClass) && this.options.toggleSelect) {
			state = 0;
		}
		
		return state;
	},
	
	/**
	 * Récupère tous les éléments en état 1
	 */
	getElementsHasOn: function()
	{
		var elements = [];
		
		var options = this.options;
		this.childrens.each(function(e){
				if ($(e).hasClassName(this.options.selectClass)) {
					elements.push( $(e) );
				}
			}.bind(this));
		return elements;
	},
	
	/**
	 * Vérifie si l'élément element est enregistré pour ne pas être observé
	 * 
	 * @param {Object} element
	 * @return {Boolean} Return TRUE si element est enregistré pour ne pas être observé, sinon retourne FALSE
	 */
	_isDontObserved: function( element )
	{
		var retour = false;		
		this.options.dontObserve.each( function( el ){
			if( $(el) === $(element) ) {
				$(element).addClassName( 'dontObserved' );
				retour = true;
			}
		});
		return retour;
	}
});

/**
 * voir Scriptaculous::dragdrop
 * 
 * @param {Object} element
 * @param {Object} only
 * @param {Object} recursive
 * @param {Object} tagName
 */
Element.findChildren = function(element, only, recursive, tagName) {   
	if (!element.hasChildNodes()) {
		return null;
	}
	
	tagName = tagName.toUpperCase();
	
	if (only) {
		only = [only].flatten();
	}
	
	var elements = [];
	$A(element.childNodes).each( function(e) {
		if (e.tagName && e.tagName.toUpperCase() == tagName && (!only || (Element.classNames(e).detect(function(v) { return only.include(v);})))) {
			elements.push(e);
		}
		if(recursive) {
			var grandchildren = Element.findChildren(e, only, recursive, tagName);
			if (grandchildren) {
				elements.push(grandchildren);
			}
		}
	});
	
	return (elements.length>0 ? elements.flatten() : []);
};
