/*--------------------------------------------------------------------------*/
/*  Control.Scroller, version 1.0
/*  Copyright (c) 2008, VAB studio
/*--------------------------------------------------------------------------*/

Control.Scroller = Class.create();
Control.Scroller.scrollers = [];
Control.Scroller.prototype = {
	initialize: function(content, handle, track, options) {
		this.id = "scroller"
		this.content = $(content);
		this.handle = $(handle);
		this.track = $(track);

		var _scroller = this;

		this.options = Object.extend({
			axis: 'vertical',
			onChange: function(value) {
				_scroller.updateView(value);
			},
			onSlide: function(value) {
				_scroller.updateView(value);
			}
		}, options);

		this.options = Object.extend({
			visibleHeight: this.isVertical() ? 300 : this.content.offsetHeight,
			visibleWidth: this.isVertical() ? this.content.offsetWidth : 300,
			delta: 20,
			scrollOnHover: true,
			autoHide: true,
			interval: 100
		}, this.options);

		this.buttons = {
			up: $(this.options.up),
			down: $(this.options.down)
		};

		this.currentValue = 0;

		this.content.style.height = this.options.visibleHeight+"px";
		this.content.style.visibility = "visible";

  		$H(this.buttons).values().each(function(button) {
			if (_scroller.options.scrollOnHover) {
				Event.observe(button, "mouseover", _scroller.buttonAction.bindAsEventListener(_scroller));
				Event.observe(button, "mouseout", _scroller.buttonAction.bindAsEventListener(_scroller));
			} else {
				Event.observe(button, "mousedown", _scroller.buttonAction.bindAsEventListener(_scroller));
				Event.observe(button, "mouseup", _scroller.buttonAction.bindAsEventListener(_scroller));
			}
		});
 		Event.observe(this.content, 'DOMMouseScroll', _scroller.wheel.bindAsEventListener(_scroller));
		Event.observe(this.content, 'mousewheel', _scroller.wheel.bindAsEventListener(_scroller));

		Event.observe(this.content, "scroller:change", _scroller.settings.bind(_scroller));

		this.slider = new Control.Slider(this.handle, this.track, this.options);
	},
	isVertical: function() {
		return this.options.axis == 'vertical';
	},
	settings: function() {
		this.currentValue = 0;

		if (this.options.axis == "vertical") {
			if (this.content.scrollHeight <= this.content.offsetHeight) {
				this.slider.setDisabled();
				if (this.options.autoHide) [this.track, this.handle, this.buttons.up, this.buttons.down].invoke("hide");
			} else {
				this.slider.setEnabled();
				if (this.options.autoHide) [this.track, this.handle, this.buttons.up, this.buttons.down].invoke("show");
			}
		} else {
			if (this.content.scrollWidth <= this.content.offsetWidth) {
				this.slider.setDisabled();
				if (this.options.autoHide) [this.track, this.handle, this.buttons.up, this.buttons.down].invoke("hide");
			} else {
				this.slider.setEnabled();
				if (this.options.autoHide) [this.track, this.handle, this.buttons.up, this.buttons.down].invoke("show");
			}
		}

		this.content.style.height = this.options.visibleHeight+"px";
		this.content.style.visibility = "visible";

		this.slider.setValue(0, 0);
		this.updateView(0);
	},
	buttonAction: function(e) {
		this.multiplier = Event.element(e) == this.buttons.up ? -1 : 1;
		switch (e.type) {
			case "mouseover":
			case "mousedown":
				this.scroll();
				var _scroller = this;
				this.timer = setInterval(function() { _scroller.scroll() }, _scroller.options.interval*10);
				break;
			case "mouseout":
			case "mouseup":
				clearTimeout(this.timer)
				break;
		}
	},
	scroll: function() {
		this.slider.setValueBy((this.options.delta*this.multiplier)/this.options.interval);
	},
	wheel: function(event) {
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120;
			if (Prototype.Browser.Opera) delta = -delta;
		} else if (event.detail) {
			delta = -event.detail/3;
		}
		if (delta) this.slider.setValueBy(-delta/this.options.interval*this.options.delta);
		if (event.preventDefault) event.preventDefault();
	},
	updateView: function(value) {
		this.currentValue = value;
		if (this.options.axis == "vertical") {
			this.content.scrollTop = Math.round(this.currentValue/this.slider.maximum*(this.content.scrollHeight-this.content.offsetHeight));
		} else {
			this.content.scrollLeft = Math.round(this.currentValue/this.slider.maximum*(this.content.scrollWidth-this.content.offsetWidth));
		}
		(this.options.onScroll || Prototype.emptyFunction)(value, this);
	}
}
