// Copyright (C) 2007 Cognos Incorporated. All Rights Reserved.
// Cognos and the Cognos logo are trademarks of Cognos Incorporated.

/*-----------------------------------------------------------------------------------------------------

Class :			CMenu

Description :

-----------------------------------------------------------------------------------------------------*/

var g_ownerDocument = null;

function CMenu(id,style) {
	this.m_htmlContainer = document.body;
	this.m_bVisible = false;
	this.m_id = id;
	this.m_htmlDivElement = null;
	this.m_parent = null;
	this.m_menuItems = new Array();
	this.m_style = style;
	this.m_callback = null;
	this.m_observers = new CObserver(this);
}

function CMenu_setHTMLContainer(container) {
	this.m_htmlContainer = container;
	g_ownerDocument = document.all ? this.m_htmlContainer.document : this.m_htmlContainer.ownerDocument;
}

function CMenu_getHTMLContainer() {
	return this.m_htmlContainer;
}

function CMenu_setParent(parent) {
	this.m_parent = parent;
}

function CMenu_getParent() {
	return this.m_parent;
}

function CMenu_getId() {
	return this.m_id;
}

function CMenu_getHTMLDiv() {
	return this.m_htmlDivElement;
}

function CMenu_create() {

	newElement = document.all ? this.m_htmlContainer.document.createElement("div") : this.m_htmlContainer.ownerDocument.createElement("div");

	if(typeof this.getStyle() == "object")
		newElement.className = this.getStyle().getNormalState();

	//Only set display=block when needed, because it causes flickering in Mozilla
	newElement.style.display = "none";
	newElement.style.visibility = "hidden";
	newElement.style.position = "absolute";
	newElement.id = this.m_id;

	//append the new menu
	this.m_htmlContainer.appendChild(newElement);

	//create a reference to it
	this.m_htmlDivElement = newElement;
}

function CMenu_draw() {

	if(this.m_htmlContainer == null)
		return;

	if(this.m_htmlDivElement == null)
		this.create();

	var html='';

	if(this.m_menuItems.length == 0) {
		if(this.m_callback != null) {

			menu = this;
			setTimeout("if(typeof menu != 'undefined' && menu != null && typeof menu.executeCallback != 'undefined' && typeof menu.executeCallback != null)menu.executeCallback()", 1000);

			// build a html div with a wait cursor
			html='<table class="menuItem_normal" CELLPADDING="0" CELLSPACING="0">';

			html += '<tr>';

			html += '<td>';
			html += '<img width="16" height="16" src="../common/images/tv_loading.gif"/>';
			html += '</td>';

			html += '<td nowrap="nowrap" align="left">';
			if(typeof gUIFrameWorkMenuLoadingMessage != 'undefined') {
				html += gUIFrameWorkMenuLoadingMessage;
			} else {
				html += '...';
			}

			html += '</td>';

			html += '</tr>';

			html += '</table>';
		}

	} else {

		//add the items
		var i=0;
		var html='<table CELLPADDING="0" CELLSPACING="0">';
		for (i=0; i < this.m_menuItems.length; i++) {
			if(this.m_menuItems[i].isVisible()) {
				html += '<tr><td>';
				html += this.m_menuItems[i].draw();
				html += '</td></tr>';
			}
		}
		html += '</table>';
	}

	try
	{
		this.m_htmlDivElement.innerHTML = html;
		// attach the event handlers
		this.attachEvents();
	}
	catch (e)
	{
	}

	this.updateCoords();
	
	// update hidden iframe
	var iFrameId = "uiFrameworkHiddenIframe" + this.m_id;
	var isNS7 = ((!document.all) && (document.getElementById)) ? true : false;
	setTimeout('updateIframeCoords("' + iFrameId + '", "' + this.m_htmlDivElement.id + '", ' + isNS7 + ')',50);
}

function CMenu_updateCoords() {

	myParent = this.getParent();
	var mnu = this.m_htmlDivElement;
	if(mnu != null)
	{
	
		var myDocument = document.all ? this.m_htmlContainer.document : this.m_htmlContainer.ownerDocument;
	
		//Backup the visibilty and display properties of this menu
		var originalVisibility  = mnu.style.visibility;
		var originalDisplay = 	mnu.style.display;
		
		mnu.style.visibility = "hidden";
		mnu.style.display = "block";
		//This line is used to make sure the width of the DIV element is correct in Mozilla
		if(mnu.firstChild != null)
			mnu.style.width = mnu.firstChild.offsetWidth;
			
		var x=0, y=0;
		var db = mnu.parentNode; //db = Document body
		// calculate the page width
		var pageWidth = db.clientWidth;
		var pageHeight = db.clientHeight;
		var scrollLeft = db.scrollLeft;
		var scrollTop = db.scrollTop;

		if(myParent == null)
		{
			//If this is the main context menu...
			x = mnu.style.left;
			y = mnu.style.top;
			
			//Remove 'px' on x and y coordinates if it exists
			if (x.substr(x.length - 2, 2) == 'px')
			{
				x = parseInt(x.substring(0, x.length-2));
				y = parseInt(y.substring(0, y.length-2));
			}

			//Change the y coordinate if the menu goes below the visible page
			if (y + mnu.offsetHeight >= (pageHeight))
			{
				if (y - mnu.offsetHeight > 0)
					y = y + scrollTop - mnu.offsetHeight;
				else
					y = Math.max(pageHeight - mnu.offsetHeight, 0);
			}
			else
				y = y + scrollTop;

			//Change the x coordinate if the menu goes below the visible page
			if (x + mnu.offsetWidth >= (pageWidth))
			{
				if (x - mnu.offsetWidth > 0)
					x = x + scrollLeft - mnu.offsetWidth;
				else
					x = Math.max(pageWidth - mnu.offsetWidth, 0);
			}
			else
				x = x + scrollLeft;			
		}
		else
		{
			//This is one of the menu items...
			if(!(myParent instanceof CToolbarButton) && !(myParent instanceof CMenuItem)) {
				return;
			}

			// make sure the parent has implemented the method "getMenuType"
			if(typeof myParent.getMenuType != 'function') {
				return;
			}
			myParentHTMLElement = myDocument.getElementById(this.getParent().getId());
			myParentDropdownButton = myDocument.getElementById('menu' + this.getParent().getId());
			if(myParentHTMLElement == null)
				return;

			var current = myParentHTMLElement;

			// handle drop down menus
			if(myParent.getMenuType() == 'dropDown') {

				x = 0; y = myParentHTMLElement.offsetHeight;

				while(current != null) {
					x += current.offsetLeft; y += current.offsetTop;
					current = current.offsetParent;
				}

				// if the right side of the drop down menu extends beyond browser window viewing area, adjust accordingly
				if((x + mnu.offsetWidth) > (pageWidth + scrollLeft)) {
					x = x + myParentHTMLElement.offsetWidth - mnu.offsetWidth;
					if(myParentDropdownButton != null)
						x = x + myParentDropdownButton.offsetWidth;
				}

				// if the bottom of the drop down menu extends below the browser viewing area and there is enough room to draw at the top, then draw to the top
				if(((y + mnu.offsetHeight) > (pageHeight + scrollTop)) && (y - (mnu.offsetHeight + myParentHTMLElement.clientHeight) >= 0)) {
					y -= (mnu.offsetHeight + myParentHTMLElement.clientHeight);
				}
			} else if(myParent.getMenuType() == 'cascaded') {

				x = myParentHTMLElement.offsetWidth;

				while(current != null) {
					x += current.offsetLeft; y += current.offsetTop;
					current = current.offsetParent;
				}

				// if the right side of the cascaded menu extends beyond the viewing area of the browser window right side, render to the left insted of the right
				if((x + mnu.offsetWidth) > (pageWidth + scrollLeft)) {
					x -= (myParentHTMLElement.offsetWidth + mnu.offsetWidth);
				}

				// if the bottom of the cascaded menu extends beyond the bottom of the browser viewing area, draw to the top
				if((y + mnu.offsetHeight) > (pageHeight + scrollTop)) {
					y -= (mnu.offsetHeight-myParentHTMLElement.clientHeight);
				}
			}
		}
		
		//Restore the visibilty and display properties of this menu
		mnu.style.visibility = originalVisibility;
		mnu.style.display = originalDisplay;
		
		this.setXCoord(x);
		this.setYCoord(y);
		this.setZIndex(500);
	}	
}

function CMenu_add(menuItem) {
	if(typeof menuItem.getObservers == "function" && typeof menuItem.getObservers() == "object") {
		menuItem.getObservers().attach(this, this.closeSubMenus, menuItem.onmouseover);
		menuItem.getObservers().attach(this, this.closeAllMenus, menuItem.onmouseup);
		menuItem.getObservers().attach(this, this.closeSubMenus, menuItem.onfocus);
		menuItem.getObservers().attach(this, this.closeAllMenus, menuItem.onkeypress);
	}
	this.m_menuItems[this.m_menuItems.length] = menuItem;
}

function CMenu_get(index) {
	if(index >= 0 && index < this.getNumItems()) {
		return this.m_menuItems[index];
	}
	return null;
}

function CMenu_getNumItems() {
	return this.m_menuItems.length;
}

function CMenu_hide() {
	this.hideHiddenIframe();
	if(this.m_htmlDivElement != null) {
		this.m_htmlDivElement.style.visibility = "hidden";
	}
	this.m_bVisible = false;

	// get the actual element that spawned the menu
	var theControl = this.getParent();

	if (theControl != null && typeof theControl.setFocus == "function")
		theControl.setFocus();
}

function CMenu_show() {
	if(this.m_htmlDivElement != null) {
		this.m_bVisible = true;

		// update the x and y coords
		this.updateCoords();

		var isNS7 = ((!document.all) && (document.getElementById)) ? true : false;

		var iFrameId = "uiFrameworkHiddenIframe" + this.m_id;
		var hiddenIframeElement = document.all ? this.m_htmlContainer.document.getElementById(iFrameId) : this.m_htmlContainer.ownerDocument.getElementById(iFrameId);
		if (hiddenIframeElement == null)
			hiddenIframeElement = this.createHiddenIFrame(iFrameId);

		if(hiddenIframeElement) {
			hiddenIframeElement.style.display = "block";
			updateIframeCoords(iFrameId, this.m_htmlDivElement.id, isNS7);
			setTimeout('updateIframeCoords("'+iFrameId+'", "'+this.m_htmlDivElement.id+'", '+isNS7+')',50);
		}

		//Show the context menu
		this.m_htmlDivElement.style.display = "block";
		this.m_htmlDivElement.style.visibility = "visible";

		if (!isNS7)
		{
			try
			{
				this.m_htmlDivElement.focus();
			}
			catch (e)
			{
			}
		}
	}
}

function CMenu_createHiddenIFrame(iFrameId)
{
	var container = this.getHTMLContainer();

	var iframeElem = document.all ? container.document.createElement("iframe") : container.ownerDocument.createElement("iframe");

	iframeElem.setAttribute("id",iFrameId);
	iframeElem.setAttribute("src",'../common/images/spacer.gif');
	iframeElem.setAttribute("scrolling",'no');
	iframeElem.setAttribute("frameborder",'0');
	iframeElem.style.position='absolute';
	iframeElem.style.minWidth='0px';
	iframeElem.style.minHeight='0px';
	iframeElem.style.left='0px';
	iframeElem.style.top='0px';
	iframeElem.style.zIndex=499;
	iframeElem.style.display='none';

	container.appendChild(iframeElem);

	return iframeElem;
}

function CMenu_isVisible() {
	return this.m_bVisible;
}

function CMenu_remove() {
	this.removeHiddenIframe();

	for(var i = 0; i < this.getNumItems(); ++i) {
		currentItem = this.get(i);
		if(typeof currentItem.getMenu == "function" &&  currentItem.getMenu() != null)
			currentItem.getMenu().remove();
	}

	if(this.m_htmlContainer != null && this.m_htmlDivElement != null) {
		this.m_htmlContainer.removeChild(this.m_htmlDivElement);
	}

	this.m_htmlDivElement = null;
	this.m_bVisible = false;
}

function CMenu_removeHiddenIframe()
{
	try
	{
		var hiddenIframeElement = g_ownerDocument.getElementById("uiFrameworkHiddenIframe" + this.m_id);
		if (hiddenIframeElement != null) {
			hiddenIframeElement.style.display = "none";
			if (hiddenIframeElement.parentNode && hiddenIframeElement.parentNode.removeChild) {
				hiddenIframeElement.parentNode.removeChild(hiddenIframeElement);
			}
		}
	}
	catch(e)
	{
	}
}

function CMenu_hideHiddenIframe() {
	try
	{
		var hiddenIframeElement = g_ownerDocument.getElementById("uiFrameworkHiddenIframe" + this.m_id);
		if(hiddenIframeElement) {
			hiddenIframeElement.style.display = "none";
		}
	}
	catch(e)
	{
	}
}

function CMenu_enable() {

}

function CMenu_disable() {

}

function CMenu_getState() {

}

function CMenu_clear() {
	if(this.m_htmlDivElement != null)
		this.m_htmlDivElement.innerHTML='';
	this.m_menuItems.splice(0, this.m_menuItems.length)
}

function CMenu_attachEvents() {
	for(var i = 0; i < this.m_menuItems.length; i++) {
		if(typeof this.m_menuItems[i].attachEvents == "function")
			this.m_menuItems[i].attachEvents();
	}
}

function CMenu_closeSubMenus(state) {
	// Called during a notification...
	// make sure we hide any submenus which have been opened.
	for(var i = 0; i < this.m_menuItems.length; i++) {
		menuItem = this.m_menuItems[i];
		subject = state.getSubject();
		if(menuItem != subject && typeof menuItem.getMenu == "function" && menuItem.getMenu() != null && menuItem.getMenu().isVisible()) {
			menuItem.getMenu().remove();
		}
	}
}

function CMenu_closeAllMenus(state) {
	// Called during a notification...
	current = this;
	var highestMenu = null;
	while(current) {
		if(current instanceof CMenu) {
			highestMenu = current;
		}
		current = current.getParent();
	}

	if(highestMenu != null)
		highestMenu.remove();
}


function CMenu_setStyle(style) {
	this.m_style = style;
}

function CMenu_getStyle() {
	return this.m_style;
}

function CMenu_setXCoord(x) {
	htmlDiv = this.getHTMLDiv();
	if(htmlDiv != null)
		htmlDiv.style.left = x;
}

function CMenu_setYCoord(y) {
	htmlDiv = this.getHTMLDiv();
	if(htmlDiv != null)
		htmlDiv.style.top = y;
}

function CMenu_setZIndex(zIndex) {
	htmlDiv = this.getHTMLDiv();
	if(htmlDiv != null)
		htmlDiv.style.zIndex = zIndex;
}

// set a callback routine to populate the menu
function CMenu_registerCallback(callback) {
	this.m_callback = callback;
}

function CMenu_executeCallback() {
	if(typeof this.m_callback != "function")
	{
		return;
	}
	this.m_callback();
}

function CMenu_getObservers() {
	return this.m_observers;
}

function CMenu_onmouseover(evt) {
	//get the event in a cross-browser fashion
	evt = (evt) ? evt : ((event) ? event : null);

	// notify our parent (if one exists) of this event
	if(this.getParent() != null && typeof this.getParent().onmouseover == 'function')
		this.getParent().onmouseover(evt);

	// notify observers of this event
	this.getObservers().notify(CMenu_onmouseover);
}

function CMenu_onmouseout(evt) {
	//get the event in a cross-browser fashion
	evt = (evt) ? evt : ((event) ? event : null);

	// notify our parent (if one exists) of this event
	if(this.getParent() != null && typeof this.getParent().onmouseout == 'function')
		this.getParent().onmouseout(evt);

	// notify observers of this event
	this.getObservers().notify(CMenu_onmouseout);
}

function CMenu_onmouseup(evt) {
	//get the event in a cross-browser fashion
	evt = (evt) ? evt : ((event) ? event : null);

	// notify our parent (if one exists) of this event
	if(this.getParent() != null && typeof this.getParent().onmouseup == 'function')
		this.getParent().onmouseup(evt);

	// notify observers of this event
	this.getObservers().notify(CMenu_onmouseup);
}

function CMenu_onkeypress(evt) {
	//get the event in a cross-browser fashion
	evt = (evt) ? evt : ((event) ? event : null);

	// notify our parent (if one exists) of this event
	if(this.getParent() != null && typeof this.getParent().onkeypress == 'function')
		this.getParent().onkeypress(evt);

	// notify observers of this event
	this.getObservers().notify(CMenu_onkeypress);
}

CMenu.prototype.draw = CMenu_draw;
CMenu.prototype.updateCoords = CMenu_updateCoords;
CMenu.prototype.add = CMenu_add;
CMenu.prototype.get = CMenu_get;
CMenu.prototype.getNumItems = CMenu_getNumItems;
CMenu.prototype.hide = CMenu_hide;
CMenu.prototype.hideHiddenIframe = CMenu_hideHiddenIframe;
CMenu.prototype.removeHiddenIframe = CMenu_removeHiddenIframe;
CMenu.prototype.show = CMenu_show;
CMenu.prototype.enable = CMenu_enable;
CMenu.prototype.disable = CMenu_disable;
CMenu.prototype.getState = CMenu_getState;
CMenu.prototype.clear = CMenu_clear;
CMenu.prototype.attachEvents = CMenu_attachEvents;
CMenu.prototype.setParent = CMenu_setParent;
CMenu.prototype.getParent = CMenu_getParent;
CMenu.prototype.getHTMLContainer = CMenu_getHTMLContainer;
CMenu.prototype.setHTMLContainer = CMenu_setHTMLContainer;
CMenu.prototype.getHTMLDiv = CMenu_getHTMLDiv;
CMenu.prototype.create = CMenu_create;
CMenu.prototype.remove = CMenu_remove;
CMenu.prototype.getId = CMenu_getId;
CMenu.prototype.isVisible = CMenu_isVisible;
CMenu.prototype.setStyle = CMenu_setStyle;
CMenu.prototype.getStyle = CMenu_getStyle;
CMenu.prototype.closeSubMenus = CMenu_closeSubMenus;
CMenu.prototype.closeAllMenus = CMenu_closeAllMenus
CMenu.prototype.setXCoord = CMenu_setXCoord;
CMenu.prototype.setYCoord = CMenu_setYCoord;
CMenu.prototype.setZIndex = CMenu_setZIndex;
CMenu.prototype.update = new Function("return true");
CMenu.prototype.registerCallback = CMenu_registerCallback;
CMenu.prototype.executeCallback = CMenu_executeCallback;
CMenu.prototype.getObservers = CMenu_getObservers;
CMenu.prototype.onmouseover = CMenu_onmouseover;
CMenu.prototype.onmouseout = CMenu_onmouseout;
CMenu.prototype.onmouseup = CMenu_onmouseup;
CMenu.prototype.onkeypress = CMenu_onkeypress;
CMenu.prototype.createHiddenIFrame = CMenu_createHiddenIFrame;


function updateIframeCoords(id, containerId, isNS7)
{
	if (g_ownerDocument == null)
		return;
	var container = g_ownerDocument.getElementById(containerId);
	var hiddenIframeElement = g_ownerDocument.getElementById(id);
	if (hiddenIframeElement && container) {
		if(isNS7 == true) {
			hiddenIframeElement.style.left = container.offsetLeft;
			hiddenIframeElement.style.top = container.offsetTop;
			hiddenIframeElement.style.width = container.offsetWidth;
			hiddenIframeElement.style.height = container.offsetHeight;
		} else {
			hiddenIframeElement.style.pixelLeft = container.offsetLeft;
			hiddenIframeElement.style.pixelTop = container.offsetTop;
			hiddenIframeElement.style.pixelWidth = container.offsetWidth;
			hiddenIframeElement.style.pixelHeight = container.offsetHeight;
		}
	}
}

