// -----------------------------------------------------------------------------------
// COPYRIGHT (C) Paul Davis 2005-2008. All rights reserved. 
// You may not copy or distribute this script without the authors permission.
// -----------------------------------------------------------------------------------

function getAsNumber (astring) {
	astring = String(astring);
	var count = (arguments.length > 1) ? arguments[1] - 1 : 0;
	var matches = astring.match(/[0-9\-]+/g);
	if (!matches || (count > matches.length))
		return 0;
	return Number(matches[count]);
}

// -----------------------------------------------------------------------------------

function popUp (path) {
	var js = "var d = document.getElementById('pic'); var x = Math.max(d.offsetWidth, d.clientWidth); var y = Math.max(d.offsetHeight, d.clientHeight); window.resizeTo(x + 40 + window.outerWidth - window.innerWidth, y + 40 + window.outerHeight - window.innerHeight);";
	var w = window.open('', 'Picture', 'toolbar=no,menubar=no,location=no,resizable=yes,scrollbars=no,status=no');
	w.document.write('<html><head></head><body><img id="pic" src="' + path + '" onload="' + js + '"></body></html>');
	w.document.close();
}

// -----------------------------------------------------------------------------------

function getPageDimension (width){
	var x, y;
	if (window.innerHeight && window.scrollMaxY) {	
		x = window.innerWidth + window.scrollMaxX;
		y = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		x = document.body.scrollWidth;
		y = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		x = document.body.offsetWidth;
		y = document.body.offsetHeight;
	}
	return (width) ? x : y;
}

// -----------------------------------------------------------------------------------

function SlideShow (varname, elid, atype, amode, aslidetime, atranstime, valuearray) {

	this.name = varname;
	this.type = atype;	// image, text
	this.mode = amode;	// transition type
	
	this.port = null;	// screen container for images/divs and controls (parent of this.el)
	this.black = null;	// screen fade element (outside this.port)
	this.progress = null;	// element containing the current image number
		
	this.value = valuearray;
	this.cursor = 0;
	this.nextcursor = 1;
	this.count = 2;		// concurrrent images to display in div
	this.spacing = 0;	// space between elements - calculated co-ords
	this.centering = false;	// automatic horizontyal centering
	// attributes of images/divs
	this.width = 0;		// width of each image : 0 = auto
	this.height = 0;	// height of each image : 0 = auto
	this.onmouseover = '';
	this.onmouseout = '';
	this.onclick = '';
	
	this.slidetime = aslidetime;
	this.slideinterval = 0;
	this.transtime = atranstime;
	this.transinterval = 0;
	this.playing = false;
	
	this.ie = (navigator.appName.indexOf("Microsoft") > -1);
	this.fps = (this.ie) ? 15 : 25;
	
	this.opacity = 1;
	this.offset = 0;
	this.direction = -1;
	this.vertical = false;
	this.flag = false;
		
	this.elid = elid;
	this.el = null;		// the containing div or block
	this.el_width  = 0;
	this.el_height = 0;

	// methods
	
	// system ----------------------------------------------------------------
	
	this.prime = function (elid) {
		elid = (elid) ? elid : this.elid;
		if (!this.el || (elid != this.elid)) {
			if (document.getElementById(elid)) {
				this.elid = elid;
				this.el = document.getElementById(elid);
			} else {
				//alert("SlideShow error : Can't find element with id = ".elid);
			}
		}
		if (this.el) {
			this.el_width  = Math.max(this.el.clientWidth,  this.el.offsetWidth );
			this.el_height = Math.max(this.el.clientHeight, this.el.offsetHeight);
			return true;
		}
		return false;
	}
	
	// ----------------------------------------------------------------

	this.prime(elid);
	
	// ----------------------------------------------------------------

	this.dump = function () {
		clearInterval(this.slideinterval);
		clearInterval(this.transinterval);
		this.playing = false;
		while (this.value.length)
			this.value.shift();
	}
	
	// ----------------------------------------------------------------

	this.load = function (valuearray) {
		this.dump();
		this.value = valuearray;
		this.preloadImages();
	}
	
	// ----------------------------------------------------------------

	this.preloadImages = function () {
		if (this.type == 'image') {
			var p1 = new Image(1,1);
			p1.src = this.value[this.cursor];
			var p2 = new Image(1,1);
			p2.src = this.value[this.forward()];
			var p3 = new Image(1,1);
			p3.src = this.value[this.back()];
		}
	}
	
	// controls ----------------------------------------------------------------
	
	this.forward = function () {
		if ((this.cursor < 0) || (this.cursor >= (this.value.length - 1)))
			return 0;
		return this.cursor + 1;
	}
	
	// ----------------------------------------------------------------

	this.back = function () {
		if ((this.cursor < 1) || (this.cursor >= this.value.length)) {
			if (this.value.length)
				return this.value.length - 1;
			return 0;
		}
		return this.cursor - 1;
	}
	
	// ----------------------------------------------------------------

	this.goto = function (index, transtime) {
		if (index != this.cursor) {
			this.nextcursor = (index == -1) ? this.forward() : index;	
			this.nextcursor = (index == -2) ? this.back() : this.nextcursor;	
			if (transtime) {
				clearInterval(this.transinterval);
				this.transinterval = setInterval(this.name + '.' + this.mode + '(' + transtime + ');', Math.round(1000 / this.fps));
				this.cursor = this.nextcursor;
			} else {
				if (this.slidetime > 0)
					clearInterval(this.slideinterval);
				clearInterval(this.transinterval);
				this.change();
			}
			this.screenProgress();
		}
	};
	
	// ----------------------------------------------------------------

	this.previous = function (transtime) {
		this.goto(-2, transtime);
		if (this.playing) {
			clearInterval(this.slideinterval);
			this.slideinterval = setInterval(this.name + '.goto(-1, ' + this.transtime + ');', this.slidetime);
		}
	};
	
	// ----------------------------------------------------------------

	this.prev = function (transtime) {
		this.previous(transtime);
	};
	
	// ----------------------------------------------------------------

	this.next = function (transtime) {
		this.goto(-1, transtime);
		if (this.playing) {
			clearInterval(this.slideinterval);
			this.slideinterval = setInterval(this.name + '.goto(-1, ' + this.transtime + ');', this.slidetime);
		}
	};	
	
	// ----------------------------------------------------------------

	this.play = function (start) {
		this.boot(start);
		this.stop();
		this.preloadImages();
		this.playing = true;
		if (this.slidetime == 0)
			this.goto(-1, this.transtime);
		else
			this.slideinterval = setInterval(this.name + '.goto(-1, ' + this.transtime + ');', this.slidetime);
	};
	
	// ----------------------------------------------------------------

	this.stop = function () {
		if (this.slidetime > 0)
			clearInterval(this.slideinterval);
		clearInterval(this.transinterval);
		this.playing = false;
		this.setOpacity(1);
	};
	
	// ----------------------------------------------------------------

	this.boot = function (start) {
		if (!isNaN(start))
			this.cursor = (start) ? start : 0;
		this.nextcursor = this.cursor;
		this.cursor = this.back();
		eval(this.name + '.' + this.mode + '();');
		this.goto(-1);
	}
	
	// ----------------------------------------------------------------

	this.change = function () {
		this.el.insertBefore(this.el.firstChild, this.el.lastChild.nextSibling);
		var el = this.el.lastChild;
		if (this.type == 'image') {
			el.src = this.value[this.nextcursor];
		} else
			el.innerHTML = this.value[this.nextcursor];
		this.cursor = this.nextcursor;
		this.preloadImages();
	};
	
	// ----------------------------------------------------------------

	this.setOpacity = function () {
		if (arguments.length > 0)
			this.opacity = arguments[0];
		var el = this.el.firstChild;
		if (arguments.length > 1)
			el = arguments[1];
		if (this.ie)
			el.style.filter = 'alpha(opacity=' + Math.floor(Number(this.opacity) * 100) + ')';
		else
			el.style.opacity = this.opacity;		
	};
	
	// ----------------------------------------------------------------

	this.newElement = function () {
		var newtype = (this.type == 'image') ? 'img' : 'div';
		var newel = document.createElement(newtype);
		if (this.type == 'image')
			newel.src = this.value[this.nextcursor];
		else
			newel.innerHTML = this.value[this.nextcursor];
		if (this.centering) {
			newel.style.textAlign = 'center';
			newel.style.verticalAlign = 'middle';
			newel.style.display  = 'inline';
		} else {
			newel.style.position = 'absolute';
			newel.style.display  = 'block';
			newel.style.top  = '0px';
			newel.style.left = '0px';
		}
		newel.style.overflow = 'hidden';
		newel.style.width = 'auto';
		if (this.width)
			newel.style.width = (typeof(this.width) == 'Number') ? this.width + 'px' : this.width;
		newel.style.height = 'auto';
		if (this.height)
			newel.style.height = (typeof(this.height) == 'Number') ? this.height + 'px' : this.height;
		if (this.onmouseover)
			eval('newel.onmouseover = function () { ' + this.onmouseover + ' };');
		if (this.onmouseout)
			eval('newel.onmouseout = function () { ' + this.onmouseout + ' };');
		if (this.onclick) {
			eval('newel.onclick = function () { ' + this.onclick + ' };');
			newel.style.cursor = 'pointer';	
		}
		return newel;
	}
		
	// ----------------------------------------------------------------

	this.getDimension = function (el, width) {
		if (width) {	
			if (this.type == 'image')
				return getAsNumber(el.width);
			else
				return Math.max(el.clientWidth, el.offsetWidth);
		} else {
			if (this.type == 'image')
				return getAsNumber(el.height);
			else
				return Math.max(el.clientHeight, el.offsetHeight);
		}
	}
		
	// transitions ----------------------------------------------------------------
	
	this.convey = function (ishorizontal, isbackward) {
		var attribute = (ishorizontal) ? 'left' : 'top';
		var dimension = (ishorizontal) ? this.el_width : this.el_height;
		var loaded = (this.el.childNodes.length >= this.count);
		var delta = 0;
		if (loaded)
			delta = dimension / (this.transtime / 1000) / this.fps;
		var dim = (this.el.firstChild) ? this.getDimension(this.el.firstChild, ishorizontal) : 0;
		var oldoffset = this.offset;
		this.offset -= delta;
		if (!loaded || (Math.floor(oldoffset) != Math.floor(this.offset))) {
			delta = Math.ceil(delta);
			if ((!isbackward && (this.offset <= (-dim - delta))) || (isbackward && (this.offset >= (dimension + delta))) || (!loaded && ((this.type != 'image') || (!this.el.lastChild || this.el.lastChild.complete)))) {
				// change images - old one (firstchild) out, new one in as lastchild
				this.nextcursor = this.forward();
				// new image
				var lastkid = this.el.lastChild;
				var newel = this.newElement();
				newel.style[attribute] = '-100000px';
				this.el.appendChild(newel);
				if (lastkid) {
					if (isbackward)
						newel.style[attribute] = (getAsNumber(lastkid.style[attribute]) - this.getDimension(newel, ishorizontal) - this.spacing) + 'px';
					else
						newel.style[attribute] = (getAsNumber(lastkid.style[attribute]) + this.getDimension(lastkid, ishorizontal) + this.spacing) + 'px';
				} else {
					if (isbackward)
						newel.style[attribute] = (dimension - this.getDimension(newel, ishorizontal)) + 'px';
					else
						newel.style[attribute] = '0px';
				}
				// remove old image
				if (this.el.childNodes.length > this.count)
					this.el.removeChild(this.el.firstChild);
			}
			this.offset = getAsNumber(this.el.firstChild.style[attribute]);
			// shuffle all 
			delta = (isbackward) ? -delta : delta;
			for (var i = 0; i < this.el.childNodes.length; i++)
				this.el.childNodes[i].style[attribute] = (getAsNumber(this.el.childNodes[i].style[attribute]) - delta) + 'px';
		}
	};
		
	this.conveyleft = function () {	
		this.convey(true, false);
	};
		
	this.conveyright = function () {	
		this.convey(true, true);
	};
		
	this.conveyup = function () {	
		this.convey(false, false);
	};
		
	this.conveydown = function () {	
		this.convey(false, true);
	};
		
	// ----------------------------------------------------------------

	this.fadeaway = function () {
		this.count = 2;
		if (this.el.childNodes.length == 0) {
			this.nextcursor = 0;
			var newel = this.newElement();
			this.el.appendChild(newel);
			this.nextcursor = this.forward();
			var newel = this.newElement();
			this.el.appendChild(newel);
			this.nextcursor = this.forward();
		} else {
			var delta = this.transtime / this.fps / 1000;
			this.opacity -= delta;
			if (this.opacity < 0) {
				this.opacity = 0;
				clearInterval(this.transinterval);
				this.change();
				this.setOpacity(1, this.el.lastChild);
				this.el.lastChild.style.zIndex = 999;		
				this.el.firstChild.style.zIndex = 1000;		
			} else
				this.setOpacity();
		}
	};
		
	// ----------------------------------------------------------------

	this.fade = function (transtime) {
		this.count = 1;
		if (this.el.childNodes.length == 0) {
			var newel = this.newElement();
			this.el.appendChild(newel);
			this.nextcursor = this.forward();
		} else {
			transtime = (transtime) ? transtime : this.transtime;
			var delta = 1000 / this.fps / transtime * 2;
			this.opacity += this.direction * delta;
			if (this.opacity < 0) {
				this.opacity = 0;
				this.direction = 1;
				this.change();
			} 
			if (this.opacity > 1) {
				this.opacity = 1;
				this.direction = -1;
				clearInterval(this.transinterval);
			}
			this.setOpacity();
		}
	};
		
	// ----------------------------------------------------------------

	this.slideoff = function (direction) {
		var dimension = (direction == 'left') ? this.el_width : this.el_height;
		this.count = 2;
		if (this.el.childNodes.length == 0) { // load
			this.nextcursor = 0;
			var newel = this.newElement();
			this.el.appendChild(newel);
			this.nextcursor = this.forward();
			var newel = this.newElement();
			newel.style[direction] = dimension + 'px';
			this.el.appendChild(newel);
			this.nextcursor = this.forward();
		} else { // transition
			var delta = this.transtime / this.fps / 1000 * 2 * dimension;
			this.offset -= delta;
			if (this.offset < (-dimension)) {
				this.offset = dimension;
				this.el.firstChild.style[direction] = dimension + 'px';
				this.change();
				this.direction = 1;
			} 
			if ((this.offset < 0) && (this.direction == 1)) {
				this.offset = 0;
				this.el.firstChild.style[direction] = '0px';
				this.direction = -1;
				clearInterval(this.transinterval);
			}
			this.el.firstChild.style[direction] = this.offset + 'px';
		}
	};


	this.slideoffleft = function () {
		this.slideoff('left');
	};
		
	this.slideofftop = function () {
		this.slideoff('top');
	};

	// screen fade and controls etc ----------------------------------------------------------------
	
	this.screenBlack = function (elid) {
		elid = (elid) ? elid : this.name + 'fade';
		if (!this.black || (this.black.id != elid)) {
			var el = document.getElementById(elid);
			if (el) {
				this.black = el;
				return true;
			}
		}
		return false;
	}
	
	// ----------------------------------------------------------------

	this.screenPort = function (elid) {
		elid = (elid) ? elid : this.name + 'port';
		if (!this.port || (this.port.id != elid)) {
			var el = document.getElementById(elid);
			if (el) {
				this.port = el;
				return true;
			}
		}
		return false;
	}
	
	// ----------------------------------------------------------------

	this.screenProgress = function (elid) {
		if (elid) {
			if (!this.progress || (this.progress.id != elid)) {
				if (document.getElementById(elid))
					this.progress = document.getElementById(elid);
			}
		}
		if (this.progress) {
			this.progress.innerHTML = this.cursor + 1;
			return true;
		}
		return false;
	}
	
	// ----------------------------------------------------------------

	this.screenStart = function (portleft, start, blackid, portid, progressid) {
		this.screenBlack(blackid);
		this.screenPort(portid);
		if (this.black && this.port) {
			this.centering = true;
			this.port.style.display = 'block';
			this.prime();
			this.height = '100%';
			this.boot(start);
			this.black.style.display = 'block';
			this.black.style.left = '0px';
			this.black.style.width = getPageDimension(true) + 'px';
			this.black.style.height = getPageDimension(false) + 'px';
			this.port.style.left = portleft;
			window.scrollTo(0, 0);
		}
		progressid = (progressid) ? progressid : this.name + 'progress';
		this.screenProgress(progressid);
	}
	
	// ----------------------------------------------------------------

	this.screenClose = function () {
		if (this.port) {
			this.port.style.display = 'none';
			this.port.style.left = '-10000px';
		}
		if (this.black) {
			this.black.style.display = 'none';
			this.black.style.left = '-10000px';
		}
	}
	
	// ----------------------------------------------------------------
		
}
