/*JS for the Scroller*/
function ScrollJob(containerElement, verticalOrientation, elementSize)
{
this.maxSpeed = 5.5;      // speed limit in pixel per interval
this.minSpeed = 0.5;       // snail speed in pixel per interval
this.fAcceleration = 1.5;  // increasing factor
this.fSlowdown = 1.1;      // decreasing factor
this.scrollInterval = 40;  // interval in msec

this.container = containerElement; 
this.verticalOrientation = verticalOrientation; 
this.elementSize = elementSize; 
this.direction = 1; 
this.speed = this.minSpeed; 
this.timer = null; 
this.pausetimer = null; 
this.stopping = false; 
this.elementCount = 0; 
this.targetOffs = -1; 

ScrollJob.prototype.setupContainer = function(job)
{
	var p = job.container; 
	var strip = scrollManager.findFirstDiv(p); 
	if (strip == null)
	return; 
	if (!p.scrollingSetup) 
	{
	var elements = scrollManager.getElements(strip); 
	for (var i=0; i<elements.length; i++)
		strip.appendChild(elements[i].cloneNode(true)); 
	p.scrollingSetup = true; 
	job.elementCount = elements.length; 
	}
}
this.setupContainer(this); 

ScrollJob.prototype.slide = function(job)
{
	var p = job.container; 
	if (job.targetOffs >= 0)
	{
	var distance = job.targetOffs - (verticalOrientation ? p.scrollTop : p.scrollLeft); 
	if (distance >= job.elementCount * job.elementSize - 1){
		distance -= job.elementCount * job.elementSize; 
	}
	else if (distance <= -(job.elementCount * job.elementSize - 1)){
		distance += job.elementCount * job.elementSize; 

	}
	if (Math.abs(distance) > 1)
	{
		job.direction = (distance < 0) ? -1 : 1; 
		job.speed = Math.max(job.minSpeed, Math.abs(distance) * 0.5); 
	}
	else
	{
		if (verticalOrientation)
		p.scrollTop = job.targetOffs; 
		else
		p.scrollLeft = job.targetOffs; 
		job.targetOffs = -1; 
		job.speed = 0; 
	}
	}
	if (verticalOrientation)
	{
	p.scrollTop += job.direction * job.speed; 
	if ((job.direction > 0) && (p.scrollTop >= job.elementSize * job.elementCount)) 
		p.scrollTop = 0;  
	else if ((job.direction < 0) && (p.scrollTop <= 1))
		p.scrollTop = job.elementSize * job.elementCount; 
	}
	else
	{
	p.scrollLeft += job.direction * job.speed; 
	if ((job.direction > 0) && (p.scrollLeft >= job.elementSize * job.elementCount)){  
		p.scrollLeft = -324; 
	}
	else if ((job.direction < 0) && (p.scrollLeft <= 1)){  
		p.scrollLeft = job.elementSize * job.elementCount; 
	}

 	}
	if (job.stopping)
	{
	job.speed /= job.fSlowdown; 
	if (Math.abs(job.speed) < job.minSpeed)
	{
		window.clearInterval(job.timer); 
		job.timer = null; 
		job.stopping = false; 
	}
	}
	else if (job.speed < job.minSpeed) 
	job.speed = job.minSpeed; 
	else if (job.speed * job.fAcceleration < job.maxSpeed)
	job.speed *= job.fAcceleration; 
	else
	job.speed = job.maxSpeed; 

}

this.getPosition = function() 
{
	var p = Math.round((this.verticalOrientation ? this.container.scrollTop : this.container.scrollLeft) / this.elementSize) + 1; 
	if (p > this.elementCount)
	p -= this.elementCount; 
	return p; 
}

this.start = function(direction) 
{
	if (this.stopping)
	this.stopping = false; 
	if (this.speed < this.minSpeed)
	this.speed = this.minSpeed; 
	var job = this; 
	job.direction = direction; 
	if (this.timer == null)
	{
	var fn = this.slide; 
	this.timer = window.setInterval(function() { fn(job); }, this.scrollInterval); 
	}
}

this.stop = function()
{
	this.scrollAt(this.getPosition()); 
}

this.scrollAt = function(elementPos)
{
	this.targetOffs = Math.min((this.elementCount-1) * this.elementSize, Math.max(0, (elementPos-1) * this.elementSize)); 
	this.stopping = true; 
	if (this.timer == null)
	{
	var job = this; 
	var fn = this.slide; 
	this.timer = window.setInterval(function() { fn(job); }, this.scrollInterval); 
	}
}

this.pause = function(msec)
{
	this.speed = 0; 
	this.stopping = true; 
	this.slide(this); 
	var intv = this.scrollInterval; 
	var job = this; 
	var fn = this.slide; 
	if (this.pausetimer != null)
	{
	window.clearTimeout(this.pausetimer); 
	this.pausetimer = null; 
	}
	this.pausetimer = window.setTimeout(function() { job.timer = window.setInterval(function() { fn(job); }, intv); }, msec);  
}

this.update = function()
{
	this.slide(this); 
}
}

function ScrollManager()
{
this.scrollJobs = new Array(); 

this.getJob = function(containerElement, create)
{
	for (var i=0; i<this.scrollJobs.length; i++)
	if (this.scrollJobs[i].container == containerElement)
		return this.scrollJobs[i]; 
	if (create)
	{
	var nj = new ScrollJob(containerElement, false, 100); 
	this.scrollJobs.push (nj); 
	return nj; 
	}
	else 
	return null; 
}

this.findFirstDiv = function(container)
{
	for (var i=0; i<container.childNodes.length; i++)
	if (container.childNodes[i].tagName == "DIV")
		return container.childNodes[i]; 
	return null; 
}

this.findNextDiv = function(sibling)
{
	var e = sibling.nextSibling; 
	while ((e) && (e != null))
	{
	if (e.tagName == "DIV")
		return e; 
	e = e.nextSibling; 
	}
	return null; 
}


this.findPrevDiv = function(sibling)
{
	var e = sibling.previousSibling; 
	while ((e) && (e != null))
	{
	if (e.tagName == "DIV")
		return e; 
	e = e.previousSibling; 
	}
	return null; 
}

this.getElements = function(strip)
{
	var res = new Array(); 
	for (var i=0; i<strip.childNodes.length; i++)
	if (strip.childNodes[i].tagName == "DIV")
		res.push(strip.childNodes[i]); 
	return res; 
}

this.startSlide = function(containerElement, direction, verticalOrientation, elementSize) 
{
	if (containerElement == null) 
	return; 
	var job = this.getJob(containerElement, true); 
	job.verticalOrientation = verticalOrientation; 
	job.elementSize = elementSize; 
	job.start(direction); 
}

this.stopSlide = function(containerElement) 
{
	if (containerElement == null) 
	return; 
	var job = this.getJob(containerElement, false); 
	if (job != null)
	job.stop(); 
}

this.jump = function(containerElement, direction, verticalOrientation, elementSize, number) 
{
	var job = this.getJob(containerElement, true);
	job.container.scrollLeft+=direction*job.elementSize*number;
	if(job.container.scrollLeft<=0){
	job.container.scrollLeft=job.elementSize*job.elementCount;
	}
	else{
	scrollManager.stopSlide(containerElement);
	}
}

this.jumpTo = function(containerElement, verticalOrientation, elementSize, atPosition)
{
	if (containerElement == null) 
	return; 
	var job = this.getJob(containerElement, true); 
	job.verticalOrientation = verticalOrientation; 
	job.elementSize = elementSize; 
	var pos = Math.min(Math.max(1, atPosition), job.elementCount); 
	job.scrollAt(pos); 
}
}

var scrollManager = new ScrollManager();
