//**************************************************
//	Overlay Module
//**************************************************
//	Can pop up overlays(divs) with user defined
//	content. Following the mouse is supported for
//	FF as well as IE. Other Browsers not testet.
//--------------------------------------------------
//	+ Use function "Overlay" to open up a new overlay
//	+ Be careful to always close an overlay some time!
//	  It is possible for the user to layer up multiple
//	  instances of it (Overlay Module does not care
//	  about closing an overlay at the right time)
//	+ It's best to use Overlay_CloseAll() whenever
//	  possible, since it clears the
//	  document.onmousemove function cascade
//--------------------------------------------------

//**************************************************
//	functions to be called from outside
//**************************************************
//call this function to open up an overlay (e is only needed when OL_FOLLOWMOUSE or OL_MOUSEPOS is set)
function Overlay(params)//e, content, flags, left, top)
{
	//alert("new overlay");
	var e = null;
	var content = "Overlay";
	var mousePos = false;
	var closeOthers = true;
	var followMouse = true;
	var isDom = false;
	var left = 15;
	var top = 15;
	var vertical_align = "bottom";
	var horizontal_align = "right";
	var overlay_delay = 200;
	var overlay_fade = false;
	var overlay_fade_speed = 200;
	var overlay_close_timeout = 0;		//timeout closes the overlay after "overlay_close_timeout"ms of no mousemove. 0 means no timeout close
	var overlay_close_onclick = false;
	var overlay_close_callback = null;

	if(typeof(params.event)	!= "undefined")						var e = params.event;
	if(typeof(params.content)	!= "undefined")					content = params.content;
	if(typeof(params.mousePos)	!= "undefined")					mousePos = params.mousePos;
	if(typeof(params.closeOthers)	!= "undefined")				closeOthers = params.closeOthers;
	if(typeof(params.followMouse)	!= "undefined")				followMouse = params.followMouse;
	if(typeof(params.isDom)	!= "undefined")						isDom = params.isDom;
	if(typeof(params.left)	!= "undefined")						left = params.left;
	if(typeof(params.top)	!= "undefined")						top = params.top;
	if(typeof(params.vertical_align)	!= "undefined")			vertical_align = params.vertical_align;
	if(typeof(params.horizontal_align)	!= "undefined")			horizontal_align = params.horizontal_align;
	if(typeof(params.overlay_delay)	!= "undefined")				overlay_delay = params.overlay_delay;
	if(typeof(params.overlay_fade)	!= "undefined")				overlay_fade = params.overlay_fade;
	if(typeof(params.overlay_fade_speed)	!= "undefined")		overlay_fade_speed = params.overlay_fade_speed;
	if(typeof(params.overlay_close_timeout)	!= "undefined")		overlay_close_timeout = params.overlay_close_timeout;
	if(typeof(params.overlay_close_onclick)	!= "undefined")		overlay_close_onclick = params.overlay_close_onclick;
	if(typeof(params.overlay_close_callback)	!= "undefined")	overlay_close_callback = params.overlay_close_callback;

	//Create DIV containing content
	var oDiv = document.createElement("div");
	oDiv.setAttribute("id", "oOverlayDiv");
	oDiv.style.position = "absolute";
	oDiv.event = e;
	oDiv.mousePos = mousePos;
	oDiv.closeOthers = closeOthers;
	oDiv.followMouse = followMouse;
	oDiv.left = left;
	oDiv.top = top;
	oDiv.vertical_align = vertical_align;
	oDiv.horizontal_align = horizontal_align;
	oDiv.overlay_delay = overlay_delay;
	oDiv.overlay_fade = overlay_fade;
	oDiv.overlay_fade_speed = overlay_fade_speed;
	oDiv.overlay_close_timeout = overlay_close_timeout;
	oDiv.overlay_close_onclick = overlay_close_onclick;
	oDiv.overlay_close_callback = overlay_close_callback;

	oDiv.alreadyRemovedFromBody = false;	//needed to prevent an error with timout wanting to remove the overlay and onclick already did

	//is "content" already a DOM object? -> append directly
	if(isDom)
		oDiv.appendChild(content);
	else		//no it's a string -> innerHTML
		oDiv.innerHTML = content;

	//close the other overlays?
	if(closeOthers)
		Overlay_CloseAll();

	oDiv.style.visibility = "hidden";
	document.body.appendChild(oDiv);
	//align
	if(vertical_align == "top"){
		oDiv.top = - oDiv.top;
		oDiv.top -= oDiv.offsetHeight;
	}
	else if(vertical_align == "center")
		oDiv.top = - Math.round(oDiv.offsetHeight/2);

	if(horizontal_align == "left"){
		oDiv.left = - oDiv.left;
		oDiv.left -= oDiv.offsetWidth;
	}
	else if(horizontal_align == "center")
		oDiv.left = - Math.round(oDiv.offsetWidth/2);

	//should the overlay follow the mouse? (left/top is used as offset)
	if(followMouse){
		oUpdatePosToMouse(oDiv);
		oHookToMouseMove(function(e){if(!oDiv)return; oDiv.event = e; oUpdatePosToMouse(oDiv);});
	}
	//set overlay to mouse position?
	else if(mousePos)
		oUpdatePosToMouse(oDiv); //e needed for FF
	else
		oUpdatePos(oDiv, oDiv.left, oDiv.top);

	if(overlay_close_timeout != 0)
		oDiv.onmousemove = function(){this.closeTimeout = 0;};
	if(overlay_close_onclick == true)
		oDiv.onclick = function(){Overlay_TurnInvisible(this);};

	//make it visible
	window.setTimeout(function(){Overlay_TurnVisible(oDiv); if(overlay_close_timeout != 0)window.setTimeout(function(){Overlay_Do_CloseTimeout(oDiv);}, 50);},overlay_delay);

	//return the overlay div
	return oDiv;
}

function Overlay_Do_CloseTimeout(oDiv) {
	if(typeof(oDiv) == "undefined")
		return;
	if(oDiv.alreadyRemovedFromBody)
		return;
	oDiv.closeTimeout += 200;
	if(oDiv.closeTimeout >= oDiv.overlay_close_timeout)
		Overlay_TurnInvisible(oDiv);
	else
		window.setTimeout(function(){Overlay_Do_CloseTimeout(oDiv);}, 200);
}

function oGetOverlayPosition(elem)
{
	var tagname='div',x=0,y=0;

	// solange elem ein Objekt ist und die Eigenschaft offsetTop enthaelt
	//   wird diese Schleife fuer das Element und all seine Offset-Eltern ausgefuehrt
	while ((typeof(elem)=='object')&&(typeof(elem.tagName)!='undefined'))
	{
		y+=elem.offsetTop;     // Offset des jeweiligen Elements addieren
		x+=elem.offsetLeft;    // Offset des jeweiligen Elements addieren
		tagname=elem.tagName.toUpperCase(); // tag-Name ermitteln, Grossbuchstaben

		// wenn beim Body-tag angekommen elem fuer Abbruch auf 0 setzen
		if (tagname=='BODY')
			elem=0;

		// wenn elem ein Objekt ist und offsetParent enthaelt
		//   Offset-Elternelement ermitteln
		if (typeof(elem)=='object')
			if (typeof(elem.offsetParent)=='object')
				elem=elem.offsetParent;
	}

	// Objekt mit x und y zurueckgeben
	position=new Object();
	position.x=x;
	position.y=y;
	return position;
}

function Overlay_TurnVisible(divObj) {
	if(divObj.overlay_fade){
		divObj.style.visibility = "visible";
		Overlay_Fade({div:divObj});
	}
	else
		divObj.style.visibility = "visible";
}

function Overlay_TurnInvisible(divObj) {
	if(divObj.alreadyRemovedFromBody)
		return;
	if(divObj.overlay_fade)
		Overlay_Fade({div:divObj, callback:function(d){document.body.removeChild(d); d.alreadyRemovedFromBody = true; if(typeof(d.overlay_close_callback) == "function") d.overlay_close_callback(d);}, direction:"fade out"});
	else{
		document.body.removeChild(divObj);
		divObj.alreadyRemovedFromBody = true;
		if(typeof(divObj.overlay_close_callback) == "function") divObj.overlay_close_callback(divObj);
	}
}

function Overlay_Fade(params, fromTimeout) {
	var div = params.div;
	var callback = params.callback;
	if(typeof(div.oFade_callback) == "undefined")
		div.oFade_callback = callback;
	var direction = "fade in";
	if(params.direction)
		direction = params.direction;
	var speed = div.overlay_fade_speed;
	var val = (100/speed)*50;

	if(typeof(div.oOpacity) == "undefined")
		div.oOpacity = 0;
	if(typeof(div.oFade_CurDir) == "undefined")
		div.oFade_CurDir = "finished";

	if(!div)
		return;

	if((div.oFade_CurDir != "finished") && !fromTimeout) {
		//alert("nicht fertig, nicht vom timeout angestoßen\n"+direction);
		div.oFade_callback = callback;
		if(div.oFade_CurDir == direction)
			return;
		else{
			div.oFade_CurDir = direction;
			return;
		}
	}
	if(!fromTimeout){
		div.oFade_CurDir = direction;
		//alert("fertig, aber nicht vom timeout angestoßen\n"+direction);
	}

	//div.oFade_CurDir = "fade in";
	if(div.oFade_CurDir == "fade in")
		div.oOpacity += val;
	else if(div.oFade_CurDir == "fade out"){
		div.oOpacity -= val;
	}
	else
		alert("Overlay_Fade: ungültige Direction (div.oFade_CurDir): "+div.oFade_CurDir);

	var opacity = div.oOpacity;

    var object = div.style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
   // alert(object.filter);

	if(opacity < 1){
		if(div.oFade_CurDir == "fade out"){
			div.oFade_CurDir = "finished";
			if(div.oFade_callback)
				div.oFade_callback(div);
			return;
		}
	}
	else if(opacity > 99){
		if(div.oFade_CurDir == "fade in"){
			div.oFade_CurDir = "finished";
			if(div.oFade_callback)
				div.oFade_callback(div);
			return;
		}
	}
	else
   		window.setTimeout(function(){Overlay_Fade(params, true);},50);
}

//closes all overlays (all divs with ID == oOverlayDiv)
function Overlay_CloseAll()
{
	document.onmousemove = null;
	while(document.getElementById("oOverlayDiv")){
		var obj = document.getElementById("oOverlayDiv");
		obj.setAttribute("id", "Overlay_CloseAll_closed");
		Overlay_TurnInvisible(obj);
	}
}

//closes a given overlay (USE Overlay_CloseAll() WHENEVER POSSIBLE)
function Overlay_CloseThis(div)
{
	if(div.id == "oOverlayDiv"){
		if(div.overlay_fade)
			Overlay_TurnInvisible(div);
		else
			document.body.removeChild(div);
	}
}


//**************************************************
//	functions called internally
//**************************************************
//sets the document.onmousemove for OL_FOLLOWMOUSE
/*function oSetOnMouseMove(oDiv) //, left, top)
{
	var left = oDiv.left;
	var top = oDiv.top;

	var oldOnMove = document.onmousemove;
	if(typeof document.onmousemove != "function")	//is there an onMove to be saved?
		document.onmousemove = function(e){
			oDiv.event = e;
			if(oDiv){
				oUpdatePosToMouse(oDiv);
				Overlay_WatchMousePos(e, oDiv);
			}
		};
	else	//yes there is
	{
		document.onmousemove = function(e){
			oDiv.event = e;
			if(oldOnMove)oldOnMove(oDiv);
			if(oDiv){
				oUpdatePosToMouse(oDiv);
				Overlay_WatchMousePos(e, oDiv);
			}
		}
	}
}*/

function oGetMousePos(e){
	var posx = 0;
	var posy = 0;

	if (!e) var e = window.event;
	if (e.pageX || e.pageY) 	{
		posx = e.pageX;
		posy = e.pageY;
	}
	else if (e.clientX || e.clientY) 	{
		posx = e.clientX + document.body.scrollLeft
			+ document.documentElement.scrollLeft;
		posy = e.clientY + document.body.scrollTop
			+ document.documentElement.scrollTop;
	}

	return {x:posx, y:posy};
}

function oHookToMouseMove(fct) {
	if(!fct)
		return;
	var oldOnMove = document.onmousemove;
	if(typeof document.onmousemove != "function"){	//is there an onMove to be saved?
		document.onmousemove = fct;					//no there isn't
	}
	else											//yes there is
	{
		document.onmousemove = function(e){
			if(oldOnMove)oldOnMove(e);
			fct(e);
		};
	}
}
//sets the overlay(div) position to mouse position (the event is needed for FF) + offset
function oUpdatePosToMouse(div)//, e, lOffset, tOffset)
{
	var e = div.event;
	var lOffset = div.left;
	var tOffset = div.top;
	//alert("UpdatePos");
	var mPos = oGetMousePos(e);
	//alert(parseInt(mPos.x+lOffset, 10) + " " + parseInt(mPos.y+tOffset, 10));
	oUpdatePos(div, mPos.x+lOffset, mPos.y+tOffset);
	/*
	if(window.event)	//IE
	{
		oUpdatePos(div, window.event.clientX+lOffset, window.event.clientY+tOffset);

	}
	else				//FF
		oUpdatePos(div, ev.clientX+lOffset, ev.clientY+tOffset);
	*/
}

//sets the overlay(div) position to left/top
function oUpdatePos(div, left, top)//, left, top)
{
	div.style.left = Math.abs(left)+"px";
	div.style.top = Math.abs(top)+"px";
}
