VerticalScroller = Class.create();

Object.extend(VerticalScroller.prototype, {

	initialize: function (scroller, controls, options) {

		this.timer = null;
		this.scroller = scroller;
		this.controls = controls;

		this.options = Object.extend({
									frequency: 0.1, 
									step: 1, 
									oldStep: null, 
									stepModifier: 3, 
									controlOpacity: 1, 
									deactivateControl: true, 
									activeControlClass: 'active', 
									fasterControlClass: false
									}, options || {});

		this.events = {
					mouseoverTop: this.mouseoverTop.bind(this),  
					mouseoutTop: this.mouseoutTop.bind(this), 
					mousedownTop: this.mousedownTop.bind(this),
					mouseupTop: this.mouseupTop.bind(this), 

					mouseoverBottom: this.mouseoverBottom.bind(this),
					mouseoutBottom: this.mouseoutBottom.bind(this), 
					mousedownBottom: this.mousedownBottom.bind(this), 
					mouseupBottom: this.mouseupBottom.bind(this), 

					click: this.click.bind(this) 
					};

		this.bindObservers(this.controls);

		this.controls.top.active = true;
		this.controls.bottom.active = true;

		this.controls.top.setOpacity(0);
		this.controls.bottom.setOpacity(0);

		if (this.options.deactivateControl) {
			this.controls.top.active = false;
			this.controls.bottom.addClassName(this.options.activeControlClass);
			}
	
		},
	

	bindObservers: function (controls) {
		controls.top.observe('mouseover', this.events.mouseoverTop);
		controls.top.observe('mouseout', this.events.mouseoutTop);
		controls.top.observe('mousedown', this.events.mousedownTop);
		controls.top.observe('mouseup', this.events.mouseupTop);
		controls.top.observe('click', this.events.click);

		controls.bottom.observe('mouseover', this.events.mouseoverBottom);
		controls.bottom.observe('mouseout', this.events.mouseoutBottom);
		controls.bottom.observe('mousedown', this.events.mousedownBottom);
		controls.bottom.observe('mouseup', this.events.mouseupBottom);
		controls.bottom.observe('click', this.events.click);
		},


	mouseoverTop: function (event) {
		this.controls.top.addClassName('hover');
		this.controls.top.setOpacity(this.options.controlOpacity);
		if ($('content-hints')) {
			$('content-hints').hide();
			}
		if ($('scroll-top-hint')) {
			$('scroll-top-hint').show();
			}
		this.moveTop();
		},


	mouseoutTop: function (event) {
		this.controls.top.removeClassName('hover');
		this.controls.top.setOpacity(0);
		if ($('content-hints')) {
			$('content-hints').show();
			}
		if ($('scroll-top-hint')) {
			$('scroll-top-hint').hide();
			}
		this.stop();
		},


	mouseoverBottom: function (event) {
		this.controls.bottom.addClassName('hover');
		this.controls.bottom.setOpacity(this.options.controlOpacity);
		if ($('content-hints')) {
			$('content-hints').hide();
			}
		if ($('scroll-bottom-hint')) {
			$('scroll-bottom-hint').show();
			}
		this.moveBottom();
		},

	
	mouseoutBottom: function (event) {
		this.controls.bottom.removeClassName('hover');
		this.controls.bottom.setOpacity(0);
		if ($('content-hints')) {
			$('content-hints').show();
			}
		if ($('scroll-bottom-hint')) {
			$('scroll-bottom-hint').hide();
			}
		this.stop();
		},


	mousedown: function () {
		if (this.options.oldStep == null) {
			this.options.oldStep = this.options.step;
			this.options.step = this.options.step * this.options.stepModifier;
			}
		},


	mouseup: function () {
		if (this.options.oldStep != null) {
			this.options.step = this.options.oldStep;
			this.options.oldStep = null;
			}
		},


	mousedownTop: function (event) {
		this.mousedown();
		if (this.options.fasterControlClass) {
			this.controls.top.addClassName(this.options.fasterControlClass);
			}
		},


	mouseupTop: function () {
		this.mouseup();
		if (this.options.fasterControlClass) {
			this.controls.top.removeClassName(this.options.fasterControlClass);
			}
		},


	mousedownBottom: function (event) {
		this.mousedown();
		if (this.options.fasterControlClass) {
			this.controls.bottom.addClassName(this.options.fasterControlClass);
			}
		},


	mouseupBottom: function () {
		this.mouseup();
		if (this.options.fasterControlClass) {
			this.controls.bottom.removeClassName(this.options.fasterControlClass);
			}
		},


	click: function (event) {
		event.stop();
		},

	
	stop: function () {
		if (this.timer != null) {
			clearTimeout(this.timer);
			}
		},

	
	moveTop: function () {
		this.activateBottomControl();
		this.scroller.scrollTop -= this.options.step;
		if (this.options.deactivateControl && this.scroller.scrollTop == 0) {
			this.deactivateTopControl();
			}
		this.timer = setTimeout(this.moveTop.bind(this), this.options.frequency);
		},

	
	moveBottom: function () {
		this.activateTopControl();
		temp = this.scroller.scrollTop;
		this.scroller.scrollTop += this.options.step;
		if (this.options.deactivateControl && this.scroller.scrollTop == temp) {
			this.deactivateBottomControl();
			}
		this.timer = setTimeout(this.moveBottom.bind(this), this.options.frequency);
		},

	
	activateTopControl: function () {
		if (!this.controls.top.active) {
			this.controls.top.active = true;
			if (this.options.activeControlChild) {
				this.controls.top.down(this.options.activeControlChild).show();
				}
			this.controls.top.addClassName(this.options.activeControlClass);
			this.controls.top.observe('mouseover', this.events.mouseoverTop);
			}
		},

	
	activateBottomControl: function () {
		if (!this.controls.bottom.active) {
			this.controls.bottom.active = true;
			if (this.options.activeControlChild) {
				this.controls.bottom.down(this.options.activeControlChild).show();
				}
			this.controls.bottom.addClassName(this.options.activeControlClass);
			this.controls.bottom.observe('mouseover', this.events.mouseoverBottom);
			}
		},

	
	deactivateTopControl: function () {
		this.controls.top.active = false;
		this.controls.top.removeClassName(this.options.activeControlClass);
		this.controls.top.stopObserving('mouseover', this.events.mouseoverTop);
		this.mouseup();
		},

	
	deactivateBottomControl: function () {
		this.controls.bottom.active = false;
		this.controls.bottom.removeClassName(this.options.activeControlClass);
		this.controls.bottom.stopObserving('mouseover', this.events.mouseoverBottom);
		this.mouseup();
		}

	});
