/**
 * Paged slider-component including scroll per image
 * Necessary 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.1
 * @date		2011-02-03
 * @copyright	2011 iWink BV
 * @author		Elbert Jan Woudstra
 */
var iSlider = Class.create({
	islider			: null,
	container		: null,
	items			: null,
	active			: 0,
 
	itemSize		: 1,
	viewportSize	: 1,
 
	peTimeout		: 10,
	pe				: null,
	directionRight	: true,
 
	/**
	 * 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();
 
		this._resizeElements();
		this._addObservers ();
 
		if (options && options.timer) {
			this.peTimeout = options.timer;
			this.pe	= new PeriodicalExecuter(function() {
				if (this.directionRight) {
					this.nextItem();
				} else {
					this.previousItem();
				}
			}.bind(this), this.peTimeout );
		}
	},
 
	/**
	 * Retrieves some size information and resizers the container if necessary
	 * @access	private
	 */
	_resizeElements: function() {
		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'});
		}
	},
 
	/**
	 * Adds observers to various elements
	 * @access	private
	 */
	_addObservers: function() {
		if (this.islider.down('a.islider-previous'))
			this.islider.down('a.islider-previous').observe('click', this.previousItem.bind(this));
		if (this.islider.down('a.islider-previous'))
			this.islider.down('a.islider-next').observe('click', this.nextItem.bind(this) );
	},
 
	/**
	 * Go to next item
	 * @param	Event	event
	 */
	nextItem: function(event) {
		if (event) {
			event.stop();
			if (this.pe) {
				// Als de PeriodicalExecuter aanstaat, moeten we deze even opnieuw starten
				this.restartPeriodicalExecuter();
			}
		}
		this.gotoItemIndex(this.active + 1);
	},
 
	/**
	 * Go to previous item
	 * @param	Event	event
	 */
	previousItem: function(event) {
		if (event) {
			event.stop();
			if (this.pe) {
				// Als de PeriodicalExecuter aanstaat, moeten we deze even opnieuw starten
				this.restartPeriodicalExecuter();
			}
		}
		this.gotoItemIndex(this.active - 1);
	},

	/**
	 * Go to a numbered item
	 * @param	Integer	index
	 */
	gotoItemIndex: function(index) {
		if ((index <= 0) || (index >= this.items.length)) {
			index	= 0;
			this.directionRight = true;
		}
		
		var sumWidth = 0;
		for (var int = 0; int < this.items.length; int++) {
			// Loop through all images and count the widths
			if (int == index) {
				// We have added all the image widths up to the one we want to view
				break;
			}
			sumWidth += this.items[int].getWidth();
		}
		
		// Count the image widths from the right back to the left
		if (this.directionRight) {
			var sumRemainingWidth = 0;
			for (var int = this.items.length - 1; int >= 0; int--) {
				// Loop through all images from the right back to the left
				// and count the widths
				sumRemainingWidth += this.items[int].getWidth();
				if (int == index) {
					// We have added all the image widths up to the one we are currently viewing
					break;
				}
			}
			
			// The remaining image width is equal to the viewport size:
			// time to change the direction, we have reached the last image
			if (sumRemainingWidth <= this.viewportSize) {
				// reverse the morph direction
				this.directionRight = false;
			}
		}
		
		// Morph to the correct position
		this.container.morph('margin-left: -' + sumWidth + 'px;', {
			duration: 1.0,
			transition: Effect.Transitions.linear,
			afterFinish: function() {
				this.active	= index;
			}.bind(this)
		});
	},
 
	/**
	 * Restarts the periodicalExecuter
	 */
	restartPeriodicalExecuter: function() {
		if (!this.pe) {
			return;
		}
		
		this.pe.stop();
		this.pe	= new PeriodicalExecuter(function() {
			if (this.directionRight) {
				this.nextItem();
			} else {
				this.previousItem();
			}
		}.bind(this), this.peTimeout);
	}
 
});
