/*
---
description: A carrousel class that makes the carrousel actually GO ROUND, instead of flipping back to the front when it reaches the end.
 
license:
 - MIT-style

authors:
  - Doeke Norg (doeke@disain.nl)
  - Jaap Broekhuizen (jaapz.b@gmail.com)

version: 1.2

requires:
  core/1.3: '*'

provides:
 - Carrousel
...
*/

var Carrousel = new Class(
{
	
	Implements: [Events, Options],
	
	options: 
	{
		id:				'carrousel', // element which contains [itemsWrapper]
		itemsWrapper:	'listItems', // element which contains the items with [itemClass]
		itemClass:		'.item', // selector for [items] within [itemsWrapper]
		mode:			'horizontal', // speaks for itself
		
		buttonPrev:		'butPrev', // element that fires previous function
		buttonNext:		'butNext', // element that fires next function
		
		fadeIn:			true, // fade [itemsWrapper] in ; or not
		hideControls:	true,  // hide [buttonPrev] and [buttonNext] if there is just one item
		
		duration:       'normal', // 'short', 'normal', 'long' or integer
		minimalItems:	2,
		
		focusedClass:   'active', // give this class to the focused item
		touch:			true
	},
	
	items:				new Array(),
	itemDimensions:		null,
	clone: 				null,
	offset: 			{ top: null, left: null },
	wait:				false,	
	FX:					null,
	currentID:			0,
	
	initialize: function(options)
	{
		this.setOptions(options);
		this.getItems();
		
		this.itemDimensions = this.items[0].getSize();
				
		if(this.items.length >= this.options.minimalItems)
		{
			if(this.options.mode == "vertical")
			{
				this.offset.top = this.itemDimensions.y*-1;
			}
			else
			{
				this.offset.left = this.itemDimensions.x*-1;
				
				this.items.each(function(el)
				{
					el.set('styles',{ float: 'left'} );
				});
				document.id(this.options.itemsWrapper).set('styles',{ width: (this.items.length+1)*this.itemDimensions.x } );
			}

			this.clone = this.items[this.items.length-1].clone();
			this.clone.inject(document.id(this.options.itemsWrapper),'top');
			this.getItems(); //refresh list;
		    this.attachEvents();
			
			document.id(this.options.id).set('styles',{position:'relative'} );
			document.id(this.options.itemsWrapper).set('styles', { position: 'absolute', left: this.offset.left, top:this.offset.top });
			
			document.id(this.options.buttonNext).addEvent('click',(this.next).bind(this));
			document.id(this.options.buttonPrev).addEvent('click',(this.previous).bind(this));
			
			if(this.options.touch)
			{
				document.id(this.options.id).addEvent('swipe',(function(e)
				{
					if(e.direction == "left") this.next();
					else if(e.direction == "right") this.previous();
					
				}).bind(this));
			}
			
		}
		else
		{
			if(this.options.hideControls)
			{
				document.id(this.options.buttonPrev).fade('hide');
				document.id(this.options.buttonNext).fade('hide');
			}			
		}
		
		this[this.options.mode]();

		if(this.options.fadeIn) document.id(this.options.id).fade('hide').fade('in');
	},
	
	horizontal: function()
	{
		this.layout = 'margin-left';
		this.offsetMargin = '-'+ this.itemDimensions.x+'px';
	},
	
	vertical: function()
	{
		this.layout = 'margin-top';
		this.offsetMargin = '-'+this.itemDimensions.y+'px';
	},
	
	getItems: function()
	{
		this.items = document.id(this.options.id).getElements(this.options.itemClass);
		return this.items.length;
	},
	
	updateCarrousel: function()
	{
	    this.getItems();
	    
	    if (this.items.length <= this.options.minimalItems) {
	        if (this.options.hideControls) {
	            document.id(this.options.buttonPrev).fade('out');
				document.id(this.options.buttonNext).fade('out');
				
				document.id(this.options.itemsWrapper).set('styles', {left: 0, top: 0 });
	        }
	    } else {
	        if (this.options.hideControls) {
			    document.id(this.options.buttonPrev).fade('in');
			    document.id(this.options.buttonNext).fade('in');
			    
			    document.id(this.options.itemsWrapper).set('styles', {left: this.offset.left, top: this.offset.top });
	        }
	        
		    this.clone = this.items[this.items.length-1].clone();
	        this.clone.inject(document.id(this.options.itemsWrapper),'top');
	    }
		
		// refresh and attach events to the clones
		this.getItems();
		this.attachEvents();
		
		// fire update event
		this.fireEvent("update", document.id(this.options.itemsWrapper));
	},
	
	attachEvents: function() {
		this.items.each(function(item, index) {
		    item.getElements('a').each(function(link){
                link.removeEvents('click');
   	            link.addEvent('click', (function(e) {
       	                e.preventDefault();
       	                // remove every other focusedClass
	                    this.items.each(function (itemInner) {
	                        itemInner.removeClass(this.options.focusedClass);
	                    }, this);
       	            
       	                // add the new one
	                    item.addClass(this.options.focusedClass);
	                    
	                    // fire up the focus event
	                   this.fireEvent('focus',[link, index, item]);
	            }).bind(this));
            }, this);
		}, this);
	},
	
	setCurrent:function(mode)
	{
		switch(mode)
		{
			case '+':
				if(this.currentID+1 == (this.items.length/2) - 1) this.currentID = 0;
				else this.currentID++;
				break;
			case '-':
				if(this.currentID == 0) this.currentID = (this.items.length / 2) - 2;
				else this.currentID--;
				break;
			default:
				return;
				break;
		}
	},
	
	previous: function()
	{
  	if(!this.wait && this.items.length >= this.options.minimalItems )
		{
			this.wait = true;
			this.setCurrent("-");
			
			this.items[this.items.length-1].destroy(); //remove last item
			this.clone = this.items[this.items.length-2].clone();
			this.clone.setStyle(this.layout,this.offsetMargin);
			this.clone.inject(document.id(this.options.itemsWrapper),'top');
			
			this.fireEvent('previous');
			
			this.FX = new Fx.Tween(this.clone,{
				duration:this.options.duration,
				onComplete:(function()
				{
					this.wait = false;
					this.getItems();
					this.attachEvents();
					this.fireEvent('complete');
				}).bind(this)
			}).start(this.layout,0);
		}
	},
	
	next: function()
	{
		if(!this.wait && this.items.length >= this.options.minimalItems)
		{
			this.wait = true;
			this.setCurrent("+");

			this.FX = new Fx.Tween(this.items[0],{
				duration:this.options.duration,
				onComplete:(function()
				{
					this.items[0].destroy();
					
					this.clone = this.items[1].clone();

					this.clone.inject(document.id(this.options.itemsWrapper));

					this.getItems(); //refresh itemslist
					this.attachEvents();
					this.wait = false;
					this.fireEvent('complete');
				}).bind(this)			
			}).start(this.layout,this.offsetMargin);
			
			this.fireEvent('next');
		}
	}
});

