

// 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   = '/images-global/zoom/'; // 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);

}