var ElementScroller = Class.create({
	initialize: function(container) {
		this.container = $(container);		
		this.elements = this.container.childElements();
		this.scrollQueue = [];
		
		this.actions = {
			'next': { multiplier: -1 },
			'previous': { multiplier: 1 }
		};
		
		this.prepareStyles();
	},
	
	prepareStyles: function() {
		this.container.absolutize();
		this.container.style.overflow = 'hidden';
		this.elements.each(this.positionElementAtIndex.bind(this));
	},
	
	shiftFirstElement: function() {
		var firstElement = this.elements.shift();
		this.positionElementAtIndex(firstElement, this.elements.length);
		this.elements.push(firstElement);
	},
	
	popLastElement: function() {
		var lastElement = this.elements.pop();
		this.positionElementAtIndex(lastElement, -1);
		this.elements.unshift(lastElement);
	},
	
	next: function() {
		this.queueScrollDirection('next');
	},
	
	previous: function() {
		this.queueScrollDirection('previous');
	},
	
	queueScrollDirection: function(direction) {
		if (this.scrollQueue.length > 2)
			this.scrollQueue.clear();
		
		this.scrollQueue.push(direction);
		this.scroll();
	},
	
	scroll: function() {
		if (!this.scrolling && this.scrollQueue.length > 0) {
			var containerWidth = this.container.getWidth();
			var action = this.actions[this.scrollQueue.shift()];
			
			if (action.multiplier == 1)
				this.popLastElement();

			this.scrolling = true;			
			this.elements.each(function(element, index) {
				options = {};
				
				if (index == 0 && action.multiplier == -1) {
					options.afterFinish = this.shiftFirstElement.bind(this);
				} else if (index == this.elements.length - 1) {
					options.afterFinish = function() {
						this.scrolling = false;
						this.scroll();
					}.bind(this);
				}
				
				new Effect.MoveBy(element, 0, action.multiplier * containerWidth, options);
			}.bind(this));
		}
	},
	
	positionElementAtIndex: function(element, index) {
		element.absolutize();
		element.style.left = (this.container.getWidth() * index) + 'px';
	}
});
