/*
Part of JJLIB.
Copyright (c) 2009, Wisebusiness Ltd. All rights reserved. Unauthorised re-use or redistribution of any part of this file is strictly prohibited.
Developer: James Mistry
*/

SCROLLER_DIRECTION_UP = 0;
SCROLLER_DIRECTION_LEFT = 1;
SCROLLER_DIRECTION_FADE = 2;

function jjlib_scroller(itemclassname, container, direction) {
	
	if (itemclassname == null) itemclassname = "scroller_item";
	
	this.container = container;
	this.direction = direction;
	this.speed = 5;
	this.interval = 0;
	this.paused = false;
	this.ScrollerItemClassName = itemclassname;
	this.pauselvl = 0;
	
	this.timerhandle = null;
	
	document.getElementById(this.container).style.position = "relative";
	document.getElementById(this.container).style.overflow = "hidden";
	
	this.FindScrollerItems = function() {
		// Modified version of getElementsByClass by AnyExample.com.
		var searchClass = this.ScrollerItemClassName;
		var domNode = document.getElementById(this.container);
		var tagName = 'div';
		var el = new Array();
		var tags = domNode.getElementsByTagName(tagName);
		var tcl = " "+searchClass+" ";
		for(i=0,j=0; i<tags.length; i++) {
			var test = " " + tags[i].className + " ";
			if (test.indexOf(tcl) != -1)
				el[j++] = tags[i];
		}
		return el;
	}
	
	var itms = this.FindScrollerItems();
	
	for(var i=0;i<itms.length;i++){
		
		itms[i].style.position = "absolute";
		
	}
	
	this.GetItemClassName = function() {
		
		return this.ScrollerItemClassName;
		
	}
	
	this.SetItemClassName = function(NewClass) {
		
		this.ScrollerItemClassName = NewClass;
		
	}
	
	this.GetSpeed = function() {
		
		return this.speed;
		
	}
	
	this.SetSpeed = function(NewSpeed) {
		
		this.speed = NewSpeed;
		
	}
	
	this.GetInterval = function() {
		
		return this.interval;
		
	}
	
	this.SetInterval = function(NewInterval) {
		
		this.interval = NewInterval;
		
	}
	
	this.Start = function() {
		
		var items = this.FindScrollerItems();
		var con = document.getElementById(this.container);
		if (con == null) return false;
		
		if (this.direction == SCROLLER_DIRECTION_UP) {
			
			if ((!this.paused) && (!this.active)) {
				
				var top_pos = parseInt(con.clientTop) + (parseInt(con.offsetHeight));
				var totheight = 0;
				var tmpheight = 0;
				
				for (var i=0;i<items.length;i++) {
					tmpheight = 0;
					for (var j=i-1;j>=0;j--) {
						tmpheight = tmpheight + items[j].offsetHeight;
					}
					items[i].style.top = (top_pos + tmpheight) + "px";
					totheight += items[i].offsetHeight;
					items[i].style.visibility = "visible";
				}
				
				this.top_pos = top_pos;
				this.totheight = totheight;
				var sticky = true;
				
			} else {
				var sticky = false;
				if (this.pauselvl > 1) {
					this.pauselvl--;
					return;
				} else {
					this.paused = false;
					if (this.timerhandle != null) clearInterval(this.timerhandle);
				}
			}
			
			var speedcalc = this.speed;
			var itime = this.GetInterval();
			var pobj = this;
			var itmtop = 0;
			var bound = 0;
			var diff = 0;
			this.active = true;
			this.timerhandle = setInterval(function() {
				if (pobj == null) return;
				for(var i=0;i<items.length;i++){
					if ((items[i].style.top=="0px")&&(itime>0)&&(sticky)) {
						pobj.Pause();
						setTimeout(function() { pobj.Start(); }, itime);
						sticky = false;
					}
					
					itmtop = parseInt(items[i].style.top);
					bound = 0;
					diff = 0;
					if (((itmtop - speedcalc) <= (bound)) && (itmtop > bound) && (itime > 0)) {
						diff = bound - itmtop;
						for (var l=0;l<items.length;l++) {
							if (l != i) items[l].style.top=(parseInt(items[l].style.top) + diff) + "px";
						}
						items[i].style.top = "0px";
					} else {
						items[i].style.top = (parseInt(items[i].style.top)-speedcalc)+"px";
					}
					
					if (items[i].offsetTop<=(-1*(pobj.totheight))) items[i].style.top=pobj.top_pos+"px";
				}
				if (!sticky) sticky = true;
			}, 75);
			
		} else if (this.direction == SCROLLER_DIRECTION_LEFT) {
			
			if ((!this.paused) && (!this.active)){
				
				var left_pos = parseInt(con.clientLeft) + parseInt(con.offsetWidth);
				var totwidth = 0;
				var tmpwidth = 0;
				
				for (var i=0;i<items.length;i++) {
					tmpwidth = 0;
					for (var j=i-1;j>=0;j--) {
						tmpwidth = tmpwidth + items[j].offsetWidth;
					}
					items[i].style.left = (left_pos + tmpwidth) + "px";
					totwidth += items[i].offsetWidth;
					items[i].style.visibility = "visible";
				}
				
				this.left_pos = left_pos;
				this.totwidth = totwidth;
				this.sticky = true;
				
			} else {
				if (this.pauselvl > 1) {
					this.pauselvl--;
					return;
				} else {
					this.paused = false;
					if (this.timerhandle != null) clearInterval(this.timerhandle);
				}
			}
			
			var speedcalc = this.speed;
			var itime = this.GetInterval();
			var pobj = this;
			var itmleft = 0;
			var bound = 0;
			var diff = 0;
			this.active = true;
			this.timerhandle = setInterval(function() {
				if (pobj == null) return;
				con = document.getElementById(pobj.container);
				for(var i=0;i<items.length;i++){
					if ((items[i].style.left=="0px")&&(itime>0)&&(pobj.sticky)) {
						pobj.Pause();
						setTimeout(function() { pobj.Start(); }, itime);
						pobj.sticky = false;
					} else pobj.sticky = true;
					
					itmleft = parseInt(items[i].style.left);
					bound = 0;
					
					if (((itmleft - speedcalc) <= (bound)) && (itmleft > bound) && (itime > 0)) {
						diff = bound - itmleft;
						for (var l=0;l<items.length;l++) {
							if (l != i) items[l].style.left=(parseInt(items[l].style.left) + diff) + "px";
						}
						items[i].style.left = "0px";
					} else {
						items[i].style.left=(parseInt(items[i].style.left)-speedcalc)+"px";
					}
					
					if (items[i].offsetLeft<=(-1*(pobj.totwidth))) items[i].style.left=pobj.left_pos+"px";
					
				}
				if (!pobj.sticky) pobj.sticky = true;
			}, 75);
			
		} else if (this.direction == SCROLLER_DIRECTION_FADE) {
			
			// Requires jjlib.fader.js
			
			if ((!this.paused) && (!this.active)) {
				
				var left_pos = parseInt(con.clientLeft);
				
				for (var i=0;i<items.length;i++) {
					items[i].style.left = left_pos + "px";
					if (i==0) items[i].style.opacity = "1";
					else items[i].style.opacity = "0";
					if (i==0) items[i].style.filter = "alpha(opacity=100)";
					else items[i].style.filter = "alpha(opacity=0)";
					if (i==0) items[i].style.display = "block";
					else items[i].style.display = "none";
					items[i].id = this.ScrollerItemClassName + "_scroller_item_" + i;
					items[i].style.visibility = "visible";
				}
				
			} else {
				if (this.pauselvl > 1) {
					this.pauselvl--;
					return;
				} else {
					this.paused = false;
					return;
				}
				
			}
			
			var itime = this.GetInterval();
			if (itime == null) return false;
			var citm = 0;
			var vis = false;
			var pobj = this;
			var first_run = true;
			
			this.active = true;
			this.timerhandle = setInterval(function() {
				if (pobj == null) return;
				if (pobj.paused) return;
				
				if (first_run) {
					
					var fdr = new jjlib_fader(pobj.ScrollerItemClassName + "_scroller_item_0", FADE_DIRECTION_OUT);
					fdr.Fade(true);
					first_run = false;
					citm++;
					
				}
				
				if (citm >= items.length) {
					citm = 0;
					litm = -1;
				}
				
				if ((citm == 0) && (!first_run)) var litm = items.length - 1;
				else var litm = citm - 1;
				
				if (document.getElementById(pobj.ScrollerItemClassName + "_scroller_item_" + litm) != null) {
					var ofdr = new jjlib_fader(pobj.ScrollerItemClassName + "_scroller_item_" + litm, FADE_DIRECTION_OUT);
					ofdr.Fade(true);
				}
				
				if (document.getElementById(pobj.ScrollerItemClassName + "_scroller_item_" + citm) != null) {
					document.getElementById(pobj.ScrollerItemClassName + "_scroller_item_" + citm).style.display = "block";
					var fdr = new jjlib_fader(pobj.ScrollerItemClassName + "_scroller_item_" + citm, FADE_DIRECTION_IN);
					fdr.Fade(true);
				}
				
				citm++;
			}, itime);
			
		}
		
	}
	
	this.Pause = function() {
		
		if (this.paused) {
			this.pauselvl++;
			return;
		} else {
			this.paused = true;
			this.pauselvl = 1;
		}
		if (this.direction != SCROLLER_DIRECTION_FADE) {
			if (this.timerhandle == null) return;
			clearInterval(this.timerhandle);
			this.timerhandle = null;
			this.active = false;
		}
		
	}
	
	return true;
	
}
