// Javascript One Div Scroller v1
// May 1, 2006
// by tieg zaharia
//  
// Has been minimally tested in:
//   MAC:   Safari, Firefox 1.0.7/1.5
//   PC:    IE 5.5/6
//   LINUX: Firefox (glitchy)
//
// This is a JS script for a horizontal (left or right) scroller that 
// can be used multiple times on a page. It works by taking the .scroll_chunk and duplicating
// it enough times to extend more than past the parent DIV so that the scroller will always
// be full regardless of the what you have inside of it (unlesss that is nothing).
//
// To use more than once, duplicate the HTML/CSS/JS,
// put the HTML inside #scroller_wrapper, and give it a different name than 'scroller'.
//
// KNOWN BUGS: 
//  * stepLeft() doesn't work as it ideally should, and should be fixed someday (hopefully
//    using DOM instead of style.left)
//  * scroller gets slower the more scrollers you are running (including in other browsers)
//  * accelerate functions not currently working (but they have been working in the past, 
//    so they will be fixed one day)
//
// I WOULD LOVE TO HEAR SUGGESTIONS/QUESTIONS : tieg dot zaharia at gmail dot com
//
// *** CSS ***
// #scroller_wrapper {width:500px /* changeable */;height:100px /* changeable */;top:20px /* changeable */;left:20px /* changeable */;overflow:hidden;position:relative;}
// #scroller {z-index:1 /* changeable */;visibility:hidden;overflow:hidden;white-space:nowrap;position:absolute;left:0px /* changeable */;top:0px /* changeable */;}
// #scroller div.scroll_chunk, #scroller div.scroll_chunk * {display:inline;}
//
// *** JS (to initialize scroller after the contents have loaded) ***
// // 3 things should have the same name: 
// //  1) the new Scroller reference variable
// //  2) the parameter you pass to Scroller()
// //  3) and the id of the DIV that contains DIV#scroll_chunk (everything goes inside DIV#scroll_chunk)
// scroller = new Scroller('scroller');
// scroller.show();
// scroller.populate();
// scroller.play(scroller);

// *** HTML for REGULAR PLAY ***
// <div id="scroller_wrapper">
//    <div id="scroller"><div class="scroll_chunk">STUFF GOES HERE</div></div>
// </div>

var deceleRate; // this is used as a incrementally decelerating STEP value for Scroller
var deceleFlag = false; // this is used as a FLAG so that you can stop the deceleration


function Scroller(ref) {
	this.name = ref;
	this.wrapper = document.getElementById(ref);
	this.parent = this.wrapper.parentNode;
	this.interval = null;
	this.firstChild = this.wrapper.firstChild;
	this.lastChild = this.wrapper.lastChild;
	this.childWidth = this.wrapper.firstChild.offsetWidth;

	// properties that can be changed to affect scroller movement
	this.step = 1;
	this.speed = 15;
	this.direction = 'right';

	// Scroller functions
	this.show = show;
	this.hide = hide;
	this.populate = populate;
	this.play = play;
	this.stop = stop;
	this.resume = resume;
	
	function show() { this.wrapper.style.visibility='visible'; }

	function hide() { this.wrapper.style.visibility='hidden'; }

	function populate() {
		var curChunk = this.firstChild; 
		var count = 1;
		while(this.wrapper.lastChild.offsetLeft+this.childWidth<this.parent.offsetWidth+this.wrapper.lastChild.offsetWidth&&count<50) {
			var newChunk = curChunk.cloneNode(true);
			this.wrapper.appendChild(newChunk);
			count++;
		}
	}

	function play() {
		if (this.interval) this.stop();
		if (this.direction=='left') { this.interval = setInterval("stepLeft("+this.name+")",this.speed); }
		if (this.direction=='right') { this.interval = setInterval("stepRight("+this.name+")",this.speed); }
	}

	function stop() {
		clearInterval(this.interval);	
	}

	function resume() {
		if (this.interval) this.stop();
		if (this.direction=='left') this.interval = setInterval("stepLeft("+this.name+")",this.speed);
		if (this.direction=='right') this.interval = setInterval("stepRight("+this.name+")",this.speed);
	}

}

// note: had to put the following functions outside of the Scroller object
//       because setInterval wouldn't recognize them as Scroller functions
//       (anyone know how to fix that?)
function stepLeft(ref) {
	ref.wrapper.style.left=ref.wrapper.offsetLeft-ref.step+'px';
	if(ref.wrapper.offsetLeft<=0-ref.firstChild.offsetWidth) {
		ref.wrapper.appendChild(ref.firstChild);
		ref.wrapper.style.left='0px';
		ref.firstChild=ref.wrapper.firstChild;
	}
}

function stepRight(ref) {
	ref.wrapper.style.left=ref.wrapper.offsetLeft+ref.step+'px';
	if(ref.wrapper.offsetLeft>=5) {
		ref.wrapper.style.left=ref.wrapper.offsetLeft-ref.wrapper.firstChild.offsetWidth+'px';
	}
}

function recursiveStop(ref) {
	if (ref.step>0 && deceleFlag==true) {
		deceleRate = deceleRate + 10;
		setTimeout("recursiveStop("+ref.name+")", deceleRate);
		if (ref.step==1) ref.step--;
		else ref.step = ref.step - 2;
	} else {
		deceleFlag==false;
	}
}
function accelerateStop(ref) {
	if (ref.interval) {
		deceleRate = ref.speed;
		deceleFlag = true;
		setTimeout("recursiveStop("+ref.name+")",deceleRate);
	}
	return true;
}

function acceleratePlay(ref,direction,speed,step) {
	ref.deceleFlag = false;
	if (ref.interval) ref.stop();
	ref.direction = direction;
	ref.speed = speed;
	ref.step = step;
	if (ref.direction=='left') ref.interval = setInterval("stepLeft("+ref.name+")",ref.speed);
	if (ref.direction=='right') ref.interval = setInterval("stepRight("+ref.name+")",ref.speed);
}



