/*
	class CMenu

	requires class CSS (css.js)
*/

function CMenu(strId) {
	this.strId = null;
	this.objChildren = null;

	this.construct = CMenu_construct;
	this.getId = CMenu_getId;
	this.appendItem = CMenu_appendItem;
	this.show = CMenu_show;
	this.hide = CMenu_hide;
	this.startTimeout = CMenu_startTimeout;
	this.resetTimeout = CMenu_resetTimeout;
	this.hideChildrenExcept = CMenu_hideChildrenExcept;
	this.getParent = CMenu_getParent;

	this.construct(strId);
}

function CMenu_construct(strId) {
	this.strId = strId;
	this.objChildren = new Object();
}

function CMenu_getId() {
	return this.strId;
}

function CMenu_getParent() {
	return null;
}

function CMenu_appendItem(objMenu) {
	this.objChildren[objMenu.getId()] = objMenu;
	objMenu.setParent(this);
}

function CMenu_show() {
}

function CMenu_hide() {
}

function CMenu_startTimeout() {
}

function CMenu_resetTimeout() {
}

function CMenu_hideChildrenExcept(objMenu) {
	var strChildId;
	var objChildMenu;
	for (strChildId in this.objChildren) {
		objChildMenu = this.objChildren[strChildId];
		if (objChildMenu && (objChildMenu != objMenu)) objChildMenu.hide();
	}
}


/*
	class CPopupMenu

	requires class CSS (css.js)
*/

CPopupMenu.iTimeout = 500;
CPopupMenu.onShowListener = function(objMenu) {}
CPopupMenu.onHideListener = function(objMenu) {}


CPopupMenu.setTimeout = function(iTimeout) {
	CPopupMenu.iTimeout = iTimeout;
}

CPopupMenu.getTimeout = function() {
	return CPopupMenu.iTimeout;
}

function CPopupMenu(objParent, strIdItem, strIdMenu, bPosBelow, iTimeout, iOffsetX, iOffsetY) {
	// init properties
	this.strId = strIdItem;
	this.strIdMenu = strIdMenu;
	this.bPosBelow = bPosBelow;
	this.objParent = objParent;
	this.objChildren = new Object();
	this.objView = null;
	this.objViewContent = null;
	this.iOffsetX = iOffsetX;
	this.iOffsetY = iOffsetY;
	this.iTimerId = null;
	this.iTimeout = parseInt("" + iTimeout);
	this.bHasFocus = false;

	// init functions
	this.construct = CPopupMenu_construct;
	this.getId = CPopupMenu_getId;
	this.setParent = CPopupMenu_setParent;
	this.getParent = CPopupMenu_getParent;
	this.getLeft = CPopupMenu_getLeft;
	this.getTop = CPopupMenu_getTop;
	this.getWidth = CPopupMenu_getWidth;
	this.getHeight = CPopupMenu_getHeight;
	this.setVisible = CPopupMenu_setVisible;
	this.getVisible = CPopupMenu_getVisible;
	this.getTimeout = CPopupMenu_getTimeout;
	this.onMouseOver = CPopupMenu_onMouseOver;
	this.onMouseOut = CPopupMenu_onMouseOut;
	this.moveTo = CPopupMenu_moveTo;
	this.doHighlight = null;
	this.show = CPopupMenu_show;
	this.hide = CPopupMenu_hide;
	this.hideChildrenExcept = CPopupMenu_hideChildrenExcept;
	this.onTimeout = CPopupMenu_onTimeout;
	this.startTimeout = CPopupMenu_startTimeout;
	this.resetTimeout = CPopupMenu_resetTimeout;

	this.appendItem = CPopupMenu_appendItem;

	// init object
	this.construct(objParent, strIdItem, strIdMenu, bPosBelow, iTimeout, iOffsetX, iOffsetY);
}

function CPopupMenu_construct(objParent, strIdItem, strIdMenu, bPosBelow, iTimeout, iOffsetX, iOffsetY) {
	if (!strIdItem) return;
	this.strId = strIdItem;
	this.strIdMenu = strIdMenu;
	this.bPosBelow = bPosBelow;
	this.objParent = objParent;
	this.objChildren = new Object();
	this.objView = null;
	this.objViewContent = null;
	this.iOffsetX = iOffsetX;
	this.iOffsetY = iOffsetY;
	this.iTimerId = null;
	this.iTimeout = parseInt("" + iTimeout);
	this.bHasFocus = false;
	this.objView = CSS.getElementById(this.strId);
	this.objViewContent = CSS.getElementById(this.strIdMenu);

	var objDest = this;
	var objFuncOver = function() {
		objDest.onMouseOver();
	}

	var objFuncOut = function() {
		objDest.onMouseOut();
	}
	CSS.addEventListener(this.objView, "mouseover", null, objFuncOver);
	CSS.addEventListener(this.objViewContent, "mouseover", null, objFuncOver);
	CSS.addEventListener(this.objView, "mouseout", null, objFuncOut);
	CSS.addEventListener(this.objViewContent, "mouseout", null, objFuncOut);

	CSS.setPositioningAbsolute(this.objViewContent, true);
	CSS.setVisible(this.objViewContent, false);
	if (this.objParent) this.objParent.appendItem(this);
}

function CPopupMenu_getId() {
	return this.strId;
}

function CPopupMenu_setParent(objParent) {
	if (this.objParent == objParent) return;
	this.objParent = objParent;
	objParent.appendItem(this);
}

function CPopupMenu_getParent() {
	return this.objParent;
}

function CPopupMenu_getLeft() {
	return CSS.getOffsetAbsoluteLeft(this.objViewContent);
}

function CPopupMenu_getTop() {
	return CSS.getOffsetAbsoluteTop(this.objViewContent);
}

function CPopupMenu_getWidth() {
	return CSS.getWidth(this.objViewContent);
}

function CPopupMenu_getHeight() {
	return CSS.getHeight(this.objViewContent);
}

function CPopupMenu_setVisible(bVisible) {
	if (this.getVisible() != bVisible) {
		if (bVisible) {
			if (CSS.getVisible(this.objViewContent)) return;
			if (this.bPosBelow) {
				this.moveTo(CSS.getOffsetAbsoluteLeft(this.objView) + this.iOffsetX, CSS.getOffsetAbsoluteTop(this.objView)+ CSS.getHeight(this.objView) + this.iOffsetY);
			} else {
				this.moveTo(CSS.getOffsetAbsoluteLeft(this.objView) + CSS.getWidth(this.objView) + this.iOffsetX, CSS.getOffsetAbsoluteTop(this.objView) + this.iOffsetY);
			}
			CPopupMenu.onShowListener(this);
		} else {
			CPopupMenu.onHideListener(this);
		}
		CSS.setVisible(this.objViewContent, bVisible);
	}
}

function CPopupMenu_getVisible() {
	return CSS.getVisible(this.objViewContent);
}

function CPopupMenu_moveTo(x, y) {
	CSS.moveTo(this.objViewContent, x, y);
}

function CPopupMenu_onMouseOver() {
	this.bHasFocus = true;
	this.resetTimeout();
	this.show();
	return true;
}

function CPopupMenu_onMouseOut() {
	this.bHasFocus = false;
	this.startTimeout();
	return true;
}

function CPopupMenu_onTimeout() {
	this.resetTimeout();
	this.hide();
	return true;
}

function CPopupMenu_resetTimeout() {
	if (this.iTimerId) window.clearTimeout(this.iTimerId);
	this.iTimerId = null;
}

function CPopupMenu_startTimeout() {
	if (1 >= this.iTimeout) return this.hide();
	this.resetTimeout();
	var objDest = this;
	var objFunc = function() {
		objDest.onTimeout();
	}

	if (!this.bHasFocus) this.iTimerId = window.setTimeout(objFunc, this.getTimeout());
}

function CPopupMenu_getTimeout() {
	return this.iTimeout;
}

function CPopupMenu_show() {
	if (this.getVisible()) return;
	this.setVisible(true);
	//if we've got a parent, show parent-menu!
	if (this.objParent) {
		this.objParent.resetTimeout(); // abandon pending "hide" commands
		this.objParent.hideChildrenExcept(this); // hide all siblings of this menu
		this.objParent.show(true);
	}
}

function CPopupMenu_hide() {
	if (!this.getVisible()) return;

	var bMayHide = true;
	bMayHide = (bMayHide && (!this.bHasFocus)); // don't hide, if we've got the focus

	// don't hide, if any child has the focus
	if (bMayHide) {
		var strChildId;
		var objChildMenu;
		for (strChildId in this.objChildren) {
			objChildMenu = this.objChildren[strChildId];
			if (objChildMenu) bMayHide = (bMayHide && (!objChildMenu.bHasFocus));
		}
	}
	if (bMayHide) {
		this.setVisible(false); // hide me
		this.hideChildrenExcept(null); // hide all children
		if (this.objParent) this.objParent.startTimeout(); // hide parent (if it doesn't have the focus)
	}
}

function CPopupMenu_hideChildrenExcept(objMenu) {
	var strChildId;
	var objChildMenu;
	for (strChildId in this.objChildren) {
		objChildMenu = this.objChildren[strChildId];
		if (objChildMenu && (objChildMenu != objMenu)) objChildMenu.hide();
	}
}

function CPopupMenu_appendItem(menuitem) {
	this.objChildren[menuitem.getId()] = menuitem;
	menuitem.setParent(this);
}
