
/* Allow use of mouse wheel */
Object.extend(Event, {
	wheel:function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail/3;	}
		return Math.round(delta); //Safari Round
	}
});

/* Scroller class, applies scrolling behaviour to a given div using the given scroll buttons */
var Scroller = Class.create({
	/* Approximate refresh speed. Real value may be higher/lower due to timer inaccuracies */
	REFRESH_SPEED_MS: 20,
	/* If refresh is occuring slower than this, cap scroll distance to prevent massive scroll jumps */
	MAX_REFRESH_DELAY_MS: 500,
	/* Scrolling speed */
	SCROLL_PIXELS_PER_SECOND:200,
	/* Wheel scrolling speed */
	SCROLL_PIXELS_PER_WHEEL_NOTCH: 20,

	initialize: function(contentId, downId, upId) {
		this.content = document.getElementById(contentId);
		this.direction = 1;
		this.timer = null;
		this.previousTime = null;
		
		var down = document.getElementById(downId);
		var up = document.getElementById(upId);
		
		if (this.content == null) { throw "No content element found for scrolling with id: " + contentId; }
		if (down == null) { throw "No down scroller found with id: " + downId; }
		if (up == null) { throw "No up scroller found with id: " + upId; }
		
		Event.observe(down, 'mousedown', this.scrollDown.bind(this));
		Event.observe(up, 'mousedown', this.scrollUp.bind(this));
		Event.observe(down, 'mouseup', this.stopScrolling.bind(this));
		Event.observe(up, 'mouseup', this.stopScrolling.bind(this));
		Event.observe(down, 'mouseout', this.stopScrolling.bind(this));
		Event.observe(up, 'mouseout', this.stopScrolling.bind(this));
		
		Event.observe(this.content, 'mousewheel', this.scrollWheel.bindAsEventListener(this));
		Event.observe(this.content, 'DOMMouseScroll', this.scrollWheel.bindAsEventListener(this));
		
		this.content.style.overflow = 'hidden';
	},
	
	scrollUp: function() {
		this.direction = 1;
		this.startScrolling();
	},
	
	scrollDown: function() {
		this.direction = -1;
		this.startScrolling();
	},
	
	startScrolling: function() {
		if (this.timer == null) {
			this.scroll();
		}
	},
	
	stopScrolling: function() {
		if (this.timer !=  null) {
			window.clearTimeout(this.timer);
			this.timer = null;
			this.previousTime = null;
		}
	},
	
	scroll: function() {
		var time = new Date().getTime();
		if (this.previousTime != null) {
			var deltaTime = time - this.previousTime;
			var deltaScroll = this.direction * this.SCROLL_PIXELS_PER_SECOND * deltaTime / 1000;
			this.content.scrollTop = this.content.scrollTop - deltaScroll;
		}
		this.previousTime = time;
		this.timer = window.setTimeout(this.scroll.bind(this), this.REFRESH_SPEED_MS);
	},
	
	scrollWheel: function(event) {
		var deltaWheel = Event.wheel(event);
		var deltaScroll = deltaWheel * this.SCROLL_PIXELS_PER_WHEEL_NOTCH;
		this.content.scrollTop = this.content.scrollTop - deltaScroll;
	}
});

