/*
 * Carrousel Class
 * 
 * @author: d.
 * 
 */

var Carrousel = new Class({
	
	Implements: [Options],
	
	options: {
		node: 'div.node',
		nodesWrapper: 'carrousel_container',
		btnPrevious: 'carrousel_button_previous',
		btnNext: 'carrousel_button_next',
		minNodesCount: 1
	},
	
	initialize: function(options) {
		this.setOptions(options);
		
		// initialize elements
		['nodesWrapper', 'btnPrevious', 'btnNext'].each(function(element) {
			this[element] = $(this.options[element]);
		}, this);
		
		if (this.nodesWrapper && this.btnPrevious && this.btnNext) {
			
			// prepare carrousel
			this.prepare();
			
			if (this.data.nodesCount >= this.options.minNodesCount) {
				// attach interaction events
				this.attach();
			}
		}
	},
	
	prepare: function() {
		var nodes = this.nodesWrapper.getElements(this.options.node);
		
		// define data object (containing calculated information)
		this.data = $H({
			nodesCount: nodes.length,
			nodeWidth: (nodes.length ? nodes[0].getSize().x + nodes[0].getStyle('margin-left').toInt() + nodes[0].getStyle('margin-right').toInt() : 0),
			isNextRunnable: true,
			isPreviousRunnable: true
		});
		this.data.extend({
			sliderWidth: this.data.nodesCount * this.data.nodeWidth
		});
		
		// create slider
		this.slider = new Element('div', {
			styles: {
				'position': 'relative',
				'height': '100%',
				'width': this.data.sliderWidth + 'px'
			}
		}).inject(this.nodesWrapper, 'top').adopt(nodes);
		
		// create mover (effect for moving nodes)
		this.mover = new Fx.Tween(this.slider, {
			property: 'margin-left',
			duration: 'long',
			transition: Fx.Transitions.Sine.easeOut
		});
	},
	
	attach: function() {
		
		this.btnPrevious.addEvent('click', function(e) {
			e.stop();
			if (this.data.isPreviousRunnable) {
				var controlBound = this.data.sliderWidth - this.nodesWrapper.getSize().x;
				var controlValue = this.slider.getStyle('margin-left').toInt();
				if (controlBound*(-1) <= controlValue && controlValue < 0) {
					this.mover.start(controlValue + this.data.nodeWidth);
				} else {
					this.data.isPreviousRunnable = false;
					
					// create mirror node
					var swapNode = this.slider.getLast(this.options.node);
					var swapNodeClone = swapNode.clone().setStyles({
						position: 'absolute',
						top: 0,
						left: (-1)*this.data.nodeWidth
					}); 
					this.slider.grab(swapNodeClone, 'top');
					
					// move the slider
					this.mover.start(this.slider.getStyle('margin-left').toInt() + this.data.nodeWidth).chain(function() {
						swapNodeClone.erase('style');
						swapNode.destroy();
						this.slider.setStyles({
							'margin-left': this.slider.getStyle('margin-left').toInt() - this.data.nodeWidth
						});
						this.data.isPreviousRunnable = true;
					}.bind(this));
				}
			}
		}.bind(this));
		
		this.btnNext.addEvent('click', function(e) {
			e.stop();
			if (this.data.isNextRunnable) {
				var controlBound = this.data.sliderWidth - this.nodesWrapper.getSize().x;
				var controlValue = this.slider.getStyle('margin-left').toInt();;
				if (controlBound*(-1) < controlValue && controlValue <= 0) {
					this.mover.start(controlValue - this.data.nodeWidth);
				} else {
					this.data.isNextRunnable = false;
					
					// create mirror node
					var swapNode = this.slider.getElement(this.options.node);
					var swapNodeClone = swapNode.clone().setStyles({
						position: 'absolute',
						top: 0,
						right: (-1)*this.data.nodeWidth
					}); 
					this.slider.grab(swapNodeClone, 'bottom');
					
					// move the slider
					this.mover.start(this.slider.getStyle('margin-left').toInt() - this.data.nodeWidth).chain(function() {
						swapNodeClone.erase('style');
						swapNode.destroy();
						this.slider.setStyles({
							'margin-left': this.slider.getStyle('margin-left').toInt() + this.data.nodeWidth
						});
						this.data.isNextRunnable = true;
					}.bind(this));
				}
			}
		}.bind(this));
	}
	
});