var Scrollbar = function (areaId, trackId, thumbId, thumbImgId, areaH) {
	this.area			= document.getElementById(areaId);
	this.track			= document.getElementById(trackId);
	this.thumb			= document.getElementById(thumbId);
	this.thumbImg		= document.getElementById(thumbImgId);
	this.areaViewH		= areaH;
	this.areaTotalH		= this.area.scrollHeight;
	this.areaScrollH	= this.areaViewH - this.areaTotalH;
	this.pixelRatio		= this.areaViewH / this.areaTotalH;
	this.thumbH			= Math.round(this.areaViewH * this.pixelRatio);
	this.thumbImg.height= this.thumbH;
	this.mouseFocus		= false;
	this.slider			= YAHOO.widget.Slider.getVertSlider(trackId, thumbId, 0, (this.areaViewH - this.thumbH));
	// optional element id to log to
	this.logTarget		= null;
	// set slider callbacks
	var sb = this;
	this.slider.onSlideStart	= function () { sb.onSlideStart() };
	this.slider.onSlideEnd		= function () { sb.onSlideEnd() };
	this.slider.onChange		= function (o) { sb.onSlideChange(o) };

	this.area.style.overflow = "hidden";
	if (window.addEventListener) {
		this.area.addEventListener("mouseover", function () { sb.onAreaMouseOver(); }, false);
		this.area.addEventListener("mouseout", function () { sb.onAreaMouseOut(); }, false);
		this.track.addEventListener("mouseover", function () { sb.onAreaMouseOver(); }, false);
		this.track.addEventListener("mouseout", function () { sb.onAreaMouseOut(); }, false);
		this.area.addEventListener('DOMMouseScroll', function (event) { sb.onAreaMouseWheel(event); }, false); // DOMMouseScroll is for Mozilla.
	} else {
		this.area.onmouseover = function () { sb.onAreaMouseOver(); };
		this.area.onmouseout = function () { sb.onAreaMouseOut(); };
		this.track.onmouseover = function () { sb.onAreaMouseOver(); };
		this.track.onmouseout = function () { sb.onAreaMouseOut(); };
		this.area.onmousewheel = function (event) { sb.onAreaMouseWheel(event); }; // IE/Opera
	}
}

var sbp = Scrollbar.prototype;

sbp.onSlideStart = function () {
	this.slider.setYConstraint(0, (this.areaViewH - this.thumbH));
	this.log('onSlideStart');
}
sbp.onSlideEnd = function () {
	this.log('onSlideEnd: ' + this.slider.getValue());
}
sbp.onSlideChange = function (offset) {
	var ratio = offset / (this.areaViewH - this.thumbH);
	var scrollTop = Math.round(this.areaScrollH * ratio);
	this.area.scrollTop = -scrollTop;
	//this.log('onSlideChange: ' + this.slider.getValue());
}

sbp.update = function () {
	var st = this.area.scrollTop;
	var sh = this.area.scrollHeight - this.areaViewH;
	var ratio = st / sh;
	var ymax = this.areaViewH - this.thumbImg.height;
	var y = Math.round(ymax * ratio);
	// disable the onChange handler temporarily
	this.slider.onChange = function () {};
	// set the new slider value
	//this.slider.setValue(y);
	// (this is to attempt to prevent the slider going out of bounds)
	var t = this.slider.topConstraint;
	var b = this.slider.bottomConstraint;
	this.slider.setValue(Math.min(Math.max(y, t), b));
	// enable the onChange handler again
	var sb = this;
	this.slider.onChange = function (o) { sb.onSlideChange(o) };
}

sbp.onAreaMouseOver = function () {
	this.mouseFocus = true;
}
sbp.onAreaMouseOut = function () {
	this.mouseFocus = false;
}
sbp.onAreaMouseWheel = function (event) {
	
	if (!this.mouseFocus) return;

	var delta = 0;
	if (!event) event = window.event; // for IE
	if (event.wheelDelta) {
		// IE/Opera
		delta = event.wheelDelta / 120;
		// In Opera 9, delta differs in sign as compared to IE.
		if (window.opera) delta *= -1;
	} else if (event.detail) {
		// Mozilla
		// In Mozilla, sign of delta is different than in IE.
		// Also, delta is multiple of 3.
		delta = -event.detail / 3;
	}
	// If delta is nonzero, handle it.
	// Basically, delta is now positive if wheel was scrolled up,
	// and negative, if wheel was scrolled down.
	if (delta) {
		this.area.scrollTop -= (delta * 25);
		this.update();
	}
	// Prevent default actions caused by mouse wheel.
	// That might be ugly, but we handle scrolls somehow
	// anyway, so don't bother here..
	if (event.preventDefault) event.preventDefault();
	event.returnValue = false;
}

sbp.log = function (msg) {
	if (this.logTarget == undefined) return;
	this.logTarget.innerHTML = msg + "<br>" + this.logTarget.innerHTML;
}
