function GetOptionalArg(args, index, defaultValue)
{
	if(args.length > index)
		return args[index];
	else
		return defaultValue;
}

// Arguments: containerId, areaId, [scrollTrackClass], [scrollGripClass], [topMargin]
function ScrollBar(containerId, areaId)
{
	this.ScrollSpeedFactor = 0.05;
	this.ScrollTrack = document.createElement("div");
	this.ScrollTrackClass = GetOptionalArg(arguments, 2, "scroll-track");
	this.ScrollGrip = document.createElement("div");
	this.ScrollGripClass = GetOptionalArg(arguments, 3, "scroll-grip");
	this.TopMargin = GetOptionalArg(arguments, 4, 20);
	this.Container = document.getElementById(containerId);
	this.Area = document.getElementById(areaId);
	
	this.Container.style.overflow = "hidden";
	this.Container.style.position = "relative";
	
	this.Area.style.position = "absolute";
	this.Area.style.top = "0";
	
	this.ScrollTrack.className = this.ScrollTrackClass;
	this.Container.appendChild(this.ScrollTrack);

	this.ScrollGrip.className = this.ScrollGripClass;
	this.ScrollGrip.style.position = "absolute";
	this.ScrollGrip.style.right = "0";
	this.ScrollGrip.style.top = "0";
	this.ScrollTrack.appendChild(this.ScrollGrip);
	
	var ExtraGrip = document.createElement("div");
	
	ExtraGrip.className = "scroll-extra-grip";
	this.ScrollGrip.appendChild(ExtraGrip);
	
	// Add event handlers
	this.Container.onscroll = this.CreateEventHandler("ContainerScroll");	// Capture real scroll events
	// this.ScrollTrack.onmousedown = this.CreateEventHandler("TrackPress");
	// this.ScrollTrack.onmouseup = this.CreateEventHandler("TrackRelease");
	this.ScrollGrip.onmousedown = this.CreateEventHandler("GripStartMove");
	
	if(document.all)
	{
		this.Container.onmousewheel = this.CreateEventHandler("WheelScroll");
		this.ScrollGrip.onmousemove = this.CreateEventHandler("GripMove");
		this.ScrollGrip.onmouseup = this.CreateEventHandler("GripStopMove");
	}
	else
	{
		var Html = document.getElementsByTagName("html")[0];

		this.Container.addEventListener("DOMMouseScroll", this.CreateEventHandler("WheelScroll"), false);
		Html.onmousemove = this.CreateEventHandler("GripMove");
		Html.onmouseup = this.CreateEventHandler("GripStopMove");
	}
	
	// Update size and visibility of scroll bar
	this.UpdateScrollBar();
	
	this.Gripped = false;
	this.LastCursorY = 0;
	
	setInterval(this.CreateCallback("UpdateScrollBar"), 500);
}

ScrollBar.prototype.UpdateScrollBar = function()
{
	if((this.Area.offsetHeight + this.TopMargin) <= this.Container.offsetHeight)
	{
		if(this.ScrollTrack.style.display != "none")
		{
			this.ScrollTo(0);

			// Hide scroll bar altogether
			this.ScrollTrack.style.display = "none";
		}
	}
	else
	{
		this.ScrollTrack.style.display = "block";
		
		// Calculate size of scroll grip
		this.ScrollGrip.style.height = this.ScrollTrack.offsetHeight * (this.Container.offsetHeight / (this.Area.offsetHeight + this.TopMargin)) + "px";
	}
}

ScrollBar.prototype.CreateEventHandler = function(methodName)
{
	var Context = this;
	
	return function(e)
	{
		e = e || window.event;
		
		return Context[methodName](e);
	};
}

ScrollBar.prototype.CreateCallback = function(methodName)
{
	var Context = this;
	
	return function() { return Context[methodName](); };
}

ScrollBar.prototype.ContainerScroll = function(e)
{
	this.Scroll(this.Container.scrollTop);
	this.Container.scrollTop = 0;
}

ScrollBar.prototype.WheelScroll = function(e)
{
	e = e || window.event;
	
	var Delta = 0;
	
	if(e.wheelDelta)
	{
		Delta = -e.wheelDelta / 120;
		
		if(window.opera)
			Delta = -Delta;
	}
	else if(e.detail)
		Delta = e.detail / 3;
	
	this.Scroll(Delta * this.ScrollTrack.offsetHeight * this.ScrollSpeedFactor);
}

// Scrolls to a pixel position of the body
ScrollBar.prototype.ScrollTo = function(position)
{
	var NewGripY = (this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight) * (position / this.Area.offsetHeight);
	
	if(NewGripY < 0)
		NewGripY = 0;
	else if(NewGripY > this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight)
		NewGripY = this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight;
	
	var ScrollPct = NewGripY / (this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight);
	var NewAreaY = -(this.Area.offsetHeight - this.Container.offsetHeight + this.TopMargin) * ScrollPct;
	
	this.ScrollGrip.style.top = NewGripY + "px";
	this.Area.style.top = NewAreaY + "px";
}

ScrollBar.prototype.Scroll = function(delta)
{
	if(this.ScrollTrack.style.display == "none")
		return;
	
	var NewGripY = parseInt(this.ScrollGrip.style.top) + delta;

	if(NewGripY < 0)
		NewGripY = 0;
	else if(NewGripY > this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight)
		NewGripY = this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight;
	
	var ScrollPct = NewGripY / (this.ScrollTrack.offsetHeight - this.ScrollGrip.offsetHeight);
	var NewAreaY = -(this.Area.offsetHeight - this.Container.offsetHeight + this.TopMargin) * ScrollPct;
	
	this.ScrollGrip.style.top = NewGripY + "px";
	this.Area.style.top = NewAreaY + "px";
}

/* ScrollBar.prototype.TrackPress = function(e)
{
	e = e || window.event;
	
	if(e.screenY < this.ScrollGrip.offsetTop)
	{
		this.Scroll(-5);
	}
	else if(e.screenY > this.ScrollGrip.offsetTop + this.ScrollGrip.offsetHeight)
	{
		this.Scroll(5);
	}
}

ScrollBar.prototype.TrackRelease = function(e)
{
} */

ScrollBar.prototype.GripStartMove = function(e)
{
	if(this.ScrollGrip.setCapture)
		this.ScrollGrip.setCapture();

	this.LastCursorY = e.screenY;
	this.Gripped = true;
	
	return false;
}

ScrollBar.prototype.GripMove = function(e)
{
	if(!this.Gripped)
		return;

	this.Scroll(e.screenY - this.LastCursorY);
	this.LastCursorY = e.screenY;
}

ScrollBar.prototype.GripStopMove = function(e)
{
	if(this.ScrollGrip.releaseCapture)
		this.ScrollGrip.releaseCapture();
	
	this.Gripped = false;
}