/**
 * display block with tween transition
 *
 * @author slemoigne@agenceinteractive.com
 *
 * @version 1.0 - 2009-03-02
 *
 * Use mootools 1.2
 */

var TweenTab = new Class({
	
	Implements: [Events, Options],
	
	/**
	 * Options
	 *
	 */
	options : {
		alternate : false,
		changeEvent: {
			link : 'click',
			arrow : 'click'
		},
		cssSelector: {
			link : '.link',
			block : '.block'
		},
		element: {
			blockPrefix : 'TweenTab',
			linkPrefix	: 'TweenTabLink'
		},
		move : {
			display		: false,
			property	: 'height',
			from		: '0',
			to			: '200',
			duration	: 500,
			transition	: Fx.Transitions.Sine.easeOut
		},
		status : {
			on 			: 'arrow_display',
			off 		: 'arrow_hide'
		},
		
		activeLink: function(sId) {
			if ($(sId))
			{
				$(sId).src = $(sId).src.replace('_on', '_active');
				$(sId).src = $(sId).src.replace('_off', '_active');
			}
		},
		disableLink: function(sId) {
			if ($(sId))
				$(sId).src = $(sId).src.replace('_active', '_off');
		}
	},
	
	/**
	 * Constructor
	 *
	 */
	initialize: function(sLinkContainerCss, sBlockContainerCss, sIdStatus, options) {
		this.sLinkContainerCss = sLinkContainerCss;
		this.sBlockContainerCss = sBlockContainerCss;
		
		this.sIdStatus = sIdStatus;
		
		this.sCurrentId = null; //stocke l'id de l'element en cours / affiché
		this.sLastId = null; //stocke l'id du dernier element
		
		this.bChangeElement = true; //donne l'autorisation d'ouvrir un nouveau menu
		this.bOpen = false; //indique si un block est deja ouvert
	
		this.setOptions(options);
		
		this.initElement();
		
		this.initEvent();
	},
	
	/**
	 * Destroy - unset var and remove event
	 *
	 */
	destroy: function() {
		$$(this.sLinkContainerCss + ' ' + this.options.cssSelector.link).removeEvents();
		$(this.sIdStatus).removeEvent(this.options.changeEvent.arrow);
	
		this.sLinkContainerCss = null;
		this.sBlockContainerCss = null;
		this.sIdStatus = null;
		this.sCurrentId = null;
		this.sLastId = null;
		this.bChangeElement = null;
		this.bOpen = null;
		this.options = null;
	},
	
	/**
	 * InitElement - add id on element
	 *
	 */
	initElement: function() {
		var i = 0;
		
		$$(this.sLinkContainerCss + ' ' + this.options.cssSelector.link).each(function(el){
			el.id = this.options.element.linkPrefix + i;
			i++;
		}.bind(this));

		i = 0;

		$$(this.sBlockContainerCss + ' ' + this.options.cssSelector.block).each(function(el){
			el.id = this.options.element.blockPrefix + i;
			i++;
		}.bind(this));
	},
	
	/**
	 * Init event - add event on element
	 *
	 */
	initEvent: function() {
	
		$$(this.sLinkContainerCss + ' ' + this.options.cssSelector.link).each(function(el){
			el.addEvent(this.options.changeEvent.link, function(e){
				//extract id without prefix
				sId = el.id.replace(this.options.element.linkPrefix, '');
				this.clickElement(sId);
				this.changeElement(sId);
			}.bind(this));
		}.bind(this));
		
		if ( $(this.sIdStatus) )
		{
			$(this.sIdStatus).addEvent(this.options.changeEvent.arrow, function(e){
				//block ouvert
				if ( this.bOpen )
					this.hideCurrentElement();
				else
					this.displayLastElement();
			}.bind(this));
		}
		
	},
	
	/**
	 * Change element
	 *
	 * @param string - id of element to display without prefix
	 */
	changeElement: function(sId) {
		//change d'element s'il est différent de celui en cours et si une animation n'est pas en train de jouer
		if ( this.sCurrentId != sId && this.bChangeElement && $(this.options.element.blockPrefix + sId))
		{
			this.bChangeElement = false;
			
			this.options.activeLink(this.options.element.linkPrefix + sId);
			
			if ( this.sCurrentId != null )
			{
				this.hideCurrentElement();
				
				if ( this.options.move.display )
					this.displayElement(sId);
				else
					this.displayElement.delay(this.options.move.duration, this, sId);
			}
			else
			{
				this.displayElement(sId);
			}
		}
		//cas ou on clique sur l'element deja sélectionné
		else if ( this.bChangeElement && this.options.alternate )
		{
			if ( this.bOpen )
				this.hideCurrentElement();
			else
				this.displayLastElement();
		}
	},
	
	/**
	 * Display element
	 *
	 * @param string - id of element to display without prefix
	 */
	displayElement: function(sId) {
		this.sCurrentId = sId;
		
		this.options.activeLink(this.options.element.linkPrefix + sId);
		
		if ( $(this.sIdStatus) )
		{
			$(this.sIdStatus).removeClass(this.options.status.off);
			$(this.sIdStatus).addClass(this.options.status.on);
		}
		
		this.bOpen = true;
		
		if ( this.options.move.display )
		{
			if ($(this.options.element.blockPrefix + sId))
				$(this.options.element.blockPrefix + sId).setStyle('display','block');
			this.bChangeElement = true;
			this.displayComplete();
		}
		else
		{
			var oFx = new Fx.Tween(
				$(this.options.element.blockPrefix + sId),
				{
					wait : false, 
					transition : this.options.move.transition,
					duration : this.options.move.duration,
					onComplete: function(){
						this.bChangeElement = true;
						this.displayComplete();
					}.bind(this)
				}
			);
			oFx.start(
				this.options.move.property,
				this.options.move.from,
				this.options.move.to
			);
		}
		
	},
	
	/**
	 * Hide element
	 *
	 * @param string - id of element to hide without prefix
	 */
	hideElement: function(sId) {
	
		this.sLastId = this.sCurrentId;
		this.sCurrentId = null;
	
		this.options.disableLink(this.options.element.linkPrefix + sId);
		
		if ( $(this.sIdStatus) )
		{
			$(this.sIdStatus).removeClass(this.options.status.on);
			$(this.sIdStatus).addClass(this.options.status.off);
		}
		
		this.bOpen = false;
		
		if ( this.options.move.display )
		{
			if ($(this.options.element.blockPrefix + sId))
			{
				$(this.options.element.blockPrefix + sId).setStyle('display','none');
				this.hideComplete();
			}
		}
		else
		{
			var oFx = new Fx.Tween(
				$(this.options.element.blockPrefix + sId),
				{
					wait : false, 
					transition : this.options.move.transition,
					duration : this.options.move.duration,
					onComplete: function(){
						this.hideComplete();
					}.bind(this)
				}
			);
			oFx.start(
				this.options.move.property,
				this.options.move.to,
				this.options.move.from
			);
		}
		
	},
	
	/**
	 * Hide current element
	 *
	 */
	hideCurrentElement: function() {
		if ( this.sCurrentId != null )
			this.hideElement(this.sCurrentId);
		else
			this.hideComplete();
	},
	
	/**
	 * Display last element
	 *
	 */
	displayLastElement: function() {
		if ( this.sLastId != null )
			this.displayElement(this.sLastId);
		else
			this.displayComplete();
	},
	
	/**
	 * getSCurrentId
	 *
	 * @return string
	 */
	getSCurrentId: function() {
		return this.sCurrentId;
	},
	
	/**
	 * getBOpen
	 *
	 * @return bool
	 */
	getBOpen: function() {
		return this.bOpen;
	},
	
	/**
	 * EVENT
	 *
	 */
	hideComplete: function() {
		this.fireEvent('hideComplete');
	},
	
	displayComplete: function() {
		this.fireEvent('displayComplete');
	},
	
	clickElement: function(sId) {
		this.fireEvent('clickElement', sId);
	}
	
});
