/**
 * Necessary HTML structure:
 *	<div class="ifader">
 *
 *		<!-- optional -->
 *		<ul class="ifader-nav">
 *			<li><a href="#">nav item</a></li>
 *			<li><a href="#">nav item</a></li>
 *		</ul>
 *
 *		<!-- optional -->
 *		<a href="#" class="js-ifader-previous">previous</a>
 *		<a href="#" class="js-ifader-next">next</a>
 *
 *		<div class="ifader-item">content</div>
 *		<div class="ifader-item">content</div>
 *	</div>
 *
 * @version		1.1
 * @date		2011-03-29
 * @copyright	2011 iWink BV
 * @author		Timo Schinkel
 */
var iFader = Class.create({

	container	: null,
	items 		: [],
	links		: [],
	active 		: 0,
	pe			: null,
	options		: {
		timer		: 8,
		animation	: {
			enabled		: true,
			duration	: 1.0
		}
	} ,

	/**
	 * Creates a new instance of iFader
	 * @param	{Element}	container
	 * @param	{Object}	options
	 */
	initialize : function ( container , options ) {

		this.container	= container;
		this.items		= this.container.select('.js-ifader-item');
		if ( this.container.down('ul.js-ifader-nav') )
			this.links	= this.container.down('ul.js-ifader-nav').select('a');

		if ( options )	Object.extend( this.options , options );

		if ( this.items.size() > 1 ) {
			this._selectActiveItems();
			this.startPeriodicalExecutor();
			this.addObservers();
		}
	},

	/**
	 * Searches for already marked as active items
	 */
	_selectActiveItems		: function () {
		if ( this.container.down('ul.js-ifader-nav a.js-ifader-active' ) )	//	Er is een actieve link gevonden, dan gaan we daar verder
			this.active	= this.links.indexOf( this.container.down('ul.js-ifader-nav a.js-ifader-active' ) );
		this.items[this.active].setStyle({zIndex: '1'});
		if ( this.links[this.active] )
			this.links[this.active].addClassName( 'js-ifader-active' );
	} ,

	/**
	 * Starts the PeriodicalExecutor, if a PeriodicalExecuter already exists, it is stopped first
	 */
	startPeriodicalExecutor : function () {
		if ( this.pe )
			this.pe.stop ();
		if ( this.options.timer )
			this.pe 	= new PeriodicalExecuter( function(pe) {this.next();}.bind(this) , this.options.timer );
	},

	/**
	 * Adds the observers to the different elements
	 */
	addObservers : function () {
		this.links.each( function( a ) {
			a.observe( 'click' , this.linkClicked.bind(this) );
		}.bind(this));
		if ( this.container.down( '.js-ifader-next' ) )
			this.container.down( '.js-ifader-next' ).observe( 'click' , this.next.bind(this) );
		if ( this.container.down( '.js-ifader-prev' ) )
			this.container.down( '.js-ifader-prev' ).observe( 'click' , this.previous.bind(this) );
	},

	/**
	 * @param	{Event}	event
	 */
	linkClicked : function ( event ) {
		if ( event )
			event.stop();

		var a	= event.findElement('a');

		for( i = 0 ; i < this.links.size() ; i++ ) {
			if ( a == this.links[i] && i != this.active ) {
				this.goToIndex(i);
				if ( this.pe ) {
					this.pe.stop();
					this.startPeriodicalExecutor();
				}
			}
		}

	},

	/**
	 * @param	{Event}	event
	 */
	next		: function ( event ) {
		try {
			event.stop ();
		} catch ( err ) {}
		var next	= ( this.active + 1 ) % this.items.size();
		this.goToIndex( next );
		this.startPeriodicalExecutor();
	} ,

	/**
	 * @param	{Event}	event
	 */
	previous	: function ( event ) {
		try {
			event.stop ();
		} catch ( err ) {}
		var prev	= ( this.active - 1 + this.items.size() ) % this.items.size();
		this.goToIndex( prev );
		this.startPeriodicalExecutor();
	} ,

	/**
	 * @param	{Integer}	index
	 */
	goToIndex : function( index ) {
		//	Fade-out, fade-in:
		for( i = 0 ; i < this.items.size() ; i++ )						//	Alle items, die niet active zijn helemaal naar achter!
			if ( i != this.active )
				this.items[i].setStyle({zIndex: '0'});
		this.items[this.active].setStyle({zIndex: '1'});				//	active naar achter plaatsen:
		this.items[index].setStyle({zIndex: '2' , opacity: '0.0'});		//	volgende naar voren plaatsen:

		if ( this.options.animation.enabled )
			this.items[index].fade({duration: this.options.animation.duration, from: 0, to: 1});		//	volgende infaden
		else
			this.items[index].setStyle({opacity: '1.0'});

		//	Links op active zetten:
		this.links.each( function( a ) {
			a.removeClassName( 'js-ifader-active' );
		});
		if ( this.links[index] )
			this.links[index].addClassName( 'js-ifader-active' );

		//	Event afvuren:
		Event.fire( this.items[this.active] , 'ifader:blur' );
		Event.fire( this.items[index] , 'ifader:focus' );

		//	Administratie bijwerken:
		this.active		= index;
	}

});
