//Carousel, <http://www.circlesquare.biz>. Copyright (c) 2008, circlesquare solutions ltd. BSD Style License.

/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the <organization> nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY MICHAEL BIRD 'AS IS' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

var Carousel = new Class({

	Implements: [Events, Options],

	options: {
		onLoad: function(){
			this.play();
		},
		onPlay: $empty,
		onPause: $empty,
		onStop: $empty,
		index: 0,
		interval: 3000,
		duration: 1000,
		transition: 'quad:out'
	},
	
	initialize: function(carousel, options){
		this.setOptions(options);
		this.carousel = $(carousel);
		this.index = 0;
		this.playing = false;
		this.paused = false;
		this.swapping = false;
		this.carousel.setStyle('position', 'relative');
		this.carousel.getChildren().each(function(child, index){
			child.setStyles({
				'position': 'absolute',
				'top': '0px',
				'left': '0px'
			});
			if (index == this.options.index) {
				this.index = index;
			} else {
				child.setStyle('display', 'none');
			}
		}.bind(this));
		this.fireEvent('load');
	},
	
	swap: function(index, direction){
		if (!$defined(direction)) {
			direction = 1;
		}
		// swap to next element
		this.swapping = true;
		var elements = this.carousel.getChildren();
		elements[index].setStyle('display', 'block');
		if (direction > 0) {
			var offset = -elements[index].getSize().y;
		} else {
			var offset = elements[index].getSize().y;
		}
		elements[index].setStyle('top', -offset);
		new Fx.Tween(elements[index], {
			wait: false,
			duration: this.options.duration,
			transition: this.options.transition,
			onComplete: function(){
				elements[this.index].setStyle('display', 'none');
				this.index = index;
				if (this.playing) {
					this.jumper = this.next.delay(this.options.interval, this);
				}
				this.swapping = false;
			}.bind(this)
		}).start('top', 0);
		new Fx.Tween(elements[this.index], {
			wait: false,
			duration: this.options.duration,
			transition: this.options.transition
		}).start('top', offset);
		
	},
	
	play: function(){
		if (!this.playing) {
			this.playing = true;
			this.jumper = this.next.delay(this.options.interval, this);
			this.fireEvent('play');
		}
	},
	
	pause: function(){
		if (this.playing) {
			this.playing = false;
			this.paused = true;
			$clear(this.jumper);
			this.fireEvent('pause');
		}
	},
	
	stop: function(){
		if (this.playing || this.paused) {
			this.playing = false;
			this.paused = false;
			$clear(this.jumper);
			if (this.index != this.options.index) {
				this.swap(this.options.index);
			}
			this.fireEvent('stop');
		}
	},
	
	next: function(){
		if (!this.swapping) {
			$clear(this.jumper);
			var index = this.index+1;
			if (index < 0) {
				index = this.carousel.getChildren().length-1;
			}
			if (index >= this.carousel.getChildren().length) {
				index = 0;
			}
			this.swap(index, 1);
		}
	},
	
	previous: function(){
		if (!this.swapping) {
			$clear(this.jumper);
			var index = this.index-1;
			if (index < 0) {
				index = this.carousel.getChildren().length-1;
			}
			if (index >= this.carousel.getChildren().length) {
				index = 0;
			}
			this.swap(index, -1);
		}
	}

});

window.addEvent('domready', function(){
	document.getElements('.scroll').each(function(scroll){
		var carousel = new Carousel(scroll.getElement('ul'));
		scroll.getElement('.previous').addEvent('click', function(e){
			new Event(e).stop();
			carousel.previous();
		});
		scroll.getElement('.next').addEvent('click', function(e){
			new Event(e).stop();
			carousel.next();
		});
	});
});
