/*
 * hovergrid.js
 *
 * Controls hovering content for "hovergrid" lists
 *
 * @author scampbell
 */

//var preloaded = new Array();

//var SRC_OFF = /^(.*)\.([^.]*)$/ ;	// matches everything before and after the last full-stop
//var SRC_ON = /^(.*)_on\.([^.]*)$/ ;	// matches everything before and after the image-name "on" suffix (and last full-stop)

// Insert initialisation code
var _hovergrid_js_wOnload = window.onload;
window.onload = function() {
	if (_hovergrid_js_wOnload != null) {
		_hovergrid_js_wOnload();
	}

	var grid = document.getElementById("hovergrid1");
	var gridItems = grid.getElementsByTagName("li");

	// square off the grid to a multiple of 5
	var extraItems = gridItems.length % 5;
	if (extraItems != 0) {
		for (var ii = 0; ii < (5 - extraItems); ii++) {
			var gItem = document.createElement("li");
			grid.appendChild(gItem);
		}
	}

	// recount for potentially added elements (necessary?)
	gridItems = grid.getElementsByTagName("li");

	// apply styles for edge elements and attach hover listeners
	for (var ii = 0; ii < gridItems.length; ii++) {
		var gridItem = gridItems[ii];

		if (ii < 5) {
			gridItem.className += " firstRow";
		}
		if (ii % 5 == 0) {
			gridItem.className += " firstCol";
		}

		var img = gridItem.getElementsByTagName("img").item(0);
		if (img != null) {
			// preload hover image
			//var hoverImage = new Image();
			//hoverImage.src = img.src.replace(SRC_OFF, "$1_on.$2");
			//preloaded.push(hoverImage);

			// attach hover listeners
			gridItem.onmouseover = startHover;
			gridItem.onmouseout = endHover;
		}
	}
}


// Keep track of the hovering element
var currHover = null;
var lastPos = null;


/**
 * Starts a hover effect on an element with a hidden <div>.
 *
 * @param e The associated MouseEvent
 */
function startHover(e) {
	// check if a hover has already been started
	if (currHover != null) {
		return false;
	}

	var el = this;
	el.style.zIndex = "2";

	// ":hover" emulation - so only elements with images get the styles applied
	el.className += " hover";

	currHover = el.getElementsByTagName("div").item(0);

	//@todo: Image state

	// now check that we could find an element to show
	if (!currHover) {
		return false;
	}

	// find our "origin" - the position of the containing element
	var originX = 0;
	var originY = 0;
	var offsetEl = el;
	while (offsetEl != null) {
		originX += offsetEl.offsetLeft;
		originY += offsetEl.offsetTop;

		offsetEl = offsetEl.offsetParent;
	}

	//alert("Parent pos:\nx=" + originX + ",y=" + originY);

	var mPos = getPos(e);

	var startX = mPos.x - originX + 5;
	var startY = mPos.y - originY + 5;

	//alert("Relative to parent:\nstartX=" + startX + ",startY=" + startY);

	// display <p> at current mouse position
	currHover.style.left = startX + "px";
	currHover.style.top = startY + "px";
	currHover.style.display = "block";

	// maintain a purely numeric coordinate representation
	currHover._hoverX = startX;
	currHover._hoverY = startY;

	lastPos = mPos;

	// activate hover image
	//var img = el.getElementsByTagName("img").item(0);
	//img.src = img.src.replace(SRC_OFF, "$1_on.$2");

	document.onmousemove = doHover;
}


/**
 * Moves the currently hovering element when the mouse
 * is moved.
 *
 * @param e The associated MouseEvent
 */
function doHover(e) {
	if (currHover == null) {
		return false;
	}

	var mPos = getPos(e);

	diffX = mPos.x - lastPos.x;
	diffY = mPos.y - lastPos.y;

	lastPos = mPos;

	// update internal (numeric) coordinates
	currHover._hoverX += diffX;
	currHover._hoverY += diffY;

	// update actual (CSS) coordinates
	currHover.style.left = currHover._hoverX + "px";
	currHover.style.top = currHover._hoverY + "px";
}


/**
 * Ends the hover effect on an element.
 */
function endHover() {
	if (currHover == null) {
		return false;
	}

	var el = this;
	el.style.zIndex = "1";

	// ":hover" emulation - so only elements with images get the styles applied
	el.className = el.className.replace("hover", "");


	//var img = el.getElementsByTagName("img").item(0);
	//img.src = img.src.replace(SRC_ON, "$1.$2");

	currHover.style.display = "none";
	currHover._hoverX = null;
	currHover._hoverY = null;

	document.onmousemove = null;
	currHover = null;
	lastPos = null;
}


/**
 * Returns the current x- and y-coordinates of the mouse pointer,
 * relative to the top-left corner of the document.
 *
 * @param e The window event
 *
 * @return A simple object with properties x and y, which hold
 *         the current position of the mouse pointer.
 */
function getPos(e) {
	if (!e) {
		e = window.event;
	}

	if (e.pageX || e.pageY) {
		_x = e.pageX;
		_y = e.pageY;
	}
	else if (e.clientX || e.clientY) {
		_x = e.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		_y = e.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
	}

	return { x:_x, y:_y };
}