// flyover.js: Implementation file for SearchShield flyovers.
//
// Copyright 2006-2007 Exploit Prevention Labs, Inc.

function ShowFlyover()
{
	var div = document.getElementById("XPLSS_Flyover");
	if (div == null)
		return;

	div.style.visibility = "visible";

	var trans_div = document.getElementById("XPLSS_Trans");
	if (trans_div == null)
		return;
	trans_div.style.visible = "visible";
}

function containedIn(container, element)
{
	while (element != null) 
	{
		if (container == element) 
		{
			return true;
		}
		element = element.parentNode;
	}
	return false;
}


// if an onmousemove already set we will save and restore it
var orig_onmousemove = null;

function HideFlyover(e)
{
	var div = document.getElementById("XPLSS_Flyover");
	if ((div == null) || (div.style == null) || (div.style.visibility == "hidden"))
		return;

	var trans_div = document.getElementById("XPLSS_Trans");
	if ((trans_div == null) || (trans_div.style == null) || (trans_div.style.visibility == "hidden"))
		return;

	// restore onmousemove
	if (orig_onmousemove != null)
		document.onmousemove = orig_onmousemove;

	// make sure we aren't still over the popped image or our layer
	if (containedIn(div, e.relatedTarget) || (typeof(poppedElement) == "undefined")	||
		containedIn(poppedElement, e.relatedTarget)	|| containedIn(trans_div, e.relatedTarget))
	{
		return;
	}
	// else hide the element

	// hide and move somewhere off screen (negative offsets)
	div.style.visibility = "hidden";
	div.style.left = -2100;
	div.style.top  = -2100;
	trans_div.style.visibility = "hidden";
	trans_div.style.left = -2100;
	trans_div.style.top  = -2100;
}


var poppedUp = false;
var poppedElement = null;

function PopupFlyover(event, hash, search, flyover)
{
	var div = document.getElementById("XPLSS_Flyover");
	if (div == null)
		return;

	// if the element is the clock, don't pop over it
	if ((event.currentTarget.src != null) &&
		(event.currentTarget.src.indexOf("clock.gif") != -1))
		return;
	
	// save the element we popped over
	poppedElement = event.currentTarget;	

	// if no flyover get it
	if ((flyover == null) || (flyover == ""))
	{
		// get flyover data element, used to pass data
		var element = document.getElementById("XplFlyoverDataElement");
		if (element == null)
		{
			element = document.createElement("xplflyoverdata");
			element.setAttribute("id", "XplFlyoverDataElement");
			document.documentElement.appendChild(element);
		}

		// set search and hash
		element.setAttribute("hash", hash);
		element.setAttribute("search", search);

		// send the event to get the flyover data
		var evt = document.createEvent("Events");
		evt.initEvent("xplflyover", true, false);
		element.dispatchEvent(evt);

		flyover = element.getAttribute("flyover");
		if (flyover == null)
			return;

		// cleanup flyover, replace any new lines
		flyover = flyover.replace(/\r/g, "");
		flyover = flyover.replace(/\n/g, "");
		// escape any single quotes
		flyover = flyover.replace(/'/g, "\\'");

		if (poppedElement != null)
			poppedElement.setAttribute("onmouseover", "PopupFlyover(event,'" + hash + "','" + search + "','" + flyover + "')");
	}

	// set the html in the layer
	div.innerHTML = flyover;
	poppedUp = true;


	// reset display count
	count = 0;

	div.onmouseout = HideFlyover;

	// if an onmousemove is already set and it isn't us, save it and restore later
	if ((document.onmousemove != null) && (document.onmousemove != MoveFlyover))
		orig_onmousemove = document.onmousemove;
	document.onmousemove = MoveFlyover;
}


var count = 0;

function MoveFlyover(e)
{
	if (!poppedUp || (poppedElement == null))
		return;

	var flyover = document.getElementById("XPLSS_Flyover");
	if (flyover == null)
		return;

	// relative position of flyover in relation to icon
	var locateX = 0;  // 0=left, 1=right
	var locateY = 0;  // 0=above, 1=below, 2=beside icon

	var scrollXWidth = 19;  // approx

	// get window sizes
	var windowX = window.innerWidth - scrollXWidth;
	var windowY = window.innerHeight;

	// get the exact size of the flyover
	var style = document.defaultView.getComputedStyle(flyover, null);
	var flyoverX = parseInt(style.width);
	var flyoverY = parseInt(style.height);

	// half width/height of element popped over
	var halfX= poppedElement.width / 2;
	var halfY= poppedElement.height / 2;

	// element the mouse is over, get the center position
	var posX = offsetLeft(poppedElement) + halfX;
	var posY = offsetTop(poppedElement)  + halfY;

	// normalize pos to 0
	posX -= window.pageXOffset;
	posY -= window.pageYOffset;

	// setup the offsets
	var offsetX = posX;
	var offsetY = posY;

	// calc where to display on page
	if ((windowX - posX) > posX)
	{
		// right
		offsetX += 15;
		locateX = 1;
	}
	else
	{
		//left
		offsetX -= (flyoverX + 10);
	}
	if ((windowY - posY) > posY)
	{
		// below
		if (posY < (windowY/4))
		{
			offsetY -= 15;
			locateY = 1;
		}
		else
		{
			offsetY -= (flyoverY / 2);
			locateY = 2;
		}
	}
	else
	{
		// above
		if ((windowY - posY) < (windowY/4))
			offsetY -= flyoverY;
		else
		{
			offsetY -= (flyoverY / 2);
			locateY = 2;
		}
	}
	// make sure we aren't off the screen
	if (offsetY < 0)
		offsetY = 0;
	if ((offsetY + flyoverY) > windowY)
		offsetY = windowY - flyoverY;

	// add page offsets back
	offsetX += window.pageXOffset;
	offsetY += window.pageYOffset;
	posX += window.pageXOffset;
	posY += window.pageYOffset;

	// set where to put the flyover
	flyover.style.top = offsetY + "px";
	flyover.style.left= offsetX + "px";

	// set where to put the transparent layer
	var trans = document.getElementById("XPLSS_Trans");
	trans.style.width = flyoverX + "px";
	trans.style.height= flyoverY + "px";
	if (trans != null)
	{
		var trans_left = 0;
		var trans_top  = 0;

		// transparent layer should overlap image a little
		if (locateX == 0)
			trans_left = posX - flyoverX - halfX;  // left 
		else
			trans_left = posX + halfX; // right

		if (locateY == 0)
			trans_top = posY - flyoverY + 20; // above
		else if (locateY == 1)
			trans_top = posY - 20; // below
		else
			trans_top = posY - (flyoverY / 2); // beside icon

		trans.style.left = trans_left + "px";
		trans.style.top  = trans_top + "px";
	}

	DisplayFlyover();
}


function DisplayFlyover()
{
	count++;
	if (count == 1)
	{
		var flyover = document.getElementById("XPLSS_Flyover");
		if (flyover == null)
			return;

		// show the flyover, must use a little count to tell, crazy stuff
		flyover.style.visibility = "visible";

		// show the transparent layer
		var trans_div = document.getElementById("XPLSS_Trans");
		if (trans_div == null)
			return;
		trans_div.style.visibility = "visible";

		poppedUp = false;
	}
}

function offsetTop(element)
{
	var offset = element.offsetTop;
	while (element.offsetParent)
	{
		element = element.offsetParent;
		offset += element.offsetTop;
	}

	return offset;
}

function offsetLeft(element)
{
	var offset = element.offsetLeft;
	while (element.offsetLeft)
	{
		element = element.offsetParent;
		offset += element.offsetLeft;
	}

	return offset;
}


window.addEventListener("DOMMouseScroll", HideFlyover, false);
document.onmousemove = MoveFlyover;
document.onmouseout	 = HideFlyover;

