

function getElement(id)
{
	if (document.getElementById)
		return document.getElementById(id);
	else
		return document.all[id];
}




var g_scroller = null;

function advance()
{
	g_scroller.advance();
}

function Scroller(minPos, maxPos, startPos)
{
	this.minPos = minPos;
	this.maxPos = maxPos;
	this.cursor = startPos;
	this.numGroups = 0;
	this.groups = new Object; // empty array of ScrollGroups
	this.dir = 0;
	this.frame = 0;
	this.interval = null;

	this.addGroup =	function (group)
					{
						this.groups[ this.numGroups++ ] = group;
						group.dump("init");
					}
	
	this.scroll =	function (dir)
					{
						if (g_scroller != null) // already scrolling... prevent double-click problems
							return;

						var newPos = this.cursor - dir;
						if (newPos<this.minPos-1 || newPos>this.maxPos+1) // +/- 1 allows the first/last book to scroll to the center slot
							return;

						g_scroller = this;
						this.dir = dir;
						this.frame = 0;
						this.interval = window.setInterval(advance, 15); // milliseconds
					}

	this.advance =	function ()
					{
						for (var i=0 ; i<this.numGroups ; i++)
							this.groups[i].advance(this.dir, this.frame);

						// maybe stop the scroll
						++this.frame;
						if (this.frame >= 19)
						{
							window.clearInterval(this.interval);
							g_scroller = null;
							this.cursor = this.cursor - this.dir;
							this.reslot();
							this.dir = 0;
						}
					}

	this.reslot =	function ()
					{
						for (var i=0 ; i<this.numGroups ; i++)
							this.groups[i].reslot(this.dir);
					}
}


function ScrollGroup()
{
	this.slots = new Object;
	this.firstSlot = null;


	this.addSlot =	function (x, y, elementID)
					{
						var curr = new Object; // a slot
						curr.left = x;
						curr.top = y;
						curr.book = getElement(elementID);
						curr.book.style.left = "" + x + "px";
						curr.book.style.top = "" + y + "px";
						curr.book.style.display = "block";
						curr.book.style.zIndex = curr.book.offsetTop;
						curr.label = elementID; // debugging

						if (this.firstSlot == null)
						{
							this.firstSlot = curr;
							curr.next = curr;
							curr.prev = curr;
						}
						else
						{
							var grand = this.firstSlot.prev;
							grand.next = curr;
							curr.prev = grand;
							curr.next = this.firstSlot;
							this.firstSlot.prev = curr;
						}

						curr.prev.dx = curr.left - curr.prev.left;
						curr.prev.dy = curr.top - curr.prev.top;

						curr.dx = curr.next.left - curr.left;
						curr.dy = curr.next.top - curr.top;
					}

	this.advance =	function (dir, frame)
					{
						// slow at beginning and end of travel... faster in the middle
						var steps = dir * (10 - Math.abs(frame - 9));
						
						//if (frame==0)
						//	alert(this.slots[0].book.offsetLeft+","+this.slots[0].book.offsetTop+" steps="+steps+", dx="+this.slots[0].dx+", dy="+this.slots[0].dy)
						for (var slot=this.firstSlot ; slot.next!=this.firstSlot ; slot=slot.next)
							this.advanceSlot(slot, dir, steps);
						this.advanceSlot(slot, dir, steps);
						//if (frame==18)
						//	alert(this.slots[0].book.offsetLeft+","+this.slots[0].book.offsetTop+" steps="+steps+", dx="+this.slots[0].dx+", dy="+this.slots[0].dy)
					}
	
	this.advanceSlot =	function (slot, dir, steps)
						{
							var dest;
							var deltas;
							if (dir > 0)
							{
								dest = slot.next;
								deltas = slot;
							}
							else
							{
								dest = slot.prev;
								deltas = dest;
							}

							var book = slot.book;
							book.style.left = book.offsetLeft + Math.floor(0.5+(steps * deltas.dx / 100)) + "px";
							book.style.top = book.offsetTop + Math.floor(0.5+(steps * deltas.dy / 100)) + "px";
							book.style.zIndex = book.offsetTop; // the just-updated value
						}

	this.reslot =	function (dir)
					{
						this.dump("before");
						var link = (dir<0 ? "next" : "prev");

						//this.firstSlot[(dir>0 ? "next" : "prev")].book.style.visibility = "hidden";

						var firstBook = this.firstSlot.book;
						for (var slot=this.firstSlot ; slot[link]!=this.firstSlot ; slot=slot[link])
							slot.book = slot[link].book;
						slot.book = firstBook;

						//this.firstSlot[(dir<0 ? "next" : "prev")].book.style.visibility = "visible";

						this.dump("after");
					}

	this.dump =	function (title)
				{
					/*
					var debug = document.forms[0].debug;
					debug.value = debug.value + title + "\r\n";
					for (var slot=this.firstSlot ; slot.next!=this.firstSlot ; slot=slot.next)
						debug.value = debug.value + "("+slot.prev.book.id+")<--"+slot.book.id+"-->("+slot.next.book.id+")\r\n";
					debug.value = debug.value + "("+slot.prev.book.id+")<--"+slot.book.id+"-->("+slot.next.book.id+")\r\n";
					*/
				}
}
