



var ScreenSlider = Class.create({
	
	_wrapper: null,
	_slideArea: null,
	_items: [],
	
	_timeout: 8,
	_playTimeout: null,
	_effect: {
		duration: 0.8,
		transition: Effect.Transitions.Quart.easeInOut
	},
	
	_playing: false,
	_queue: 0,
	
	/**
	 * Initialize slider
	 */
	initialize: function(wrapper) {
		this._wrapper = $($(wrapper).select('.abs-wrapper')[0]);
		this._slideArea = $(this._wrapper.select('.slide-area')[0]);
		
		if (!this._slideArea.select('.item').length)
			return;
		
		// Event handling.
		this._slideArea.select('.item a')
			.invoke('observe', 'mouseover', function() {
				this._stop();
			}.bind(this))
			.invoke('observe', 'mouseout', function() {
				this._play();
			}.bind(this));

		// Navigation.
		var $prevLink = $(this._wrapper.select('a.previous')[0]);
		$prevLink.observe('click', function(evt) {
			this._previous();
			evt.stop();
		}.bind(this));
		this._handleNavigationAnimation($prevLink);
		
		var $nextLink = $(this._wrapper.select('a.next')[0]);
		$nextLink.observe('click', function(evt) {
			this._next();
			evt.stop();
		}.bind(this));
		this._handleNavigationAnimation($nextLink);
		
		// Play
		this._play();
	},
	
	/**
	 * Add animation.
	 */
	_handleNavigationAnimation: function(element) {
		var $element = $(element),
			scope = ($element.hasClassName('previous') ? 'slider-prev' : 'slider-next'),
			eventListener = function(event) {
				Effect.Queues.get(scope).invoke('cancel');
				new Effect.Tween($element, $element.getWidth(), (event.type == 'mouseover' ? 80 : 60), {duration: 0.2, queue: {position: 'end', scope: scope}}, $element.setWidth.bind($element));
			};

		$element.observe('mouseover', eventListener).observe('mouseout', eventListener);
	},
	
	/**
	 * Starts slide
	 */
	_play: function() {
		clearTimeout(this._playTimeout);
		
		if (this._queue != 0)
			this._animate();
		else
			this._playTimeout = setTimeout(this._animate.bind(this), this._timeout*1000);
	},
	
	/**
	 * Stops slide.
	 */
	_stop: function() {
		if (this._playTimeout)
			clearTimeout(this._playTimeout);
	},

	/**
	 * Slide to previous item.
	 */
	_previous: function() {
		this._queue = -1;
		
		if (this._playing) {
			return;
		}
		
		this._play();
	},
	
	/**
	 * Slide to newt item.
	 */
	_next: function() {
		this._queue = 1;
		
		if (this._playing) {
			return;
		}
		
		this._play();
	},
	
	/**
	 * Animate
	 */
	_animate: function() {
		var $activeItem = $(this._slideArea.select('.item.active')[0]);
		
		if (this._queue < 0) {
			var $nextItem = $activeItem.previous() || $(this._slideArea.select('.item:last')[0]),
				values = {active: 100, next: 0};
		} else {
			var $nextItem = $activeItem.next() || $(this._slideArea.select('.item:first')[0]),
				values = {active: 0, next: 100};
		}
		this._queue = 0;
		
		// Slide.
		this._playing = true;

		$nextItem.setStyle({left: values.next + '%'});
		$activeItem.setStyle({left: '50%'});
		
		new Effect.Tween($activeItem, 50, values.active, this._effect, this._setPosition.bind($activeItem));
		new Effect.Fade($activeItem, this._effect);
		
		// Handle classnames.
		$activeItem.removeClassName('active');
		$nextItem.addClassName('active');

		var self = this;
		setTimeout(function() {
			
			var afterFinish = function() {
				self._playing = false;
				self._play();
			};
			
			new Effect.Tween($nextItem, values.next, 50, Object.extend({afterFinish: afterFinish}, self._effect), self._setPosition.bind($nextItem));
			new Effect.Appear($nextItem, Object.extend({from: 0}, self._effect));
		}, 350);
	},
	
	/**
	 * Effect handler.
	 */
	_setPosition: function(pos) {
		this.setStyle({left: pos + '%'});
	}
});

$(document).observe('dom:loaded', function() {
	new ScreenSlider($('slideshow'));
});
