/**********************************

	Sliding Slide Show
	version 1.0
	last revision: 04.28.2005
	saint_croix_fx@ameritech.net

	photos (c) saint_croix_fx@ameritech.net
	based on Flash "imageviewer" by Travis Beckham from podlob.com

**********************************/
window.onload = init;
var d=document;
var zInterval=null;

var imageCoordinates = new Array(); 		// array to hold the x,y of each image
var imageObjects = new Array(); 		// object reference array to the images
var imageDimensions = new Array();		// array to hold the current width and height of the images
var imageStart = new Array(); 		// the original x/y positions of each image
var imageCourse = new Array(); 		// the x/y coordinates the image must travel to get from point A to point B
var currentOpacity = new Array(); 		// current transparency of the image
var activeImage=-1; 			// index of the currently active image
var prevImage=-1; 			// index of the formerly active image
var animationIndex = new Array(); 		// keeps track of where we need to be in the imageCourse array for each animation loop
var movementSteps = new Array();		// the width and height increments required for each image to resize by while moving
var useOpacity=1; 				// boolean to denote use of opacity filters
var iSpeed=6;				// the rate at which we step through the imageCourse array
var isAnimated=0;				// stops additional threads from running if one already is.

var TOTAL_IMAGES=10;			// the total number of images
var IMAGES_PER_ROW=2;			// how many images per row
var IMAGE_MIN_SIZE=32;			// the minimum size of the thumbnails
var IMAGE_MAX_WIDTH=500;		// max width of the enlarged images
var IMAGE_MAX_HEIGHT=375;		// max height of the enlarged images
var IMAGE_SPACING=5;			// spacing between the thumbnails
var DEST_Y=100;				// the y position of where the animation stops
var DEST_X=200;				// the x position of where the animation stops
var DEFAULT_CAPTION="Select a thumbnail to see a larger version of the image."

function init() {
	if(!document.getElementById)return;	// bail out if this is an old browser
	initThumbnails();			// initialize the thumbnail images
	initCourse();			// initialize the x/y courses the images will need to travel
	initSteps();			// intialize the step increments for the width and height changes
}

function initThumbnails() {
	x=0; y=0; i=0; z=0;
	// set the default caption up
	d.getElementById("caption").innerHTML = DEFAULT_CAPTION;
	// loop over how many images we have to deal with
	while(i<TOTAL_IMAGES) {
		// create an object reference variable to the image
		if(!imageObjects[i])imageObjects[i]=d.getElementById("image"+i);

		// set the top and left of the image
		imageObjects[i].style.left = x + "px";
		imageObjects[i].style.top = y + "px";

		// set up the bogus "xid" attribute to ID the images when they are clicked on
		imageObjects[i].xid=i;

		// set up the onclick event
		imageObjects[i].onclick=function(){animate(this.xid)}

		// set up the imageStart array for this image
		if(!imageStart[i])imageStart[i]=new Array(x,y);

		// increment the x coordinate for the next image
		x+=IMAGE_MIN_SIZE+IMAGE_SPACING;

		// set up the coordinates for this image
		imageCoordinates[i]=new Array(x,y);

		// and its initial width
		imageDimensions[i] = new Array(32,32);

		// and it initial opacity. MSIE takes 0-100 values for opacity. All others take floating points.
		currentOpacity[i]=document.all?50:.5;
	
		// set the animationIndex for this image to 0
		animationIndex[i]=0;

		// if we've got as many images in the row as we want, start the next row
		z++;
		if(z>=IMAGES_PER_ROW) {
			x=0; z=0;
			y+=IMAGE_MIN_SIZE+IMAGE_SPACING;
		}
		i++;
	}
}

function initCourse() {
	// initialize the imageCourse array for each image
	for(i=0;i<imageStart.length;i++)imageCourse[i] = plotCourse(DEST_X,DEST_Y,imageStart[i][0],imageStart[i][1]);
}

function initSteps() {
	// initialize the step increments for the width and height changes.
	for(i=0;i<imageCourse.length;i++) {
		wStep = Math.round(imageCourse[i].length/iSpeed);
		wStep = Math.round(500/wStep);
		hStep = Math.round(imageCourse[i].length/iSpeed);
		hStep = Math.round(375/hStep);
	
		movementSteps[i]=new Array(wStep,hStep);
	}
}

function animate(index) {
	// exit out of the function if there is already an animation thread running
	if(zInterval)return;

	// no current active image. that means either a single image is returning (no overlap) or we're running for the first time
	// make prevImage -1 so we dont run any animation loops we dont need to.
	if(activeImage==-1)prevImage=-1;
	if(index==activeImage) {
		// the user has clicked on the enlarged image. set prevImage to activeImage and set activeImage to -1
		prevImage=activeImage;
		imageObjects[activeImage].style.zIndex=100;
		activeImage=-1;	
	} else {
		// set up the previous image so we know which to send back and where to send it.
		if(activeImage>-1)prevImage=activeImage;
		activeImage=index;
		imageObjects[activeImage].style.zIndex=100;
		if(prevImage>-1)imageObjects[prevImage].style.zIndex=1;
	}

	// begin the animation thread
	zInterval = setInterval("slideImage()",10);
}

function setImagePosition(index) {
	// set the positions and width of the images. These can fall out of range, hence the try/catch statement
	try {
		imageObjects[index].style.top = imageCourse[index][animationIndex[index]][1]+"px";
		imageObjects[index].style.left = imageCourse[index][animationIndex[index]][0]+"px";
		imageObjects[index].style.width=imageDimensions[index][0]+"px";
		imageObjects[index].style.height=imageDimensions[index][1]+"px";
	} catch(err) { }
}

function setImageOpacity(index) {
	// set the opacity of the object. Once for Gecko, once for Safari and once for MSIE.
	if(!useOpacity)return;
	imageObjects[index].style.filter="alpha(opacity=" + currentOpacity[activeImage] + ")";
	imageObjects[index].style.MozOpacity=currentOpacity[activeImage];
	imageObjects[index].style.opacity=currentOpacity[activeImage];
}

function slideImage() {
	// if we have an active image, meaning the one that is being enlarged...
	if(activeImage>-1) {
		// set up its width,height,top and left
		setImagePosition(activeImage);
		// set up its opacity
		currentOpacity[activeImage]+=d.all?5:.05;
		setImageOpacity(activeImage);
		// if its width is less than 500, increase it. likewise with its height
		if(imageDimensions[activeImage][0]<500)imageDimensions[activeImage][0]+= movementSteps[activeImage][0];
		if(imageDimensions[activeImage][1]<375)imageDimensions[activeImage][1]+= movementSteps[activeImage][1];
		// increment our current index for imageCourse by value of iSpeed
		animationIndex[activeImage]+=iSpeed;
	}

	// do the same as above for images returning to thumbnail size, only decrementing values this time
	if(prevImage>-1) {
		setImagePosition(prevImage);
		currentOpacity[prevImage]-=d.all?5:.05;
		setImageOpacity(prevImage);
		if(imageDimensions[prevImage][0]>32)imageDimensions[prevImage][0]-=movementSteps[prevImage][0];
		if(imageDimensions[prevImage][1]>32)imageDimensions[prevImage][1]-=movementSteps[prevImage][1];
		animationIndex[prevImage]-=iSpeed;
	}

	// has our animation finished?
	if(isFinished()) {
		// if activeImage is -1, we have no enlarged image. reset the animation index and put the default caption back in.
		if(activeImage==-1) {
			d.getElementById("caption").innerHTML = DEFAULT_CAPTION;
			animationIndex[prevImage]=0;
		}
		// we've got an active image.
		if(activeImage>-1) {
			// set the animation index to the length of imageCourse so we can start at the end of that array 
			// for when this image becomes a thumbnail again
			animationIndex[activeImage] = imageCourse[activeImage].length;
			// set the final top,left,width and height of the image, just in case they're off
			imageObjects[activeImage].style.top=DEST_Y+"px";
			imageObjects[activeImage].style.left=DEST_X+"px";
			imageObjects[activeImage].style.width="500px";
			imageObjects[activeImage].style.height="375px";
			// set up the final opacity of the image if useOpacity is true
			if(useOpacity) {
				imageObjects[activeImage].style.MozOpacity=.99;
				imageObjects[activeImage].style.filter="alpha(opacity=100)";
				imageObjects[activeImage].style.opacity=1.0;
			}
			d.getElementById("caption").innerHTML = imageObjects[activeImage].title;
		} 
		// do the same for the thumbnail image.
		if(prevImage>-1) {
			animationIndex[prevImage]=0;
			imageObjects[prevImage].style.top = imageStart[prevImage][1]+"px";
			imageObjects[prevImage].style.left = imageStart[prevImage][0]+"px";
			imageObjects[prevImage].style.width="32px";
			imageObjects[prevImage].style.height="32px";
			if(useOpacity) {
				imageObjects[prevImage].style.MozOpacity=.5;
				imageObjects[prevImage].style.filter="alpha(opacity=50)";
				imageObjects[prevImage].style.opacity=.5;
			}
		}
		// stop the animation thread
		clearInterval(zInterval);
		zInterval=null;
	}
}

// checks to see if the thumbnail and enlarged image are at their final positions
// by checking the animationIndex value against the length of the images imageCourse array.
function isFinished() {
	if(activeImage>-1 && prevImage>-1)if(animationIndex[activeImage]>=imageCourse[activeImage].length && animationIndex[prevImage]<=0) return true;
	if(activeImage>-1 && prevImage==-1) if(animationIndex[activeImage]>=imageCourse[activeImage].length)return true;
	if(activeImage==-1 && prevImage>-1) if(animationIndex[prevImage]<=0)return true;
	return false;
}

// this function simply resets the opacity of the objects when the check box is clicked.
function disableOpacity(bool) {
	if(bool) {
		useOpacity=0;
		for(i=0;i<imageObjects.length;i++) {
			imageObjects[i].style.MozOpacity=1.0;
			imageObjects[i].style.opacity=1.0;
			imageObjects[i].style.filter="alpha(opacity=100)";
		}
	} else {
		location.reload();
	}
}

// this function calculates the required coordinates to go from point A to point B and returns them as an array.
// originally written by Dean Taylor for Web Paint's line functions (slayeroffice.com/tools/web_paint)
// also used in Missile Command (slayeroffice.com/arcade/missile_command)
function plotCourse(fX,fY,oX,oY) {

	dx = Math.abs(fX-oX);
	dy = Math.abs(fY-oY);
	max = dx > dy ? dx : dy;
	x_inc = dx / max;
	y_inc = dy / max;

	Xp = oX
	Yp = oY;

	path = new Array();
	pathCount = 0;

	if(fX>oX && fY > oY) {
		if(oX<fX && oY<fY) {
			while (Xp < fX) {
				nextX = Math.round(Xp);
				nextY = Math.round(Yp);
				path[pathCount] = new Array(nextX,nextY);
				pathCount++;
				Xp += x_inc;
				Yp += y_inc;
			}
		} else {
			while (Xp > fX) {
				nextX = Math.round(Xp);
				nextY = Math.round(Yp);
				path[pathCount] = new Array(nextX,nextY);
				pathCount++;
				Xp -= x_inc;
				Yp += y_inc;
			}		
		}	
	} else {
		if(oX<fX && oY>fY) {
			while (Xp < fX) {
				nextX = Math.round(Xp);
				nextY = Math.round(Yp);
				path[pathCount] = new Array(nextX,nextY);
				pathCount++;
				Xp += x_inc;
				Yp -= y_inc;
			}
		} else {
			while (Xp > fX) {
				nextX = Math.round(Xp);
				nextY = Math.round(Yp);
				path[pathCount] = new Array(nextX,nextY);
				pathCount++;
				Xp -= x_inc;
				Yp -= y_inc;
			}
		}
	}
	return path;
}
