//
// Overlay.js
//
// Copyright 2001 by Anthony Howe.  All rights reserved.
//

//
// var instanceName = new Overlay('instanceName');
//
// The instanceName string is used to construct dynamic functions
// for onMouseOver and onMouseOut event that refer to this instance
// of the object.
//
function Overlay(instanceName)
{
	// do nothing
	status = '';

	this.id = null;
	this.closeTimer = null;
	this.isMouseOverTrigger = false;
	this.isMouseOverOverlay = false;

	if (instanceName == null)
		this.instanceName = 'Overlay';
	else
		this.instanceName = instanceName;
}

//
// Overlay.getElementById(id)
//
function OverlayGetElementById(id)
{
	if (document.getElementById)
		return document.getElementById(id);
	if (document.layers)
		return document.layers[id];
	if (document.all)
		return document.all[id];
	return null;
}

//
// overlay.open(id, x, y)
// overlay.open(id, event)
//
function OverlayOpen(id, x, y)
{
statusline('Open('+id+') ');
	var e;

	if (this.closeTimer != null) {
		clearTimeout(this.closeTimer);
		this.closeTimer = null;
	}

	if (this.id != null && this.id != id) {
		this.isMouseOverTrigger = false;
		this.isMouseOverOverlay = false;
		OverlayOff(this.id);
	}

	// Avoid having the layer follow the mouse around the trigger.
	if (this.isMouseOverTrigger)
		return true;

	this.isMouseOverTrigger = true;

//	if (Overlay.isOn(id))
//		return true;

	// Should we position the layer near the mouse event position?
	if (arguments.length == 2) {
		e = x;
		if (document.getElementById || document.all) {
			x = e.clientX - 30;
			y = e.clientY - 30;
		} else {
			x = e.pageX - 30;
			y = e.pageY - 30;
		}
	}

	// Setup mouse traversal handlers.
	this.id = id;
	e = OverlayGetElementById(id);
	e.onmouseout = OverlayMouseOutFn(this);
	e.onmouseover = OverlayMouseOverFn(this);

	OverlayOn(id, x, y);

	return true;
}

//
// overlay.close()
//
function OverlayClose()
{
statusline('Close('+this.id+') ');
	this.isMouseOverTrigger = false;

	// Allow time to traverse mouse from trigger region to overlay.
	this.closeTimer = setTimeout(OverlayMouseOutFn(this), Overlay.CloseTimerMilliSeconds);

	return true;
}

//
// OverlayMouseOverFn(instance)
//
// Create an onMouseOver event function that refers to a specific
// Overlay instance.
//
function OverlayMouseOverFn(obj)
{
	return new Function ('e',
 'statusline(\'Over('+obj.id+')\');'
+'if ('+obj.instanceName+'.closeTimer != null) clearTimeout('+obj.instanceName+'.closeTimer);'
+obj.instanceName+'.isMouseOverOverlay = true;'
+obj.instanceName+'closeTimer = null;'
+'return true;'
	);
}

//
// OverlayMouseOutFn(instance)
//
// Create an onMouseOut event function that refers to a specific
// Overlay instance.
//
// In IE, subelements of a layer trigger a onMouseOut event for the layer
// as they cross into the subelement, therefore we have to wait to catch
// a possible onMouseOver event that should bubble up to the layer. Only
// when the mouse truely moves out the layer then disappear.
//
function OverlayMouseOutFn(obj)
{
	return new Function ('e',
 'statusline(\'Out('+obj.id+')\');'
+'if ('+obj.instanceName+'.isMouseOverTrigger) return true;'
+obj.instanceName+'.isMouseOverOverlay = false;'
+obj.instanceName+'.closeTimer = setTimeout("OverlayOff(\''+obj.id+'\')",Overlay.CloseTimerMilliSeconds);'
+'return true;'
	);
}

//
// Overlay.isOn(id)
//
function OverlayIsOn(id)
{
	if (document.getElementById) {
		return document.getElementById(id).style.visibility == "visible";
	} else if (document.layers) {
		return document.layers[id].visibility == "show";
	} else if (document.all) {
		return document.all[id].style.visibility == "visible";
	}

	return false;
}

//
// Overlay.on(id, x, y)
//
function OverlayOn(id, x, y)
{
statusline('On('+id+') ');

	var dx = 0, dy = 0;

	if (document.getElementById) {
		var el = document.getElementById(id);
		el.style.left = x + 'px';
		el.style.top = y + 'px';
		el.style.visibility = "visible";
	} else if (document.layers) {
		document.layers[id].left = x;
		document.layers[id].top = y;
		document.layers[id].visibility = "show";
	} else if (document.all) {
		var el = document.all[id];		
		el.style.pixelLeft = document.body.scrollLeft + x;
		el.style.pixelTop = document.body.scrollTop + y;
		el.style.visibility = "visible";
	}

	return true;
}

//
// Overlay.off(id)
//
function OverlayOff(id)
{
statusline('Off('+id+') ');

	if (document.getElementById) {
		document.getElementById(id).style.visibility = "hidden";
	} else if (document.layers) {
		document.layers[id].visibility = "hide";
	} else if (document.all) {
		document.all[id].style.visibility = "hidden";
	}

	return true;
}

function statusline(string)
{
//	status += string;
//
//	if (70 < status.length)
//		status = status.substring(status.length - 70, status.length);
}

function OverlayX(el) {
	if (document.layers)
		return el.x;
	for (x = 0; el != null; el = el.offsetParent) {
		x += el.offsetLeft;
	}
	return x;
}

function OverlayY(el) {
	if (document.layers)
		return el.y;
	for (y = 0; el != null; el = el.offsetParent) {
		y += el.offsetTop;
	}
	return y;
}		
	
new Overlay();
Overlay.version = '1.2';
Overlay.author = 'achowe@snert.com';

// Class Properties
Overlay.CloseTimerMilliSeconds = 100;

// Class Methods
//Overlay.on = OverlayOn;
//Overlay.off = OverlayOff;
//Overlay.isOn = OverlayIsOn;
//Overlay.getElementById = OverlayGetElementById;

// Public Instance Methods
Overlay.prototype.open = OverlayOpen;
Overlay.prototype.close = OverlayClose;
Overlay.prototype.X = OverlayX;
Overlay.prototype.Y = OverlayY;
