// Effects.js//////////////////////////////// ZOOM IMAGE functions// Settingsvar includeCaption = 1;   // Turn on the "caption" feature, and write out the caption HTMLvar zoomTime       = 5;   // Milliseconds between frames of zoom animationvar zoomSteps      = 15;  // Number of zoom animation framesvar fade           = 1;   // Fade images in / outvar minBorder      = 90;  // Amount of padding between large, scaled down images, and the window edgesvar zoomImageURI   = './zoom_images/'; // Location of the zoom images// Init. Do not add anything below this line, unless it's something awesome.var myWidth = 0, myHeight = 0, myScroll = 0; myScrollWidth = 0; myScrollHeight = 0;var zoomOpen = false, preloadFrame = 1, preloadActive = false, preloadTime = 0, imgPreload = new Image();var zoomActive = new Array(); var zoomTimer  = new Array(); var zoomOrigW  = new Array(); var zoomOrigH  = new Array();var zoomOrigX  = new Array(); var zoomOrigY  = new Array();var zoomID    = "ZoomBox";var theID     = "ZoomImage";var theCap    = "ZoomCaption";var theCapDiv = "ZoomCapDiv";// Zoom: Setup The Page! Called onLoad();function setupZoom() {	prepZooms();	insertZoomHTML();	zoomdiv = document.getElementById(zoomID);  	zoomimg = document.getElementById(theID);}// Zoom: Inject Javascript functions into zoomable href's, one by one.// This is done at page load time via an onLoad() handler.function prepZooms() {	if (! document.getElementsByTagName) {		return;	}	var links = document.getElementsByTagName("a");	for (i = 0; i < links.length; i++) {		if (links[i].getAttribute("href") && (links[i].getAttribute("rel"))) {			if (links[i].getAttribute("rel").indexOf("zoom:") == 0) {				links[i].onclick = function () { zoomClick(this); return false; };				links[i].onmouseover = function () { zoomPreload(this); };			}		}	}}// Zoom: Preload a zoom image when hovering over the thumbnail, then set the image once the preload is complete.// Preloaded image is stored in imgPreload() and swapped out in the zoom function.function zoomPreload(from) {	var theimage = from.getAttribute("href");	// console.log("PRELOAD START: "+theimage);	// Only preload if we have to, i.e. the image isn't this image already	if (imgPreload.src.indexOf(from.getAttribute("href").substr(from.getAttribute("href").lastIndexOf("/"))) == -1) {		preloadActive = true;		imgPreload = new Image();      		// Set a function to fire when the preload is complete, setting flags along the way.   		imgPreload.onload = function() {			// console.log("PRELOAD END");			preloadActive = false;		}		// Load it!		imgPreload.src = theimage;	}}// Zoom: Start the preloading animation cycle.function preloadAnimStart() {	preloadTime = new Date();	document.getElementById("ZoomSpin").style.left = (myWidth / 2) + 'px';	document.getElementById("ZoomSpin").style.top = ((myHeight / 2) + myScroll) + 'px';	document.getElementById("ZoomSpin").style.visibility = "visible";		preloadFrame = 1;	document.getElementById("SpinImage").src = zoomImageURI+'zoom-spin-'+preloadFrame+'.png';  	preloadAnimTimer = setInterval("preloadAnim()", 100);}// Until we've been preloading for one second, just chill out in here.// // function preloadAnimPending(from) {// 	if (preloadActive != false) {// 		if ((new Date() - preloadTime) > 1000) {// 			document.getElementById("ZoomSpin").style.visibility = "visible";// 			clearInterval(preloadAnimTimer);// 			preloadAnimTimer = setInterval("preloadAnim()", 100);// 		}// 		else {// 			// Stay in this loop and don't do anything while we wait one second// 		}// 	} else {// 		clearInterval(preloadAnimTimer);// 		zoomIn(preloadFrom);// 	}// } // Zoom: Display and ANIMATE the jibber jabber widget. Once preloadActive is false, bail and zoom it up!function preloadAnim(from) {	if (preloadActive != false) {		document.getElementById("SpinImage").src = zoomImageURI+'zoom-spin-'+preloadFrame+'.png';		preloadFrame++;		if (preloadFrame > 12) preloadFrame = 1;	} else {		document.getElementById("ZoomSpin").style.visibility = "hidden";    		clearInterval(preloadAnimTimer);		zoomIn(preloadFrom);	}}// Zoom: We got a click! Should we do the zoom? Or wait for the preload to complete?function zoomClick(from) {	// TODO: Double check that imgPreload src = clicked src	// Get browser dimensions	getSize();	if (preloadActive == true) {		// Preloading is otherwise still going on. So wait.		preloadFrom = from;		preloadAnimStart();	} else {		// Otherwise, we're loaded: do the zoom!		zoomIn(from);	}}// Zoom: Move an element in to endH endW, using zoomHost as a starting point.// "from" is an object reference to the href that spawned the zoom.function zoomIn(from) {	zoomimg.src = from.getAttribute("href");	// Determine the zoom settings from where we came from, the element in the <a>.	// If there's no element in the <a>, or we can't get the width, make stuff up	if (from.childNodes[0].width) {		startW = from.childNodes[0].width;		startH = from.childNodes[0].height;		startPos = findElementPos(from.childNodes[0]);	} else {		startW = 50;		startH = 12;		startPos = findElementPos(from);	}		    	hostX = startPos[0];	hostY = startPos[1];	// Make up for a scrolled containing div.	// TODO: This HAS to move into findElementPos.		if (document.getElementById('scroller')) {		hostX = hostX - document.getElementById('scroller').scrollLeft;	}	// Determine the target zoom settings	endW = imgPreload.width;	endH = imgPreload.height;		// TODO: need to get "rollover" setting somehow.  	// Don't act if we're already doing something.  	if (zoomActive[theID] != true) {  		// Clear everything out just in case something is already open     		document.getElementById("ShadowBox").style.visibility = "hidden";		document.getElementById("ZoomClose").style.visibility = "hidden";          		// Set the CAPTION if turned on  		if (includeCaption == 1) {			zoomcap  = document.getElementById(theCap);			zoomcapd = document.getElementById(theCapDiv);       			if (from.getAttribute('title') && includeCaption == 1) {				zoomcapd.style.display = 'block';				zoomcap.innerHTML = from.getAttribute('title');			} else {				zoomcapd.style.display = 'none';			}       		}        		// Store original position in an array for future zoomOut.		zoomOrigW[theID] = startW;		zoomOrigH[theID] = startH;		zoomOrigX[theID] = hostX;		zoomOrigY[theID] = hostY;     		// Now set the starting dimensions     		zoomimg.style.width = startW + 'px';		zoomimg.style.height = startH + 'px';		zoomdiv.style.left = hostX + 'px';		zoomdiv.style.top = hostY + 'px';     		// Show the zoom box, make it invisible     		if (fade == 1) {			setOpacity(0, zoomID);		}		zoomdiv.style.visibility = "visible";  		// If it's too big to fit in the window, shrink the width and height to fit (with ratio).  		sizeRatio = endW / endH;		if (endW > myWidth - minBorder) {			endW = myWidth - minBorder;			endH = endW / sizeRatio;		}		if (endH > myHeight - minBorder) {			endH = myHeight - minBorder;			endW = endH * sizeRatio;		}		zoomChangeX = ((myWidth / 2) - (endW / 2) - hostX);		zoomChangeY = (((myHeight / 2) - (endH / 2) - hostY) + myScroll);		zoomChangeW = (endW - startW);		zoomChangeH = (endH - startH);				// console.log("X: "+zoomChangeX+" Y: "+zoomChangeY+" W: "+zoomChangeW+" H: "+zoomChangeH);		// Setup Zoom     		zoomCurrent = 0;     		// Setup Fade with Zoom, If Requested     		if (fade == 1) {			fadeCurrent = 0;			fadeAmount = (0 - 100) / zoomSteps;		} else {			fadeAmount = 0;		}       		// Do It!				zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+hostX+", "+zoomChangeX+", "+hostY+", "+zoomChangeY+", "+zoomSteps+", "+fade+", "+fadeAmount+", 'zoomDoneIn(zoomID)')", zoomTime);				zoomActive[theID] = true; 	}}// Zoom it back out.function zoomOut() {	// Check to see if something is happening/open  	if (zoomActive[theID] != true) {     		// First, get rid of the shadow if necessary     		document.getElementById("ShadowBox").style.visibility = "hidden";		document.getElementById("ZoomClose").style.visibility = "hidden";     		// Now, figure out where we came from, to get back there		startX = parseInt(zoomdiv.style.left);		startY = parseInt(zoomdiv.style.top);		startW = zoomimg.width;		startH = zoomimg.height;		zoomChangeX = zoomOrigX[theID] - startX;		zoomChangeY = zoomOrigY[theID] - startY;		zoomChangeW = zoomOrigW[theID] - startW;		zoomChangeH = zoomOrigH[theID] - startH;    		// Setup Zoom	   		zoomCurrent = 0;     		// Setup Fade with Zoom, If Requested     		if (fade == 1) {			fadeCurrent = 0;			fadeAmount = (100 - 0) / zoomSteps;		} else {			fadeAmount = 0;		}     		// Do It!		zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+startX+", "+zoomChangeX+", "+startY+", "+zoomChangeY+", "+zoomSteps+", "+fade+", "+fadeAmount+", 'zoomDone(zoomID, theID)')", zoomTime);			zoomActive[theID] = true;   }}// Finished Zooming Infunction zoomDoneIn(zoomdiv, theID) {	// Note that it's open  	zoomOpen = true;	// Make sure they are gone	setOpacity(0, "ShadowBox");	setOpacity(0, "ZoomClose");	// Position the shadow behind the zoomed in image.	zoomdiv = document.getElementById(zoomdiv);	shadowdiv = document.getElementById("ShadowBox"); 	shadowLeft = parseInt(zoomdiv.style.left) - 13;	shadowTop = parseInt(zoomdiv.style.top) - 8;	shadowWidth = zoomdiv.offsetWidth + 26;	shadowHeight = zoomdiv.offsetHeight + 26; 	shadowdiv.style.width = shadowWidth + 'px';	shadowdiv.style.height = shadowHeight + 'px';	shadowdiv.style.left = shadowLeft + 'px';	shadowdiv.style.top = shadowTop + 'px';  	// Display Shadow and Zoom  	document.getElementById("ShadowBox").style.visibility = "visible";	fadeElementSetup("ShadowBox", 0, 100, 5);	document.getElementById("ZoomClose").style.visibility = "visible";	fadeElementSetup("ZoomClose", 0, 100, 5);  }// Finished Zooming Outfunction zoomDone(zoomdiv, theID) {	// No longer open  	zoomOpen = false;	// Clear stuff out, clean up	zoomOrigH[theID] = "";	zoomOrigW[theID] = "";	document.getElementById(zoomdiv).style.visibility = "hidden";	zoomActive[theID] == false;}// Actually zoom the elementfunction zoomElement(zoomdiv, theID, zoomCurrent, zoomStartW, zoomChangeW, zoomStartH, zoomChangeH, zoomStartX, zoomChangeX, zoomStartY, zoomChangeY, zoomSteps, fade, fadeAmount, execWhenDone) {	// console.log("Zooming Step #"+zoomCurrent+ " of "+zoomSteps+" (zoom " + zoomStartW + "/" + zoomChangeW + ") (zoom " + zoomStartH + "/" + zoomChangeH + ")  (zoom " + zoomStartX + "/" + zoomChangeX + ")  (zoom " + zoomStartY + "/" + zoomChangeY + ") Fade: "+fadeAmount);    	// Test if we're done, or if we continue	if (zoomCurrent == (zoomSteps + 1)) {		zoomActive[theID] = false;		clearInterval(zoomTimer[theID]);		if (execWhenDone != "") {			eval(execWhenDone);		}	} else {			// Do the Fade!	  		if (fade != 0) {			if (fadeAmount < 0) {				setOpacity(Math.abs(zoomCurrent * fadeAmount), zoomdiv);			} else {				setOpacity(100 - (zoomCurrent * fadeAmount), zoomdiv);			}		}	  		// Calculate this step's difference, and move it!				moveW = cubicInOut(zoomCurrent, zoomStartW, zoomChangeW, zoomSteps);		moveH = cubicInOut(zoomCurrent, zoomStartH, zoomChangeH, zoomSteps);		moveX = cubicInOut(zoomCurrent, zoomStartX, zoomChangeX, zoomSteps);		moveY = cubicInOut(zoomCurrent, zoomStartY, zoomChangeY, zoomSteps);			document.getElementById(zoomdiv).style.left = moveX + 'px';		document.getElementById(zoomdiv).style.top = moveY + 'px';		zoomimg.style.width = moveW + 'px';		zoomimg.style.height = moveH + 'px';			zoomCurrent++;				clearInterval(zoomTimer[theID]);		zoomTimer[theID] = setInterval("zoomElement('"+zoomdiv+"', '"+theID+"', "+zoomCurrent+", "+zoomStartW+", "+zoomChangeW+", "+zoomStartH+", "+zoomChangeH+", "+zoomStartX+", "+zoomChangeX+", "+zoomStartY+", "+zoomChangeY+", "+zoomSteps+", "+fade+", "+fadeAmount+", '"+execWhenDone+"')", zoomTime);	}}// Zoom Rollover Functions// To be re-addedfunction zoomMouseOver() {//  if (rollOverImg) {//     if (document.getElementById("ZoomImage").src != rollOverImg) {//        document.getElementById("ZoomImage").src = rollOverImg;//     }//  }}function zoomMouseOut() {//  if (rollOverImg) {//     if (document.getElementById("ZoomImage").src != image) {//        document.getElementById("ZoomImage").src = image;//     }//  }}//////////////////////////////// FADE Functions//function fadeOut(elem) {	if (elem.id) {		fadeElementSetup(elem.id, 100, 0, 10);	}}function fadeIn(elem) {	if (elem.id) {		fadeElementSetup(elem.id, 0, 100, 10);		}}// Fade: Initialize the fade functionvar fadeActive = new Array();var fadeQueue  = new Array();var fadeTimer  = new Array();var fadeClose  = new Array();function fadeElementSetup(theID, fdStart, fdEnd, fdSteps, fdClose) {	if (fadeActive[theID] == true) {		// Already animating, queue up this command		fadeQueue[theID] = new Array(theID, fdStart, fdEnd, fdSteps);	} else {		fadeSteps = fdSteps;		fadeCurrent = 0;		fadeAmount = (fdStart - fdEnd) / fadeSteps;		fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 15);		fadeActive[theID] = true;		if (fdClose == 1) {			fadeClose[theID] = true;		} else {			fadeClose[theID] = false;		}	}}// Fade: Do the fade. This function will call itself, modifying the parameters, so// many instances can run concurrently.function fadeElement(theID, fadeCurrent, fadeAmount, fadeSteps) {  	if (fadeCurrent == fadeSteps) {	    // We're done, so clear.	    clearInterval(fadeTimer[theID]);	    fadeActive[theID] = false;	    	    // Should we close it?	    	    if (fadeClose[theID] == true) {	    	document.getElementById(theID).style.visibility = "hidden";	    }	    	    // Hang on.. did a command queue while we were working? If so, make it happen now	    	    if (fadeQueue[theID] && fadeQueue[theID] != false) {	    	fadeElementSetup(fadeQueue[theID][0], fadeQueue[theID][1], fadeQueue[theID][2], fadeQueue[theID][3]);	    	fadeQueue[theID] = false;	    }    	} else {  		fadeCurrent++;				// Set the opacity depending on if we're adding or subtracting (pos or neg)		if (fadeAmount < 0) {			setOpacity(Math.abs(fadeCurrent * fadeAmount), theID);		} else {			setOpacity(100 - (fadeCurrent * fadeAmount), theID);		}				// Keep going, and send myself the updated variables		clearInterval(fadeTimer[theID]);		fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 15);	}}//////////////////////////////// UTILITY functions//// Utility: Set the opacity, compatible with a number of browsers. Value from 0 to 100.function setOpacity(opacity, theID) {	var object = document.getElementById(theID).style;	// If it's 100, set it to 99 for Firefox.	if (navigator.userAgent.indexOf("Firefox") != -1) {		if (opacity == 100) { opacity = 99.9999; } // This is majorly retarded	}	// Multi-browser opacity setting	object.filter = "alpha(opacity=" + opacity + ")"; // IE/Win	//object.KhtmlOpacity = (opacity / 100);            // Safari 1.1 or lower, Konqueror	//object.MozOpacity = (opacity / 100);              // Older Mozilla+Firefox	object.opacity = (opacity / 100);                 // Safari 1.2, Firefox+Mozilla}// Utility: Math functions for animation calucations - From http://www.robertpenner.com/easing///// t = time, b = begin, c = change, d = duration// time = current frame, begin is fixed, change is basically finish - begin, duration is fixed (frames),function linear(t, b, c, d){	return c*t/d + b;}function sineInOut(t, b, c, d){	return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;}function cubicIn(t, b, c, d) {	return c*(t/=d)*t*t + b;}function cubicOut(t, b, c, d) {	return c*((t=t/d-1)*t*t + 1) + b;}function cubicInOut(t, b, c, d){	if ((t/=d/2) < 1) return c/2*t*t*t + b;	return c/2*((t-=2)*t*t + 2) + b;}function bounceOut(t, b, c, d){	if ((t/=d) < (1/2.75)){		return c*(7.5625*t*t) + b;	} else if (t < (2/2.75)){		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;	} else if (t < (2.5/2.75)){		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;	} else {		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;	}}// Utility: Get the size of the window, and set myWidth and myHeightfunction getSize() {	if (document.all) {		// IE4+ or IE6+ in standards compliant 		myWidth  = (document.documentElement.clientWidth) ? document.documentElement.clientWidth : document.body.clientWidth;		myHeight = (document.documentElement.clientHeight) ? document.documentElement.clientHeight : document.body.clientHeight;		myScroll = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;	} else {		// Non-IE		myWidth = window.innerWidth;		myHeight = window.innerHeight;		myScroll = window.pageYOffset;	}		// Core code from - quirksmode.org    if (window.innerHeight && window.scrollMaxY) {	        myScrollWidth = document.body.scrollWidth;		myScrollHeight = window.innerHeight + window.scrollMaxY;	} else if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac		myScrollWidth = document.body.scrollWidth;		myScrollHeight = document.body.scrollHeight;	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari		myScrollWidth = document.body.offsetWidth;		myScrollHeight = document.body.offsetHeight;	}}// Utility: Find the Y position of an element on a page. Return Y and X as an arrayfunction findElementPos(elemFind){	var elemX = 0;	var elemY = 0;	do {		elemX += elemFind.offsetLeft;		elemY += elemFind.offsetTop;	} while ( elemFind = elemFind.offsetParent )	//console.log("Found element "+elemFind+" at "+elemY+"/"+elemX);	return Array(elemX, elemY);}