// Generic functions to expand and shrink an image that is displayed at less than its full size.
// Example usage:
//
// <img
//     id="tools-sqlplus-1"
//     title="First define a new tool" alt="First define a new tool"
//     src="../images/tools-setup-sqlplus1.png"
//     width="200"
//     onMouseOver="expand(this);"
//     onMouseOut="shrink(this);"
//> </img>
//
// William Robertson, www.williamrobertson.net 2008

// Global sequence for assigning to objects that need an ID:
var defaultIdSeq = 0;

// Image expand animation, accepts reference to an image object.
// Actually calls expandById() passing p_img's ID (assigning if necessary) because setTimeout() requires a string argument.
// Works well though IMHO - expand() does all the fancy initialisation and expandById() just provides the animation loop.
function expand (p_img) {
	// Assign default sequential ID if undefined:
	if (p_img.id == "") { p_img.id = ++defaultIdSeq; }

	// Capture starting dimensions for return trip (only capture if not already set):
	if (! p_img.originalHeight) {
		p_img.originalHeight = p_img.height;
		p_img.originalWidth  = p_img.width;
		// console.log(p_img.id + " original dimensions: " + p_img.originalWidth + "x" + p_img.originalHeight);
	}

	// Calculate expand/shrink amount as 10% of difference between thumbnail and full size (calculate only once):
	if (! p_img.heightIncrement) {

		if (! p_img.naturalWidth) {
			// Guess what, IE doesn't have naturalWidth/Height. The workaround is to remove the width and height
			// DOM attributes, read the width and height (how that even works I'll never know), and put them back again...
			// Found it here: http://www.thescripts.com/forum/thread601048.html
			p_img.removeAttribute('width');
			p_img.removeAttribute('height');
			p_img.naturalWidth = p_img.width;
			p_img.naturalHeight = p_img.height;
			p_img.width = p_img.originalWidth;
			p_img.width = p_img.originalHeight;
		}

		p_img.widthIncrement  = (p_img.naturalWidth  - p_img.width)  / 8;
		p_img.heightIncrement = (p_img.naturalHeight - p_img.height) / 8;

		// console.log(p_img.id + "naturalWidth = " + p_img.naturalWidth + " increments: " + p_img.widthIncrement + ", " + p_img.heightIncrement);
	}

	// Note the state of expand/shrink animation, beginning by initialising Boolean indicators if undefined:
	if (! p_img.shrinking) p_img.shrinking = new Boolean(false);

	if (! p_img.expanding) {
		p_img.expanding = new Boolean(true);
	} else if (p_img.expanding == true) {
		// console.log(p_img.id + " already expanding - new expand() call ignored");
		return;
	}

	if (p_img.shrinking == true) {
		// console.log(p_img.id + " already shrinking - new expand() call ignored");
		return;
	} else {
		// console.group(p_img.id);
		p_img.expanding = true;
		// p_img.shrinkLoopCount = 50;  // Loop counter for debugging and stopping runaway shrink loops
		expandById(p_img.id);
	}
}

function expandById (p_imgId) {
	var v_img = document.getElementById(p_imgId);

	// Abort if the image is currently shrinking, to avoid chaos:
	if (v_img.shrinking == true) {
		v_img.expanding = false;
		return;
	}

	var v_newWidth = v_img.width + v_img.widthIncrement;
	if (v_newWidth > v_img.naturalWidth) v_newWidth = v_img.naturalWidth;

	var v_newHeight = v_img.height + v_img.heightIncrement;
	if (v_newHeight > v_img.naturalHeight) v_newHeight = v_img.naturalHeight;

	if (v_img.width < v_img.naturalWidth || v_img.height < v_img.naturalHeight) {
		v_img.height = v_newHeight;
		v_img.width  = v_newWidth;

		setTimeout("expandById('" + v_img.id + "')", 0);
	} else {
		v_img.expanding = false;
	}
}

function shrink (p_img) {
	// Note the state of expand/shrink animation:
	if (p_img.shrinking == true) {
		return;
	} else {
		// console.group(p_img.id);
		p_img.shrinking = true;
		p_img.expanding = false;
		shrinkById(p_img.id);
	}
}

function shrinkById (p_imgId) {
	var v_img = document.getElementById(p_imgId);

	var v_startWidth  = v_img.width;
	var v_startHeight = v_img.height;

	var v_newWidth = (v_startWidth - v_img.widthIncrement);
	if (v_newWidth < v_img.originalWidth) v_newWidth = v_img.originalWidth;

	var v_newHeight = (v_startHeight - v_img.heightIncrement);
	if (v_newHeight < v_img.originalHeight) v_newHeight = v_img.originalHeight;

	// console.group(v_img.id + ": reducing dimensions " + v_startWidth + "x" + v_startHeight + " by " + v_img.widthIncrement + "x" + v_img.heightIncrement + " to " + v_newWidth + "x" + v_newHeight);

	if (v_startWidth > v_img.originalWidth || v_startHeight > v_img.originalHeight) {
		// console.log(v_img.id + ": Shrinking: " + v_img.width + "x" + v_img.height + " greater than " + v_img.originalWidth + "x" + v_img.originalHeight)
		v_img.height = v_newHeight;
		v_img.width  = v_newWidth;

		// console.groupEnd();
		setTimeout("shrinkById('" + v_img.id + "')", 0);
	} else {
		v_img.expanding = false;
		v_img.shrinking = false;
		// console.groupEnd();
		v_img.height = v_img.originalHeight;
		v_img.width  = v_img.originalWidth;
	}
}

function swapSrc (p_img) {
    var v_img = new Image();
    v_img.src = p_img.getAttribute("overSrc");

    p_img.setAttribute("overSrc", p_img.src);
    p_img.src = v_img.src;
}

