/**
 *
 * Paged slider-component including continuous scroll
 * Necessairy HTML structure:
 *	<div class="islider">
 *		<div class="islider-wrapper">
 *			<a href="#" class="islider-previous">vorige</a>
 *			<a href="#" class="islider-next">volgende</a>
 *			<div class="islider-viewport">
 *				<div class="islider-container">
 *					<a href="#" class="islider-link"></a>
 *				</div>
 *			</div>
 *		</div>
 *	</div>
 *
 * @version		1.0
 * @date		2010-05-25
 * @copyright	2010 iWink BV
 * @author		Timo Schinkel
 */
var iSlider = Class.create({
 
	islider			: null,
	container		: null,
	items			: null,
	active			: 0,
 
	itemSize		: 1,
	viewportSize	: 1,
	numOfPages		: 1,
 
	peTimeout		: 10,
	pe				: null,
 
	//	Direction implementation:
	direction		: 'horizontal',
 
	/**
	 * Builds a new instance of iSlider
	 * @param	Element	element
	 * @param	Object	options
	 */
	initialize		: function ( element , options ) {
		this.islider	= element;
		this.container	= element.down( '.islider-container' );
		this.items		= this.container.childElements();
 
		//	Direction implementation:
		if ( options && options.direction == 'vertical' )
			this.direction	= 'vertical';
 
		this._resizeElements();
		this._addObservers();
 
		if ( options && options.timer ) {
			this.peTimeout	= options.timer;
			this.pe	= new PeriodicalExecuter( function() {
				this.next();
			}.bind(this) , this.peTimeout );
		}
	} ,
 
	/**
	 * Retrieves some size information and resizers the container if necessairy
	 * @access	private
	 */
	_resizeElements	: function () {
		if ( this.direction == 'vertical' ) {
			this.viewportSize	= this.islider.down('.islider-viewport').getHeight();
			if ( this.items.length > 0 ) {
				this.itemSize	= this.items[0].getHeight();
				this.container.setStyle({height: ( this.itemSize * this.items.length ) + 'px'});	//	wss onnodig :)
			}
		} else {
			this.viewportSize	= this.islider.down('.islider-viewport').getWidth();
			if ( this.items.length > 0 ) {
				this.itemSize	= this.items[0].getWidth();
				this.container.setStyle({width: ( this.itemSize * this.items.length ) + 'px'});
			}
		}				
		this.numOfPages	= Math.ceil( ( this.itemSize * this.items.length ) / this.viewportSize );
	} ,
 
	/**
	 * Adds observers to various elements
	 * @access	private
	 */
	_addObservers	: function () {

		array = this.islider.select( 'div.islider-controls a' ).toArray();
		
		for(i = 0; i < array.length; i++) {
			
			element = $(array[i]);
			Event.observe(element, 'click', this.gotoIndexFromLink.bind(this));
		}

	},
	
	gotoIndexFromLink: function(event) {
		if(event) {
			event.stop();
			if ( this.pe ) //	Als de PeriodicalExecuter aanstaat, moeten we deze even opnieuw starten
				this.restartPeriodicalExecuter ();
			
			this.gotoIndex( parseInt(event.element().innerHTML) - 1 );
		}
	},
	 
	/**
	 * Go to next page
	 * @param	Event	event
	 */
	next			: function ( event ) {
		if ( event ) {
			event.stop();
			if ( this.pe ) //	Als de PeriodicalExecuter aanstaat, moeten we deze even opnieuw starten
				this.restartPeriodicalExecuter ();
		}
 
		this.gotoIndex( this.active + 1 );
	} ,
 
	/**
	 * Go to previous page
	 * @param	Event	event
	 */
	previous		: function ( event ) {
		if ( event ) {
			event.stop();
			if ( this.pe ) //	Als de PeriodicalExecuter aanstaat, moeten we deze even opnieuw starten
				this.restartPeriodicalExecuter ();
		}
 
		this.gotoIndex( this.active - 1 );
	} ,
 
	/**
	 * Go to a numbered page
	 * @param	Integer	index
	 */
	gotoIndex		: function ( index ) {
		if ( index < 0 )
			index	= this.numOfPages - 1;
		else if ( index >= this.numOfPages )
			index	= 0;
 
		//	Morph to the right position:
		if ( this.direction == 'vertical' ) {			
			this.container.morph( 'margin-top: -' + ( this.viewportSize * index ) + 'px;' , {
				duration: 1.0,
				transition: Effect.Transitions.sinoidal,
				afterFinish: function () {
					this.active	= index;
				}.bind(this)
			});
		} else {
			this.container.morph( 'margin-left: -' + ( this.viewportSize * index ) + 'px;' , {
				duration: 1.0,
				transition: Effect.Transitions.sinoidal,
				afterFinish: function () {
					this.active	= index;
				}.bind(this)
			});
		}		
	} ,
 
	/**
	 * Restarts the periodicalExecuter
	 */
	restartPeriodicalExecuter:	function () {
		if ( !this.pe )
			return;
		this.pe.stop();
		this.pe	= new PeriodicalExecuter( function() {
			this.next();
		}.bind(this) , this.peTimeout );
	}
 
});
