/*
	fadeShow v2.1.1  2006-6-13
	(c) 2006 Bill Tomczak, bill@grumpyengineering.com

	2007-10-4: Add fix for IE7 to prevent image jumping

	Based heavily on scripts created by brothercake - http://www.brothercake.com

	This script can be used as is, but you must not remove this header
	There is no documentation at this point
*/
function fadeShow() {
	// Things you can set
	this.type = 'fade';  // either fade or wipe
	this.interval = 5; // seconds between changes
	this.duration = 2; // seconds to make change
	this.direction = 0; // wipe direction ignored for fades
	this.resolution = 20; // changes per second
	this.width = null; // Specifying width or height resizes image proportionately
	this.height = null; // Specifying both forces all images to those dimensions
	this.randomShow = false; // Select images randomly from the list
	this.columns = 2; // Number of columns for this.linksToTable()
	this.tableClass = 'fs_linksTable'; // The class to apply to the table

	/***************************************/
	/* Don't touch anything after here!    */
	/***************************************/
	this.clock = null;
	this.count = 1;
	this.image = null;
	this.imgIndex = -1;
	this.imgList = Array();
	this.sweeps = Array('lr', 'tb', 'bltr', 'brtl', 'tlbr', 'trbl', 'cve', 'che', 'cc');
	this.currentSweep = '';
	this.fading = null;
	this.fixSize = false;
	this.ie7 = ((document.all)&&(navigator.appVersion.indexOf("MSIE 7.")!=-1)) ? true : false;

	// Image list builder
	this.addImage = function (altText, imgURL, imgLink) {
		var i = this.imgList.length;
		this.imgList[i] = new Object();
		this.imgList[i].alt = altText;
		this.imgList[i].obj = new Image;
		this.imgList[i].obj.src = imgURL;
		this.imgList[i].href = imgLink;
	}

	// create a new image object and append it to body
	// detecting support for namespaced element creation, in case we're in the XML DOM
	// Accepts entry from this.imgList array
	this.createNewImage = function(nextImage) {
		this.newImage = document.getElementsByTagName('body')[0].appendChild((typeof document.createElementNS != 'undefined') ? document.createElementNS('http://www.w3.org/1999/xhtml', 'img') : document.createElement('img'));

		// Apply needed styles to make effects work
		this.newImage.style.position = "absolute";
		this.newImage.style.zIndex = "30000";
		this.newImage.style.visibility = "hidden";

		// move it to superimpose original image
		this.newImage.style.left = this.getRealPosition(this.image, 'x');
		this.newImage.style.top = this.getRealPosition(this.image, 'y');
	
		//set new image
		this.newImage.src = nextImage.obj.src;
		this.newImage.alt = nextImage.alt;
		this.setImageSize(this.newImage);
		this.fixSize = (this.newImage.width != this.image.width) || (this.newImage.height != this.image.height);
	}
	
	this.setImageSize = function(image) {
		// set size as needed
		var width = this.width;
		var height = this.height;
		
		if (!this.width && !this.height) {
			// Set to image actual size
			width = image.width;
			height = image.height;
		} else if (!this.width) {
			// Resize based on height
			var coeff = image.height/image.width;
  		width = parseInt(this.height/coeff, 10);

  	} else if (!this.height) {
			// Resize based on width
	 		var coeff = image.width/image.height;
  		height = parseInt(this.width/coeff, 10);
  	}
		image.width = width;
		image.height = height;
	}

	// set the current image from this.imgList array entry
	this.setImage = function(nextImage) {
		this.image.src = nextImage.obj.src;
		this.image.width = nextImage.obj.width;
		this.image.height = nextImage.obj.height;
		this.image.alt = nextImage.alt;
	}

	// get Next Image object from list
	this.getNextImage = function() {
		var newIndex = this.imgIndex

		if (this.randomShow) {
			// pick something at random
			while (newIndex == this.imgIndex) {
				newIndex = Math.floor(Math.random() * this.imgList.length);
			}

		} else {
			// Let's be orderly about this!
			newIndex = (this.imgIndex+1) >= this.imgList.length ? 0 : ++this.imgIndex;
		}

		this.imgIndex = (this.imgList[newIndex].obj.complete) ? newIndex : Math.max(0, this.imgIndex);
		return this.imgList[this.imgIndex];
	}

	// get real position method
	this.getRealPosition = function(imgTag, axis) {
		var point = (axis == 'x') ? imgTag.offsetLeft : imgTag.offsetTop;

		var tmp = imgTag.offsetParent;
		while(tmp != null) {
			point += (axis == 'x') ? tmp.offsetLeft : tmp.offsetTop;
			tmp = tmp.offsetParent;
		}
		
		// Prevent jumping in IE7
		if (this.ie7) {
			point += 0;
		}
		return point + "px";
	}

	// Start next invocation of transition
	this.startNextRound = function() {
		var interval = (this.opacType == 'none') ? this.interval+this.duration : this.interval
		var nextCall;
		switch (this.type) {
			case 'fade':
				nextCall = 'startFade';
				break;
			
			case 'wipe':
				nextCall = 'startWipe';
				break;
			
			case 'swap':
				nextCall = 'startSwap';
				break;

			default:
				return;
				break;
		}
		
		nextCall = nextCall + "('" + this.name + "')";

		if ( interval == 0 ) {
			eval(nextCall);

		} else {
			setTimeout(nextCall, interval*1000);
		}
	}

	// When a link is specified for a particular image, go to the URL
	this.jump = function() {
		var URL = this.imgList[this.imgIndex].href;
		if (URL != "") {
			document.location.href = URL;
		}
	}

	// Output all the links into a table
	this.linksToTable = function() {
		if (this.imgList.length > 1) {
			var cols = this.columns;
			var tdWidth;
			tdWidth = parseInt(100/cols);

			document.write("<table class=\"" + this.tableClass + "\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">");
	
			var i = 0;
			var cnum;
			while (i < this.imgList.length) {
				document.write("<tr>");
				for (cnum=0; cnum < cols; cnum++) {
					document.write("<td align=\"center\" width=\"" + tdWidth + "%\">");
					if (i < this.imgList.length) {
						if (this.imgList[i].href == "") {
							document.write(this.imgList[i].alt + "&nbsp;");
						} else {
							document.write("<a href=\""+this.imgList[i].href+"\">"+this.imgList[i].alt+"</a>");
						}
						i += 1;
					} else {
						document.write("&nbsp;");
					}
					document.write("</td>");
				}
				document.write("</tr>");
			}
			document.write("</table>");
		}
	}

	// fade timer function
	this.doFade = function(duration, resolution) {
		//decrease the counter on a linear scale
		this.count -= (1 / (resolution));
	
		if(this.count < (1 / resolution)) {
			// Reached the bottom - clear the timer
			clearInterval(this.clock);
			this.clock = null;
			this.count = 1;
		
			//set the original image to the new image
			this.image.width = this.newImage.width;
			this.image.height = this.newImage.height;
			this.image.src = this.newImage.src;
			this.image.alt = this.imgList[this.imgIndex].alt;
		}

		// Set new opacity value on both elements
		// using whatever method is supported
		switch(this.opacType) {
			case 'filt':
				// use style filter
				var re = /alpha\(opacity=.+\)/;
				var fadeOut = "alpha(opacity=" + (this.count * 100) + ")";
				var fadeIn = "alpha(opacity=" + ((1 - this.count) * 100) + ")";

				if (this.image.style.filter.match(re)) {
					this.image.style.filter = this.image.style.filter.replace(re, fadeOut);
				} else {
					this.image.style.filter += fadeOut;
				}
				
				if (this.newImage.style.filter.match(re)) {
					this.newImage.style.filter = this.newImage.style.filter.replace(re, fadeIn);
				} else {
					this.newImage.style.filter += fadeIn;
				}
				break;

			case 'ie' :
				// Use ie filters property. Doesn't work on Mac IE5.2
				this.image.filters.alpha.opacity = this.count * 100;
				this.newImage.filters.alpha.opacity = (1 - this.count) * 100;
				break;
			
			case 'khtml' :
				// Konqueror
				this.image.style.KhtmlOpacity = this.count;
				this.newImage.style.KhtmlOpacity = (1 - this.count);
				break;
			
			case 'moz' : 
				//restrict max opacity to prevent a visual popping effect in firefox
				this.image.style.MozOpacity = (this.count == 1 ? 0.9999999 : this.count);
				this.newImage.style.MozOpacity = (1 - this.count);
				break;
			
			default : 
				//restrict max opacity to prevent a visual popping effect in firefox
				this.image.style.opacity = (this.count == 1 ? 0.9999999 : this.count);
				this.newImage.style.opacity = (1 - this.count);
		}
	
		// Keep new image in position with original image
		// in case text size changes mid transition or something
		this.newImage.style.left = this.getRealPosition(this.image, 'x');
		this.newImage.style.top = this.getRealPosition(this.image, 'y');

		//now that we've gone through one fade iteration 
		//we can show the image that's fading in
		this.newImage.style.visibility = 'visible';

		if(this.count == 1) {
			// Counter is at the top, which is just after the timer has finished
			// remove the duplicate image and start another round
			this.newImage.parentNode.removeChild(this.newImage);
			this.startNextRound();
		}
	}

	// wipe timer function
	this.doWipe = function(duration, resolution) {
		//decrease the counter on a linear scale
		this.count -= (1 / resolution);
	
		//if the counter has reached the bottom
		if(this.count < (1 / resolution)) {
			//clear the timer
			clearInterval(this.clock);
			this.clock = null;
		
			//reset the counter
			this.count = 1;
		
			//set the original image to the new image
			this.image.width = this.newImage.width;
			this.image.height = this.newImage.height;
			this.image.src = this.newImage.src;
			this.image.alt = this.imgList[this.imgIndex].alt;
		}

		// set the direction
		var sweep = this.currentSweep;

		// animate the clip of the new image
		// using the width and height properties we saved earlier
		this.newImage.style.clip = 'rect('
		+ ( (/bt|bltr|brtl/.test(sweep)) ? (this.newImage.height * this.count) : (/che|cc/.test(sweep)) ? ((this.newImage.height * this.count) / 2) : (0) )
		+ 'px, '
		+ ( (/lr|tlbr|bltr/.test(sweep)) ? (this.newImage.width - (this.newImage.width * this.count)) : (/cve|cc/.test(sweep)) ? (this.newImage.width - ((this.newImage.width * this.count) / 2)) : (this.newImage.width) )
		+ 'px, '
		+ ( (/tb|tlbr|trbl/.test(sweep)) ? (this.newImage.height - (this.newImage.height * this.count)) : (/che|cc/.test(sweep)) ? (this.newImage.height - ((this.newImage.height * this.count) / 2)) : (this.newImage.height) )
		+ 'px, '
		+ ( (/lr|tlbr|bltr/.test(sweep)) ? (0) : (/tb|bt|che/.test(sweep)) ? (0) : (/cve|cc/.test(sweep)) ? ((this.newImage.width * this.count) / 2) : (this.newImage.width * this.count) ) 
		+ 'px)';
			
		// Keep new image in position with original image
		// in case text size changes mid transition or something
		this.newImage.style.left = this.getRealPosition(this.image, 'x');
		this.newImage.style.top = this.getRealPosition(this.image, 'y');
	
		if(this.count == 1) {
			// Counter is at the top, which is just after the timer has finished
			//remove the duplicate image
			this.newImage.parentNode.removeChild(this.newImage);
			this.startNextRound();
		}
	}
	
	// swap fade timer function
	this.doSwap = function(duration, resolution) {
		//increase or reduce the counter on an exponential scale
		this.count = (this.fading) ? this.count * 0.9 : (this.count * (1/0.9)); 

		if(this.count < (1 / resolution)) {
			// Counter has reached the bottom
			// Clear the timer
			clearInterval(this.clock);
			this.clock = null;

			//set the original image to the new image
			var newImage = this.imgList[this.imgIndex];
			if (this.fixSize) {
				this.image.width = newImage.obj.width;
				this.image.height = newImage.obj.height;
			}
			this.image.src = newImage.obj.src;
			this.image.alt = newImage.alt;

			//reverse the fade direction flag
			this.fading = false;
		}
	
		if(this.count > (1 - (1 / resolution))) {
			// Counter has reached the top
			// Clear it
			clearInterval(this.clock);
			this.clock = null;
			
			//reset the counter
			this.count = 1;
			
			//reset the fade direction flag
			this.fading = true;
		}

		// set new opacity value on element
		// using whatever method is supported
		switch(this.opacType) {
			case 'filt':
				var re = /alpha\(opacity=.+\)/;
				var fade = "alpha(opacity=" + (this.count * 100) + ")";
				
				if (this.image.style.filter.match(re)) {
					this.image.style.filter = this.image.style.filter.replace(re, fade);
				} else {
					this.image.style.filter += fade;
				}
				break;

			case 'ie' :
				this.image.filters.alpha.opacity = this.count * 100;
				break;
			
			case 'khtml' :
				this.image.style.KhtmlOpacity = this.count;
				break;
			
			case 'moz': 
			default : 
				// restrict max opacity to prevent a visual popping effect in firefox
				this.image.style.opacity = (this.count == 1 ? 0.9999999 : this.count);
		}

		// Clock was cleared, time to start the next step
		if (this.clock == null) {
			// New fade is out, pause
			if (this.fading) {
				this.startNextRound();
			} else {
				// New fade is in, start right away
				startSwap(this.name);
			}
		}
	}		
}

/********************************************************************/
/* End of showFade object
/********************************************************************/

// The main function that gets the whole show rolling
// The show should be instantiated as an object and
// and <img> tag placed somewhere in the doc with a
// name attribute. Pass the variable name and img name
// for the arguments
function startShow(showName,imageName,setSize) {
	var show = eval(showName);

	var imgTag = document[imageName]
	if (setSize) {
		// Supply third argument as true or 1 to use img tag for dimensions
		show.width = imgTag.width;
		show.height = imgTag.height;
	}
	show.image = imgTag;	

	show.opacType = getOpacityType(show.image);
	show.name = showName;

	var nextImage = show.getNextImage();

	show.image.src = nextImage.obj.src;
	show.image.alt = nextImage.alt;
	if (show.width) show.image.width = show.width;
	if (show.height) show.image.height = show.height;
	
	// When interval is 0 wait a bit before starting for image loading
	if (show.imgList.length > 1) {
		if (show.interval == 0) {
			setTimeout(showName+".startNextRound()", 1000);
		} else {
			show.startNextRound();
		}
	}
}

// Utility function for determining which kind of
// cross fade we can use.
function getOpacityType(image) {
	var opacType = 'none';	

	if(typeof image.style.opacity != 'undefined') {
		opacType = 'w3c';
	} else if(typeof image.style.MozOpacity != 'undefined') {
		opacType = 'moz';
	} else if(typeof image.style.KhtmlOpacity != 'undefined') {
		opacType = 'khtml';
	} else if(typeof image.style.filter != 'undefined') {
		// Set the style filter when we can.
		// This should work at least for Win/ie4 and up
		image.style.filter += "alpha(opacity=100)";
		opacType = 'filt';
	} else if(typeof image.filters == 'object') {
		//weed out win/ie5.0 by testing the length of the filters collection (where filters is an object with no data)
		//then weed out mac/ie5 by testing first the existence of the alpha object (to prevent errors in win/ie5.0)
		//then the returned value type, which should be a number, but in mac/ie5 is an empty string
		opacType = (image.filters.length > 0 && typeof image.filters.alpha == 'object' && typeof image.filters.alpha.opacity == 'number') ? 'ie' : opacType;
	}
	return opacType;
}

// fade setup function
function startFade(showName) {
	var show = eval(showName);
	var nextImage = show.getNextImage();

	if ( show.image.src == nextImage.obj.src) {
		// There may be occasions when in random mode that the image hasn't changed
		// so do nothing and try again later
		show.startNextRound();
	} else {
		// Image has changed
		if(show.clock == null) {
			// The timer is not running
			if(show.opacType != 'none') {
				// Any kind of opacity is supported
				show.createNewImage(nextImage);

				//copy and convert duration and resolution
				var duration = show.duration * 1000;
				var resolution = show.duration * show.resolution;
				
				//start the timer
				var fadeCall = showName + ".doFade(" + duration + "," + resolution + ")";
				show.clock = setInterval(fadeCall, duration/resolution);
			} else {
				// Opacity is not supported
				// just do the image swap
				show.setImage(nextImage);
				show.startNextRound();
			}
		}
	}
}

// wipe setup function
function startWipe(showName) {
	var show = eval(showName);
	var nextImage = show.getNextImage();

	if (typeof show.direction == 'number') {
		// Sequentially looping through all the wipe effects
		show.direction = (show.direction < 0 || show.direction >= show.sweeps.length) ? 0 : show.direction;
		show.currentSweep = show.sweeps[show.direction++];
	} else {
		// Specific wipe effect has been chosen by name
		show.currentSweep = (show.direction == 'rand') ? show.sweeps[Math.floor(Math.random() * show.sweeps.length)] : show.direction;
	}

	if ( show.image.src == nextImage.obj.src) {
		// There may be occasions when in random mode that the image hasn't changed
		// so do nothing and try again later
		show.startNextRound();
	} else {
		if(show.clock == null) {
			// The timer is not running
			if(typeof document.createElementNS != 'undefined' || typeof document.createElement != 'undefined') {
				// Dynamic element creation is supported
				show.createNewImage(nextImage);

				// Set it to be completely hidden with clip
				show.newImage.style.clip = 'rect(0, 0, 0, 0)';

				//show the image 
				show.newImage.style.visibility = 'visible';

				//copy and convert duration and resolution
				var duration = show.duration * 1000;
				var resolution = show.duration * show.resolution;
				
				//start the timer
				var wipeCall = showName + ".doWipe(" + duration + "," + resolution + ")";
				show.clock = setInterval(wipeCall, duration/resolution);
			} else {
				// Dynamic element creation is not supported
				// just do the image swap
				show.setImage(nextImage);
				show.startNextRound();
			}
		}
	}
}

// swapfade setup function
function startSwap(showName) {
	var show = eval(showName);
	var nextImage = show.getNextImage();

	if(show.clock == null) {
		// The timer is not running
		if(show.type != 'none') {
			// Some kind of opacity is supported
			if (show.fading == null) {
				// Initial setting for fade in/out indicator
				show.fading = true;
			}

			// Copy and convert duration and resolution
			var duration = show.duration * 1000;
			var resolution = show.duration * show.resolution;
				
			// Start the timer
			var swapCall = showName + ".doSwap(" + duration + "," + resolution + ")";
			show.clock = setInterval(swapCall, duration/resolution);
		} else {
			// Opacity is not supported
			// just do the image swap
			show.setImage(nextImage);
			show.startNextRound();
		}
	}
}

