/**
 * ContentScroller.js
 * Copyright (c) Fluid Creativity, 2009
 *
 * Implements a slider which scrolls vertically is the content overflows the requrired height
 */

var VerticalSlider = new Class({

	Implements: [Options,  Events],

	el: null,

	options: {
		height: 200,
		transition: 'linear',
		scrollStep: 50,
		scrollDuration: 200,
		scrollUpClass: 'scrollUpLink',
		scrollDownClass: 'scrollDownLink'
	},

	initialize: function(el, options) {
		this.el = $(el);
		this.setOptions(options);
		this.setupComponent();
	},

	setupComponent: function() {
		if (this.el.getSize().y > this.options.height) {
			// Setup wrapper container
			this.slider = new Element('div').setStyles({
				'overflow': 'hidden',
				'position': 'relative',
				'height': this.options.height
			}).wraps(this.el);

			// Setup controls and events
			var endScroll = this.endScroll.bindWithEvent(this);

			this.slider.adopt(
				// Up Link
				new Element('a', {
					href: '#',
					text: 'Scroll Up',
					title: 'Scroll list up',
					'class': this.options.scrollUpClass
				}).addEvents({
					'mousedown': this.startScroll.bindWithEvent(this, 1),
					'mouseup': endScroll,
					'mouseleave': endScroll,
					'click': function(e) { e.stop(); }
				}),

				// Down Link
				new Element('a', {
					href: '#',
					text: 'Scroll Down',
					title: 'Scroll list down',
					'class': this.options.scrollDownClass
				}).addEvents({
					'mousedown': this.startScroll.bindWithEvent(this, -1),
					'mouseup': endScroll,
					'mouseleave': endScroll,
					'click': function(e) { e.stop(); }
				})
			);

			this.slider.addEvent('mousewheel', function(e) {
				e.stop();
				this.slideComponent(e.wheel);
			}.bindWithEvent(this));

			// Setup animation
			this.sliderFx = new Fx.Tween(this.el, {
				property: 'margin-top',
				link: 'ignore',
				duration: this.options.scrollDuration,
				transition: this.options.transition
			});
		}
	},

	startScroll: function(e, direction) {
		this.slideComponent(direction);
		this.timer = this.slideComponent.periodical(this.options.scrollDuration, this, direction);
	},

	endScroll: function(e) {
		$clear(this.timer);
	},

	slideComponent: function(direction) {
		var currentPos = this.el.getStyle('margin-top').toInt();
		var internalHeight = this.el.getSize().y;

		if (direction < 0 && currentPos > this.options.height - internalHeight) {
			this.sliderFx.start(Math.max(this.options.height - internalHeight, currentPos - this.options.scrollStep));
		} else if (direction > 0 && currentPos < 0) {
			this.sliderFx.start(currentPos + this.options.scrollStep > 0 ? 0 : currentPos + this.options.scrollStep);
		}
	},

	toElement: function() {
		return ($defined(this.slider) ? this.slider : this.el);
	}
});
