/*
 * Mootools Carousel
 */
var Carousel = new Class({

	Implements: [Options, Events],

	options: {
		auto: { // auto options : if false, no automatic fx
			start: true,	// auto start (use if auto is > 0)
			duration: 2000, // auto show duration
			pause: 2000	// auto restart the list on mouseleave after this time
		},
		items: {x: 1, y: 1}, // Number of items to display (like a grid)
		grouped: 1, // number of items to drop on next/previous (1 by 1, 4 by 4)
		direction: 'horizontal', // Carousel direction, vertical or horizontal
		itemDimensions: {width: 200, height: 150}, // item dimensions
		startingIndex: 0,
		fx: {
			duration: 1000,
			transition: Fx.Transitions.Cubic.easeInOut
		}
	},
	container: null,
	ul: null,
	fx: null,
	items: [],
	index: 0,
	paused: true,
	ulDimensions: {width: 0, height: 0},
	containerDimensions: {width: 0, height: 0},
	initialize: function(container, options) {
		this.setOptions(options);
		// init the properties
		this.container = container;
		this.ul = this.container.getElement('ul');
		this.items = this.ul.getElements('li');
		this.index = this.options.startingIndex;
		this.build();
	},
	build: function() {
		this.container.addClass('carousel');

		this.items.setStyles(this.options.itemDimensions);

		this.ul.addClass(this.options.direction+'-carousel');
		
		this.fx = new Fx.Morph(this.ul, this.options.fx);

		// rebuild the number of items option
		if(!isNaN(this.options.items)) {
			if(this.options.direction == 'horizontal') {
				this.options.items = {x: this.options.items, y: 1};
			} else {
				this.options.items = {x: 1, y: this.options.items};
			}
		}

		// calculate the container dimensions based on the item displayed and their dimensions
		if(this.options.direction == 'horizontal') {
			this.ulDimensions.width =  this.options.itemDimensions.width * this.items.length;
			this.ulDimensions.height =  this.options.itemDimensions.height * this.options.items.y;
		} else {
			this.ulDimensions.height = this.options.itemDimensions.height * this.items.length;
			this.ulDimensions.width =  this.options.itemDimensions.width * this.options.items.x;
		}
		// set the list dimensions
		this.ul.setStyles(this.ulDimensions);

		// set the container dimensions based on the item grid
		this.containerDimensions = {
			width: this.options.items.x * this.options.itemDimensions.width,
			height: this.options.items.y * this.options.itemDimensions.height
		}

		this.container.setStyles(this.containerDimensions);

		// if it's horizontal and the number of items vertically > 1, we need to break the floating items
		if(this.options.direction == 'horizontal' && this.options.items.y > 1) {
			this.items.each(function(el, index) {
				if(index%this.options.items.y == (this.options.items.y - 1)) {					
					el.setStyle('clear', 'both');
				}
			}.bind(this));
		}

		// auto pause
		if(this.options.auto.pause) {
			this.ul.addEvents({
				mouseenter: function() {
					this.stop();
				}.bind(this),
				mouseleave: function() {
					(function() {
						this.start();
					}.bind(this)).delay(this.options.auto.pause)
				}.bind(this)
			})
		}

		// auto start
		if(this.options.auto && this.options.auto.start) {
			this.start();
		}		
	},
	start: function() {
		if(this.paused) {
			this.paused = false;
			this.goTo(this.index);		
			this.fireEvent('start');
		}
	},
	stop: function() {
		this.paused = true;
		this.fireEvent('stop');
	},
	goTo: function(index) {
		var coordinates = {left: 0, top: 0};
		if(this.options.direction == 'horizontal') {
			coordinates.left = -this.items[index].getPosition(this.ul).x;
		} else {			
			coordinates.top = -this.items[index].getPosition(this.ul).y;
		}			
		
		this.fx.start(coordinates);

		// if it's set on auto, go next
		if(this.options.auto) {			
			(function() {
				if(!this.paused) {
					this.next();
				}
			}.bind(this)).delay(this.options.auto.duration);
		}

		this.fireEvent('show');
	},
	next: function() {
		this.index += this.options.grouped;
		if(this.index >= this.items.length) {
			this.index = 0;
		}

		this.fireEvent('next');
		this.goTo(this.index);
	},
	previous: function() {
		this.index -= this.options.grouped;
		if(this.index < 0) {
			this.index = this.items.length - 1;
		}

		this.fireEvent('previous');
		this.goTo(this.index);
	},
	pause: function() {

	},
	toElement: function() {
		return this.element;
	}
});

/* IMPLEMENTATION */

/**
 * Apply a carousel to a ul list
 */

Element.implement({
	carousel: function(options) {

		return this;
	}
});