/**
 * carrousel.class.js
 * creates a carrousel
 * 
 * @version 1.1
 * @author Rocco
 * @author Klaas
 * @since 4 oct 2010
 * @copyright Rocco Janse
 * @package Engine JS Lib
 * @subpackage Carrousel
 * @uses MooTools 1.2.x core
 *
 * @todo: fix behaviour when clicking too fast
 */
 
 var Carrousel = new Class({
	
	Implements: Options,
	
	options: {
		'slidesContainer': null,
		'linkNext': null,
		'linkPrevious': null,
		'slidesToShift': 1,
		'slidesToShow': 3		
	},
	
	initialize: function(options) {
		this.setOptions(options);

		this.slidesToShift = this.options.slidesToShift.toInt();
		this.slidesToShow = this.options.slidesToShow.toInt();
		this.slidesContainer = this.options.slidesContainer;
		this.linkNext = this.options.linkNext;
		this.linkPrevious = this.options.linkPrevious;
		this.slides = [];
		
		if (!this.linkNext || !this.linkPrevious || !this.slidesContainer) return false;
		
		// remove any previously added nav-eventlisteners, if present
		this.disableNav();
		
		// cancel carrousel creation if slides fit within viewport already
		if(this.initSlides() == false) return false;
		
		this.enableNav();
	},
	
	initSlides: function() {
		
		// fetch original slides
		this.slides = this.slidesContainer.getElements('li');
		if(this.slides.length <= this.slidesToShow) return false;
		
		// remove them from the dom
		this.slides.each(function(slide, index) {
			slide.dispose();
		}.bind(this));
		
		// (re)place the first items
		for (i = 0; i < this.slidesToShow; i++) {
			this.slides[i].inject(this.slidesContainer);
		}
	},

	gotoNextPosition: function() {
		this.disableNav();
		
		var current = this.slides.indexOf(this.slidesContainer.getLast('li'));
		var startPos = 0;
		var index;
		
		for (i = 1; i <= this.slidesToShift; ++i) {
			
			if (current + i > this.slides.length-1) {
				index = (current + i) - this.slides.length;
			} else {
				index = current + i;
			}	
			this.slides[index].inject(this.slidesContainer, 'bottom');
			startPos += this.getSlideWidth(this.slides[index]);
		}

		var myFx = new Fx.Tween(this.slidesContainer, {
			onComplete: function() {
				this.enableNav()
			}.bind(this)
		});
	
		myFx.start('margin-left', 0, -startPos).chain(function() {

			slides = this.slidesContainer.getElements('li');
			for (i = 0; i < this.slidesToShift; i++) {
				width = this.getSlideWidth(this.slides[i]);
				slides[i].dispose();
			}
			this.slidesContainer.setStyle('margin-left', 0);
			
		}.bind(this));
	},
	
	gotoPreviousPosition: function() {
		this.disableNav();
		
		var current = this.slides.indexOf(this.slidesContainer.getFirst('li'));
		var startPos = 0;
		var index;
		
		for (i = 1; i <= this.slidesToShift; ++i) {
			
			if (current - i < 0) {
				index = this.slides.length + (current - i);
			} else {
				index = current - i;
			}			
			
			this.slides[index].inject(this.slidesContainer, 'top');
			startPos += this.getSlideWidth(this.slides[index]);
			
		}
		this.slidesContainer.setStyle('margin-left',-startPos);
		
		var myFx = new Fx.Tween(this.slidesContainer, {
			onComplete: function() {
				this.enableNav()
			}.bind(this)
		});
		
		myFx.start('margin-left', -startPos, 0).chain(function() {

			slides = this.slidesContainer.getElements('li');
			for (i = 0; i < this.slidesToShift; i++) {
				var index = (slides.length-1) - i;
				slides[index].dispose();
			}
			
		}.bind(this));
	},
	
	getSlideWidth: function(elSlide) {
		var intWidth = elSlide.getWidth();
		intWidth += parseInt(elSlide.getStyle('margin-left'));
		intWidth += parseInt(elSlide.getStyle('margin-right'));
		
		return intWidth;
	},
	
	disableNav: function() {
		this.linkNext.setStyle('visibility', 'hidden');
		this.linkPrevious.setStyle('visibility', 'hidden');
		
		this.linkNext.removeEvent('click', this.boundGotoNextPosition);
		this.linkPrevious.removeEvent('click', this.boundGotoPreviousPosition);
	},
	
	enableNav: function() {
		this.linkNext.setStyle('visibility', 'visible');
		this.linkPrevious.setStyle('visibility', 'visible');
		
		// these methods need to have a bound reference to be able to remove the event listeners later on
		this.boundGotoNextPosition = this.gotoNextPosition.bind(this);
		this.boundGotoPreviousPosition = this.gotoPreviousPosition.bind(this);
		
		this.linkNext.addEvent('click', this.boundGotoNextPosition);
		this.linkPrevious.addEvent('click', this.boundGotoPreviousPosition);
	}
});
