/*
---

script: Fx.Scroll.Carousel.js

description: Extends Fx.Scroll to work like a carousel

license: MIT-style license.

authors: Ryan Florence

docs: http://moodocs.net/rpflo/mootools-rpflo/Fx.Scroll.Carousel

requires:
- more/1.2.4.2: [Fx.Scroll]

provides: [Fx.Scroll.Carousel]

...
*/


Fx.Scroll.Carousel = new Class({

	Extends: Fx.Scroll,

		options: {
			mode: 'horizontal',
			childSelector: false,
			loopOnScrollEnd: true
		},

	initialize: function(element, options){
		this.parent(element, options);
		this.cacheElements();
		this.currentIndex = 0;
	},

	cacheElements: function(){
		var cs = this.options.childSelector;
		if(cs){
			els = this.element.getElements(cs);
		} else if (this.options.mode == 'horizontal'){
			els = this.element.getElements(':first-child > *');
		} else {
			els = this.element.getChildren();
		}
		this.elements = els;
		return this;
	},

	toNext: function(){
		if(this.checkLink()) return this;
		this.currentIndex = this.getNextIndex();
		this.toElement(this.elements[this.currentIndex]);
		this.fireEvent('next');
		return this;
	},

	toPrevious: function(){
		if(this.checkLink()) return this;
		this.currentIndex = this.getPreviousIndex();
		this.toElement(this.elements[this.currentIndex]);
		this.fireEvent('previous');
		return this;
	},
	
	toIndex: function(index){
		if (this.checkLink()) return this;
		this.currentIndex = index;
		this.toElement(this.elements[this.currentIndex]);
		this.fireEvent('index', index);
		return this;
	},

	getNextIndex: function(){
		this.currentIndex++;
		if(this.currentIndex == this.elements.length || this.checkScroll()){
			this.fireEvent('loop');
			this.fireEvent('nextLoop');
			return 0;
		} else {
			return this.currentIndex;
		};
	},

	getPreviousIndex: function(){
		this.currentIndex--;
		var check = this.checkScroll();
		if(this.currentIndex < 0 || check) {
			this.fireEvent('loop');
			this.fireEvent('previousLoop');
			return (check) ? this.getOffsetIndex() : this.elements.length - 1;
		} else {
			return this.currentIndex;
		}
	},

	getOffsetIndex: function(){
		var visible = (this.options.mode == 'horizontal') ? 
			this.element.getStyle('width').toInt() / this.elements[0].getStyle('width').toInt() :
			this.element.getStyle('height').toInt() / this.elements[0].getStyle('height').toInt();
		return this.currentIndex + 1 - visible;
	},

	checkLink: function(){
		return (this.timer && this.options.link == 'ignore');
	},

	checkScroll: function(){
		if(!this.options.loopOnScrollEnd) return false;
		if(this.options.mode == 'horizontal'){
			var scroll = this.element.getScroll().x;
			var total = this.element.getScrollSize().x - this.element.getSize().x;
		} else {
			var scroll = this.element.getScroll().y;
			var total = this.element.getScrollSize().y - this.element.getSize().y;
		}
		return (scroll == total);
	},

	getCurrent: function(){
		return this.elements[this.currentIndex];
	}

});



Fx.Scroll.Carousel.Request = new Class({
	
	Extends: Fx.Scroll.Carousel,
	
	options: {
		request: {},
		itemSize: false,
		wrapper: '',
		content: ''
	},
	
	initialize: function(element, options){
		this.parent(element, options);
		
		this.wrapper = this.element.getElement(this.options.wrapper);
		
		this.addEvent('change', function(items){
			this.resize(items);
		}.bind(this));
		
		return this;
	},
	
	addItem: function(item){
		item.inject(this.wrapper);
		this.elements.push(item);
		
		return this;
	},
	
	addItems: function(){
		var items = Array.from(arguments).flatten();
		items.each(function(item){
			this.addItem(item);
		}, this)
		this.fireEvent('change', [items]);
	},
	
	resize: function(items){
		var horizontal = this.options.mode == 'horizontal';
		var direction = (horizontal ? 'x' : 'y');
		var size = this.wrapper.getSize();
		var diff = 0;
		if (this.options.itemSize){
			diff = this.options.itemSize*items.length
		} else {
			items.each(function(item){
				var size = item.getSize();
				diff +=  size[direction];
			});
		}

		this.wrapper.setStyle(horizontal ? 'width' : 'height', size[direction] + diff);
		
		this.fireEvent('resize', [diff]);
		
		return this;
	}
	
	
});


Fx.Scroll.Carousel.Request.HTML = new Class({
	
	Extends: Fx.Scroll.Carousel.Request,
	
	initialize: function(element, options){
		this.parent(element, options);
		
		this.request = new Request.HTML(Object.merge(this.options.request, {
			onRequest: function(){
				this.fireEvent('loadStart');
			}.bind(this),
			onSuccess: function(response){
				var container = new Element('div').adopt(response);
				var items = container.getElements(this.options.childSelector || '> *');
  			this.addItems(items);
			}.bind(this),
			onComplete: function(){
				this.fireEvent('loadComplete');
			}.bind(this)
		}));
	},
	
	load: function(data){
		this.request.get(data);
		
		return this;
	}
	
});
