/////////////////////////////////////////////////////////////////////////////////////////////////////
// Developer	: Chris Hack
// Date			: 2006/11/12
// Description	: This module provides a code base for reusable utility classes and functions.
// Dependencies : screen.js
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Class for defining a rectangle wich can be used to define an element's bounding box
// Common functions are part of this class which make comparison of cooridinates with the
// bounding rectangle easier.
/////////////////////////////////////////////////////////////////////////////////////////////////////
function Rect(top, left, width, height) {
	this.top = top? top : 0;
	this.left = left? left : 0;
	this.width = width? width : 0;
	this.height = height? height : 0;
	
	this.contains = function(x, y) {
		return this.intersectsX(x) && this.intersectsY(y);
	}
	
	this.intersectsX = function(x) {
		return (x >= this.left) && (x <= (this.left + this.width));
	}
	
	this.intersectsY = function(y) {
		return (y >= this.top) && (y <= (this.top + this.height));
	}
	
	this.toString = function() {
		return "top: " + this.top + " left: " + this.left + " width: " + this.width + " height: " + this.height;
	}
}// Rect
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Gets the elements bounding rectangle
/////////////////////////////////////////////////////////////////////////////////////////////////////
function getElementRect(element) {
	var rect = new Rect();
	rect.top = getElementY(element);
	rect.left = getElementX(element);
	rect.width = getElementWidth(element);
	rect.height = getElementHeight(element);
	
	return rect;
}// getElementRect
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Wrapper class around an element that provides menu style behavior
// Parameters:	element - the DOM element that is going to be the menu
//				owner	- the DOM element that this menu is bound to, can be null
//						  example: owner could be a toolbar button or another menu if this menu is
//								   a submenu.
/////////////////////////////////////////////////////////////////////////////////////////////////////
function Menu(element, owner) {
	this.owner = owner;
	this.element = element;
	this.captureMouse = false;
	this.onhide = null;
	
	this.show = function() {
		this.element.style.visibility = "visible";
		this.captureMouse = true;
	}
	
	this.hide = function() {		
		this.element.style.visibility = "hidden";
		this.captureMouse = false;
		if (this.onhide != null) this.onhide();
	}
	
	this.visible = function() {
		return (this.element.style.visibility == "visible");
	}	
	
	// The mouseEvent interface must be exported for the mouse listeners integration
	this.OnMouseMove = function() {
		
		if (this.captureMouse) {
		
			var ownerRect = getElementRect(this.owner);
			var rect = getElementRect(this.element);
			
			// If the mouse is not with the bounding rectangle of this menu or it's owner
			// then hide this menu.
			if (!(rect.contains(g_mouse.x, g_mouse.y) || ownerRect.contains(g_mouse.relativeX, g_mouse.relativeY))) 
				this.hide();
		}
		return true;
	}
	
	// Register this object as a mouse listener
	registerMouseMoveListener(this);
	
}// Menu
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Wrapper class around an element that provides popup style behavior
// Parameters:	element		- the DOM element that is going to be the popup window
//				owner		- the DOM element that this popup is bound to
//							  example: owner could be a button or any other element that when clicked 
//									   or moused over, causes the popup to display
//				bindingRect	- Use this parameter to specify a binding rectangle such that if the 
//							  mouse is anywhere in this rectangle, the popup remains visible
//							  omit or pass null to use the default binding rectangle of the owner
//							  element
/////////////////////////////////////////////////////////////////////////////////////////////////////
function Popup(element, owner, bindingRect) {
	this.owner = owner;
	this.element = element;
	this.bindingRect = bindingRect;
	
	// Default binding rect?
	if (!bindingRect) bindingRect = getElementRect(owner);
	
	// Determines if the popup window is currently visible
	this.visible = function() {
		return (this.element.style.visibility == "visible");
	}

	this.mouseEvent = function() {
		if (this.visible()) {
			
			// If the mouse is not with the bounding rectangle then hide this popup.
			if (!(bindingRect.contains(g_mouse.x, g_mouse.y))) {
				element.style.visibility = "hidden";			
			}
		}
	}// mouseEvent
	
	// Bind the popup to the element to the owner element
	owner.onmouseover = function() {
		element.style.visibility = "visible";		
	}
	
	element.onclick = function() {
		element.style.visibility = "hidden";
	}
	
	// Register this object as a mouse listener
	g_mouseListeners.push(this);
}// Popup
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Generic method for getting the inner text value of an HTML element.  Since firefox and IE support
// different parameters for this value, this function hides that difference.
// Parameters:	element		- the DOM element from which to obtain the inner text value				
/////////////////////////////////////////////////////////////////////////////////////////////////////
function getInnerText(element) {
	// IE supports innerText property
	if (document.all) return element.innerText;
	// Firefox supports textContent property
	else return element.textContent;
}// getInnerText
////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Generic method for setting the inner text value of an HTML element.  Since firefox and IE support
// different parameters for this value, this function hides that difference.
// Parameters:	element		- the DOM element of which to set the inner text value	
//              value		- the text value			
/////////////////////////////////////////////////////////////////////////////////////////////////////
function setInnerText(element, value) {
	// IE supports innerText property
	if (document.all) element.innerText = value;
	// Firefox supports textContent property
	else element.textContent = value;
}// getInnerText
////////////////////////////////////////////////////////////////////////////////////////////////////
