//Element Position Scripts
//Tristan Harmer
//June 2005

//The scripts in this file are used to work out the position elements 
//and the mouse pointer relative to the document and other elements.
//A lot of the work here is based on information found at quirksmode.org.

//Assumptions & Info
//
// - The html of a page using this script must contain the following prologue
//   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
//   This ensures that the browser uses strict mode when interpretting the markup.
//	 Not including this will yield inaccurate results for IE windows.
//
// - The border and margin of the body (document) element must are set to zero.
//   Setting these to anything other than zero will yield inaccurate results.
// 	 Settings the body padding affects mac IE (safari, mozilla/ffox, netscape and opera work).
//
// - The border and padding of the element must be set using px if this is to work in IE. 
//   Using others (em etc) will yield inaccurate results for IE windows.


//Type definition for coordinate pair
function coord(x,y)
{

	this.x = x;
	this.y = y;
	
}
	
//Gets the pixel position of the mouse relative to the DOCUMENT
//Based on the function found at quirksmode.org
function getMouseClientPosition(mouseEvent)
{
	
	var mouseCoord = new coord(0,0);

	if (!mouseEvent) var mouseEvent = window.event;
	
	//Preferred method (Opera, Konqueror/safari, iCAB)
	if (mouseEvent.pageX || mouseEvent.pageY)
	{
		mouseCoord.x = mouseEvent.pageX;
		mouseCoord.y = mouseEvent.pageY;
	}
	//Alternate method (IE, Mozilla/firefox, Netscape)
	else if (mouseEvent.clientX || mouseEvent.clientY)
	{
	    if (document.documentElement.scrollLeft || document.documentElement.scrollTop)
	    {
		    mouseCoord.x = mouseEvent.clientX + document.documentElement.scrollLeft;
		    mouseCoord.y = mouseEvent.clientY + document.documentElement.scrollTop;
	    }
	    else
	    {
		    mouseCoord.x = mouseEvent.clientX + document.body.scrollLeft;
		    mouseCoord.y = mouseEvent.clientY + document.body.scrollTop;
		}
	}
	
	return mouseCoord;
	
}

//Returns the pixel position of an element relative to the left of the DOCUMENT
//Based on the function found at quirksmode.org
function findPosX(obj)
{
	var curleft = 0;
	if (!obj) return;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
		
	return curleft;
}

//Returns the pixel position of an element relative to the top of the DOCUMENT
//Based on the function found at quirksmode.org
function findPosY(obj)
{
	var curtop = 0;
	if (!obj) return;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
		
	return curtop
}

//Returns the pixel position of the mouse relative to an ELEMENT
function getMouseElementPosition(element, mouseEvent)
{
	
	var mouseCoord;
	var topOffset = 0;
	var leftOffset = 0;
	var computedStyle = null;
	var docComputedStyle = null;
	
	//Get mouse position relative to document
	mouseCoord = getMouseClientPosition(mouseEvent);
	
	//Attempt to get computed style of element
	if (window.getComputedStyle) 
	{		
		computedStyle = window.getComputedStyle(element, null)
		
	}
	else if (document.defaultView && document.defaultView.getComputedStyle)
	{
		computedStyle = document.defaultView.getComputedStyle(element, null)
	}
	
	//Get combined width of border and padding (margin isn't considered part of the image)
	//Computed style is the preferred method.
	//All major browsers except IE windows support this.
	if (computedStyle)
	{
	
		//preferred method (ref: quirksmode.org)
		topOffset += parseInt(computedStyle.getPropertyValue('border-top-width').toLowerCase().replace("px", ""));
		if (isNaN(topOffset)) topOffset = 0;
		topOffset += parseInt(computedStyle.getPropertyValue('padding-top').toLowerCase().replace("px", ""));
		if (isNaN(topOffset)) topOffset = 0;
		
		leftOffset += parseInt(computedStyle.getPropertyValue('border-left-width').toLowerCase().replace("px", ""));
		if (isNaN(leftOffset)) leftOffset = 0;
		leftOffset += parseInt(computedStyle.getPropertyValue('padding-left').toLowerCase().replace("px", ""));
		if (isNaN(leftOffset)) leftOffset = 0;
		
	}
	else if (element && element.currentStyle && navigator.userAgent.toLowerCase().indexOf('; mac') == -1)
	{
		
		//IE method
		topOffset += parseInt(element.currentStyle.borderTopWidth.toLowerCase().replace("px", ""));
		if (isNaN(topOffset)) topOffset = 0;
		topOffset += parseInt(element.currentStyle.paddingTop.toLowerCase().replace("px", ""));
		if (isNaN(topOffset)) topOffset = 0;
		topOffset += 2
		
		leftOffset += parseInt(element.currentStyle.borderLeftWidth.toLowerCase().replace("px", ""));
		if (isNaN(leftOffset)) leftOffset = 0;
		leftOffset += parseInt(element.currentStyle.paddingLeft.toLowerCase().replace("px", ""));
		if (isNaN(leftOffset)) leftOffset = 0;
		leftOffset += 2
		
		if (isNaN(topOffset)) topOffset = 0;
		if (isNaN(leftOffset)) leftOffset = 0;
		
	}
	//Subtract image position and add offsets
	
	mouseCoord.x -= findPosX(element) + leftOffset;
	mouseCoord.y -= findPosY(element) + topOffset;
	
	return mouseCoord;
	
}

function splitCoord(coord, xTarget, yTarget)
{
	
	xTarget = coord.x;
	yTarget = coord.y;

}	

//debug function
//prints mouse coordinates to the toolbar 
function printCoord(c)
{

	window.status = "mouse x:" + c.x + "; y:" + c.y;
	
	return;

}

//debug function
//prints mouse coordinates to the toolbar 
function alertCoord(c)
{

	alert("mouse x:" + c.x + "; y:" + c.y);
	
	return;

}
