function positionOf(elem)
{
	ret = {top : 0, left : 0};
	do
	{
		ret.top += elem.offsetTop;
		ret.left += elem.offsetLeft;
	} while((elem = elem.offsetParent) != null);
	return ret;
}

function initScrollMenu()
{
	var yWin = document.documentElement.scrollTop || document.body.scrollTop;
	var hWin = window.innerHeight || document.documentElement.clientHeight;
	var hMenu = scrollMenu.$.clientHeight;
	var yMenu = positionOf(scrollMenu.$).top;
	var goal = yMenu;
	
	if(yWin < yMenu || hWin >= hMenu)
		goal = yWin;
	else if(hWin < hMenu && yWin + hWin > yMenu + hMenu)
		goal = yWin + hWin - hMenu;
		
	// Make sure the menu never appears above the header.
	goal = Math.max(goal, scrollMenu.yStart);
	
	// If the menu is already at the goal, don't do anything.
	if(yMenu == goal)
		return;

	// As soon as the scrollMenu function isn't running, set the lastInit to the
	// current time.  Call scrollMenu(...) in half a second.
	var myInit = {};
	while(scrollMenu.busy || !(scrollMenu.lastInit = myInit)){}
	setTimeout(function(){scrollMenu(myInit, goal);}, 500);
}

function scrollMenu(initTime, goal)
{
	if(scrollMenu.busy = (initTime == scrollMenu.lastInit))
	{
		var yOld = positionOf(scrollMenu.$).top;
		var y = yOld + (goal < yOld ? -1 : 1)
			* Math.max(1, Math.round(Math.abs((goal - yOld) / 3)));
		$(scrollMenu.$).setCSS("top", y + "px");
		if(goal != y)
			setTimeout(function(){scrollMenu(initTime, goal);}, 50);
		scrollMenu.busy = false;
	}
}

$(window).bind("load", function()
{
	scrollMenu.$ = $("#left-menu")[0];
	scrollMenu.yStart = positionOf(scrollMenu.$).top;

	$(window).bind("scroll", initScrollMenu).bind("resize", initScrollMenu);
});