/*
** Copyright (c) Oracle Corporation 2004. All Rights Reserved.
**
*/

// Global variable for storing browser name
var _bi_popup_is_nav5up, _bi_popup_is_ie5up, _bi_popup_is_W3C;

// popup div ids, used for controlling visibility ( hardcoded max depth = 20 )
var _bi_popup_ID = new Array("","","","","","","","","","","","","","","","","","","","");
// popup cell 
var _bi_popup_cell_ID = new Array("","","","","","","","","","","","","","","","","","","","");
var _bi_popup_left = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
var _bi_popup_top = new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
var _bi_popup_prefix;

// Store the browser name
function detectBrowser() {
	// Get Browser Name
	_bi_popup_is_W3C = (document.documentElement) ? true : false;
	var browser = navigator.appName;	
	// Set some variables useful for determining browser type and version
	var agt=navigator.userAgent.toLowerCase(); 
	var osName   = navigator.appVersion.toLowerCase();
	var is_major = parseInt(navigator.appVersion);
	// Is Navigator?
 	var _bi_popup_is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1) 
                && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1) 
                && (agt.indexOf('webtv')==-1)); 
	// Is Navigator 5 (or above)?
	_bi_popup_is_nav5up = (_bi_popup_is_nav && (is_major >= 5));
	// Is Internet Explorer?
	var _bi_popup_is_ie   = (agt.indexOf("msie") != -1);
	// Is IE 3 
	var _bi_popup_is_ie3  = (_bi_popup_is_ie && (is_major < 4)); 
	// Is IE 4
	var _bi_popup_is_ie4  = (_bi_popup_is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")==-1) && (agt.indexOf("msie 5.5")==-1) && (agt.indexOf("msie 6.")==-1));
  	// Is Internet Explorer 5 or above?
	_bi_popup_is_ie5up  = (_bi_popup_is_ie && !_bi_popup_is_ie3 && !_bi_popup_is_ie4); 
}
detectBrowser();

// Return a DOM object from it's ID
function getDOMObj(id)
{
	var element;
	if (_bi_popup_is_W3C)
		element = document.getElementById(id);
	else if (_bi_popup_is_ie5up)
		element = document.all(id);
	return element;
}

function _bi_popup_attachEvent(obj,name,funcRef)
{
	if ( _bi_popup_is_ie5up ) { 
    obj.attachEvent("on" + name,funcRef);
  } else {
    obj.addEventListener(name,funcRef,false);      
  }        
}

function _bi_popup_detachEvent(obj,name,funcRef)
{
 	if ( _bi_popup_is_ie5up )
    obj.detachEvent("on" + name,funcRef);
  else
    obj.removeEventListener(name,funcRef, false);
}

function _bi_popup_handleMouseDown(event) {
	var objID;
	if ( _bi_popup_is_ie5up )
		objID = window.event.srcElement.id;
	else if (_bi_popup_is_nav5up)
		objID = event.target.id;

	if (objID.substring(0,_bi_popup_prefix.length) != _bi_popup_prefix)
  {
    if ( _bi_popup_is_ie5up )
    { // in IE, make sure that the scrollbar can be moved without the drill menu being dismissed. 
      // so only hide the menu if the mouse is inside the client window
      if( (window.event.clientX<document.body.clientWidth)&&(window.event.clientY<document.body.clientHeight) )
        _bi_popup_hideMenu(0);
    } else
     _bi_popup_hideMenu(0);	
  }
  return true;
}

function _bi_popup_showTopMenu(event,prefix,metadata,formName,isPPR,isSmallStyle) {
	_bi_popup_hideMenu(0);
  _bi_popup_prefix = prefix;
	var menu = _bi_popup_createPopupMenu(prefix, metadata, formName, isPPR,isSmallStyle);
	var mouseX;
	var mouseY;  
  var scrollLeft;
  var scrollTop;
  var clientWidth;
  var clientHeight;
  if ( _bi_popup_is_ie5up )
  {
    scrollLeft = (document.documentElement.scrollLeft > 0) ? document.documentElement.scrollLeft : document.body.scrollLeft;
    scrollTop = (document.documentElement.scrollTop > 0) ? document.documentElement.scrollTop : document.body.scrollTop;
    clientWidth = document.body.clientWidth;
    clientHeight = document.body.clientHeight;
  } else
  { 
    scrollTop = window.scrollY;
    scrollLeft = window.scrollX;
    clientWidth = window.innerWidth - 20;
    clientHeight = window.innerHeight - 20;
  }

  if(_bi_popup_is_ie5up )
  {
    //Fix for bug 3634574. Handle BIDI popup menus for IE 5.5 and up
    if(document.dir == "rtl") 
    {
      mouseX = window.event.clientX + scrollLeft;
      
      //When dir == "rtl", (0,0) is the top left corner of the browser window, 
      //when the browser window is fully scrolled to the right (or there is no 
      //horizontal scrollbar for the page). 
      //Therefore adjust mouseX accordingly
      mouseX -= (document.body.scrollWidth - clientWidth);
      //If the scrollbar is present, we should subtract the 16 pixels from
      //mouseX. But there is no way to figure if scrollbar is present or
      //not. Therefore subtract 8 pixels
      mouseX -= 8;
    }
    else
      mouseX = window.event.clientX + scrollLeft;
      
    mouseY = window.event.clientY + scrollTop;
  } else {
    mouseX = event.clientX + scrollLeft;
    mouseY = event.clientY + scrollTop;
  }
  
  //Fix for bug 3634574. Handle BIDI popup menus for IE 5.5 and up
  if(document.dir == "rtl") 
  {
    //The popup menu should be on left side of the point where we click
    mouseX = mouseX - menu.offsetWidth;
    //left most point in the visible window
    var leftMostPoint = scrollLeft - (document.body.scrollWidth - clientWidth)
    //If the menu is going beyond left of the window, then put it on the right
    if(mouseX < leftMostPoint)
    {
      mouseX = mouseX + menu.offsetWidth; 
      //If the menu is going beyond right of the window, then put it in such
      //a way that right most point of menu is at the right most point of the
      //window
      if(mouseX + menu.offsetWidth > clientWidth)
        mouseX = clientWidth - menu.offsetWidth;
    }
  }
  else
  {
    if ( mouseX + menu.offsetWidth > clientWidth + scrollLeft )
    {
      mouseX = mouseX - menu.offsetWidth;
      if(mouseX < 0) 
        mouseX = 0;
    }
  }
  if ( mouseY + menu.offsetHeight > clientHeight + scrollTop)
  {
    mouseY = mouseY - menu.offsetHeight;   
    if(mouseY < 0)    
      mouseY = scrollTop + 50;
  }
  
	_bi_popup_show(menu,0,mouseX, mouseY);
  _bi_popup_attachEvent(document,"mousedown",_bi_popup_handleMouseDown);      
  _bi_popup_ID[0] = menu.id;
	return false;
}

// Handle mouseover an "item" drill menu entry
function _bi_popup_mouseOverItemDrillMenuEntry(evt)
{
  if(evt==null)
    evt = event;
  var drillMenuEntry;
	if ( _bi_popup_is_ie5up )
    drillMenuEntry = evt.srcElement;
	else if (_bi_popup_is_nav5up)
    drillMenuEntry = this;
  
  drillMenuEntry = _bi_popup_getParentCell(drillMenuEntry);
    
  // only handle this event for menus
  if(drillMenuEntry._bi_menu==( void 0 ))
    return;

  _bi_popup_internalHighlight(drillMenuEntry);	

	// Geometry of cascaded menu
	var cascadedMenuID = drillMenuEntry.id + "D";
  index = getDOMObj(drillMenuEntry.id+"D")._bi_depth;
 
	if(_bi_popup_ID[index]!=cascadedMenuID)
	{	
  	var cmTop = _bi_popup_top[index-1];
    var tableBody = drillMenuEntry.parentNode.parentNode;
    var rows = tableBody.childNodes;
    var i = 0;
    var rowObj;
    for(;i<rows.length;i++)
    {
      rowObj = rows[i];
      if(rowObj.childNodes[0].id==drillMenuEntry.id)
        break;
      cmTop = cmTop + rowObj.offsetHeight;
    }
    if(i>0)
      cmTop = cmTop + 1;
    
    var cmLeft = _bi_popup_left[index-1] + drillMenuEntry.offsetWidth + 1;// 1 for the div border  
    
    var scrollLeft;
    var scrollTop;
    var clientWidth;
    var clientHeight;
    if ( _bi_popup_is_ie5up )
    {
      scrollLeft = (document.documentElement.scrollLeft > 0) ? document.documentElement.scrollLeft : document.body.scrollLeft;
      scrollTop = (document.documentElement.scrollTop > 0) ? document.documentElement.scrollTop : document.body.scrollTop;
      clientWidth = document.body.clientWidth;
      clientHeight = document.body.clientHeight;
    }
    else if(_bi_popup_is_nav5up)
    { 
      scrollTop = window.scrollY;
      scrollLeft = window.scrollX;
      clientWidth = window.innerWidth - 20;
      clientHeight = window.innerHeight - 20;
    }

    var cascadedMenu = getDOMObj(cascadedMenuID);
    
    //Fix for bug 3634574. Handle BIDI popup menus for IE 5.5 and up
    if(document.dir == "rtl") 
    {
      //The popup menu should be on left side of the point where we click
      cmLeft = _bi_popup_left[index-1] - cascadedMenu.offsetWidth;
      
      //left most point in the visible window
      var leftMostPoint = scrollLeft - (document.body.scrollWidth - clientWidth)
      //If the menu is going beyond left of the window, then put it on the right
      if(cmLeft < leftMostPoint)
      {
        cmLeft = _bi_popup_left[index-1] + drillMenuEntry.offsetWidth; 
        //If the menu is going beyond right of the window, then put it in such
        //a way that right most point of menu is at the right most point of the
        //window
        if(cmLeft + cascadedMenu.offsetWidth > clientWidth)
          cmLeft = clientWidth - cascadedMenu.offsetWidth;
      }
    }
    else if ( cmLeft + cascadedMenu.offsetWidth > clientWidth + scrollLeft )
    {
      cmLeft = _bi_popup_left[index-1] - cascadedMenu.offsetWidth + 1;
      if(cmLeft < 0) 
        cmLeft = 0;
    }
    if ( cmTop + cascadedMenu.offsetHeight > clientHeight + scrollTop)
    {
      cmTop = cmTop - cascadedMenu.offsetHeight + rowObj.offsetHeight + 1;
      if(cmTop < 0)    
        cmTop = scrollTop + 50;
    }

		_bi_popup_hideMenu(index);
		_bi_popup_ID[index] = cascadedMenuID;
    _bi_popup_cell_ID[index] = drillMenuEntry.id;
		_bi_popup_show(cascadedMenu,index,cmLeft,cmTop);
	}
}

function _bi_popup_hideMenu(index) {
  if(index==0)
  {
    var objID = _bi_popup_ID[0];
    if(objID != "") {	
      var obj = getDOMObj(objID);
      if(_bi_popup_is_ie5up)
      {
        if(obj._iframe != (void (0)))
          obj._iframe.style.display="none";
      }
      _bi_popup_detachEvent(document,"mousedown",_bi_popup_handleMouseDown);
      document.body.removeChild(getDOMObj(objID));
    }	
  }

	for(;index<_bi_popup_ID.length;index++){
		if ( _bi_popup_ID[index] != "" ) {		
			_bi_popup_hide(_bi_popup_ID[index]);
			_bi_popup_ID[index] = "";	
		}
	}
}

function _bi_popup_hide(objID) {
	if(objID != "") {	
		var obj = getDOMObj(objID);
    if(obj != (void 0) )
    {
      obj.style.visibility = "hidden";
      if(_bi_popup_is_ie5up)
      {
        if(obj._iframe != (void (0)))
          obj._iframe.style.display="none";
      }
    }
	}	
}

// Show the specified drill menu fragment
function _bi_popup_show(obj,index,left,top)
{
	obj.style.visibility = 'visible';
  _bi_popup_left[index] = left;
	obj.style.left = left;	  
  _bi_popup_top[index] = top;
	obj.style.top = top;

	if(_bi_popup_is_ie5up)
	{    
    var _iframe;
	  if(obj._iframe==(void (0)))
	  {
      // IFrames were added to solve problem of windowed objects showing through the menu
      // The iframes will not be rendered by the gridview in IE 5.0, since iframes were windowed objects in 5.0
      if(index==0)
        _iframe = getDOMObj("_bi_popup_iframe0");
      else if(index==1)
        _iframe = getDOMObj("_bi_popup_iframe1");
      else if(index==2)
        _iframe = getDOMObj("_bi_popup_iframe2");
      else
        _iframe = (void (0));
      // move the iframe from the crosstab to the body, so that the positioning of 
      // the divs and iframes can remain in synch
      if( (_iframe!=(void (0))) && (_iframe.parentNode != document.body))
    	{
        _iframe.parentNode.removeChild(_iframe);
        document.body.appendChild(_iframe);
      }
      obj._iframe = _iframe;
	  } else
      _iframe = obj._iframe;
    if(_iframe != (void (0)))
    {
  	  _iframe.style.top = top;
	    _iframe.style.left = left;
	    _iframe.style.display = "block";
	    _iframe.style.position = "absolute";
	    _iframe.style.width = obj.offsetWidth;
	    _iframe.style.height = obj.offsetHeight;
	    _iframe.style.zIndex = obj.style.zIndex - 1;	
    }
  }  
}

// Highlight the specified drill menu entry
function _bi_popup_internalHighlight(obj)
{
  if(obj.isSmall)
    obj.className="OraBIPopupCellHighlight_small";
  else
    obj.className="OraBIPopupCellHighlight";  
}

// Highlight the specified drill menu entry
function _bi_popup_highlight(evt)
{
  var obj;
	if ( _bi_popup_is_ie5up )
    obj = evt.srcElement;
	else if (_bi_popup_is_nav5up)
    obj = this;

  obj = _bi_popup_getParentCell(obj);

  _bi_popup_internalHighlight(obj);

  var depth = obj._bi_depth;
	for(var index=1;index<depth;index++){
		if ( _bi_popup_cell_ID[index] != "" ) {		
      obj = getDOMObj(_bi_popup_cell_ID[index]);
      _bi_popup_internalHighlight(obj);
		}
	}  

	_bi_popup_hideMenu(depth);

}

function _bi_popup_getParentCell(obj)
{
  // NOTE : Write a real loop here for N-level menu
  if(obj.tagName!="TD")
    obj = obj.parentNode;
  if(obj.tagName!="TD")
    obj = obj.parentNode;
  return obj;
}

// lowlight the specified drill menu entry
function _bi_popup_lowlight(evt)
{	
  if(evt==null)
    evt = event;
  var obj;
	if ( _bi_popup_is_ie5up )
    obj = evt.srcElement;
	else if (_bi_popup_is_nav5up)
    obj = this;

  obj = _bi_popup_getParentCell(obj);

  if(obj.isSmall)
    obj.className="OraBIPopupCellLowlight_small";
  else
    obj.className="OraBIPopupCellLowlight";  
  
	for(var index=1;index<_bi_popup_ID.length;index++){
		if ( _bi_popup_ID[index] != "" ) {		
      obj = getDOMObj(_bi_popup_cell_ID[index]);
      if(obj.isSmall)
        obj.className="OraBIPopupCellLowlight_small";
      else
        obj.className="OraBIPopupCellLowlight";  
		}
	}    
}

function _bi_popup_isLeftMouseButton(e) {

	if ( _bi_popup_is_ie5up ) { // Get event details if browser is Internet Explorer
		if ( event.button == 1 || event.type == 'click' )
			return "true";
	} else if (_bi_popup_is_nav5up) { // if mozilla
		if ( e.button == 0 || e.type == 'click' ) 
 			return true;
	} 
	return false;
}

function _bi_popup_createPopupMenu(menuIDPrefix, metadata, formName, isPPR,isSmallStyle)
{
	var depths = metadata[0];
	var labels = metadata[1];
	// type (0=menu,1=link,2=selected,3=separator);
	var types = metadata[2];
	var params = metadata[3];
	var rootDiv = _bi_popup_createDIV(menuIDPrefix + "D",1);
  rootDiv._bi_depth = 0;
	var rootTable = _bi_popup_createTable(menuIDPrefix +"T");
  var tableBody = document.createElement("TBODY");
  tableBody.id = menuIDPrefix + "TB";
	rootDiv.appendChild(rootTable);		
  rootTable.appendChild(tableBody);
	_bi_popup_createSubMenu(menuIDPrefix, formName, 0, depths.length, depths, labels, types, params,tableBody, isPPR,isSmallStyle);
  document.body.appendChild(rootDiv);
	return rootDiv;
}

function _bi_popup_createSubMenu(menuIDPrefix, formName, index, maxIndex, depths, labels, types, params, parentObj, isPPR,isSmallStyle)
{
  var currentDepth = depths[index];
	for(;(index<maxIndex)&&(currentDepth==depths[index]);index++)
	{
    var depth = depths[index];
		var type = types[index];
		var label = labels[index];
		var row = document.createElement("TR");
    row.id = menuIDPrefix + index + "TR";
		if( (type==0)||(type==3) ) // menu item or menu item with separator
		{			
      var cell = _bi_popup_createCell(menuIDPrefix + index,"left",1,isSmallStyle);
      cell._bi_depth = depth;
      if(type==3)
      { // add separator
        cell.style.borderTopStyle = "solid";
        cell.style.borderTopWidth = "1";
        cell.style.borderTopColor = "black";        
      }
      cell._bi_menu = "foo"; 
      _bi_popup_attachEvent(cell,"mouseover",_bi_popup_mouseOverItemDrillMenuEntry);      
      _bi_popup_attachEvent(cell,"mouseout",_bi_popup_lowlight);      
			cell.appendChild(_bi_popup_createTransparentImage());			
			cell.appendChild(_bi_popup_createCellText(menuIDPrefix + index + "S",label));				
			cell.appendChild(_bi_popup_createImage(2));			
			var div = _bi_popup_createDIV(menuIDPrefix + index + "D",index+1);
      div._bi_depth = depth;
			var table = _bi_popup_createTable(menuIDPrefix + index + "T");
      var tableBody = document.createElement("TBODY");
      tableBody.id = menuIDPrefix + index + "TB";
			div.appendChild(table);
      table.appendChild(tableBody);
			index = _bi_popup_createSubMenu(menuIDPrefix, formName, index+1, maxIndex, depths,labels,types,params, tableBody, isPPR,isSmallStyle); 			
      document.body.appendChild(div);
			row.appendChild(cell);
		} else if((type==1)||type==4) // link or link with separator
		{
      var cell = _bi_popup_createCell(menuIDPrefix + index,"left",2,isSmallStyle);
      cell._bi_depth = depth;
      if(type==4)
      { // add separator
        cell.style.borderTopStyle = "solid";
        cell.style.borderTopWidth = "1";
        cell.style.borderTopColor = "black";        
      }
      
      if(_bi_popup_is_nav5up)
        cell.style.cursor = "pointer";
      else
        cell.style.cursor = "hand";
      _bi_popup_attachEvent(cell,"mouseover",_bi_popup_highlight);      
      _bi_popup_attachEvent(cell,"mouseout",_bi_popup_lowlight);      
			cell.bi_formName = formName;
			cell.bi_params = params[index];
      cell.bi_isPPR = isPPR;
      _bi_popup_attachEvent(cell,"click",_bi_popup_submit);      
			var img = _bi_popup_createTransparentImage();
      img.id = menuIDPrefix + index + "I";
			cell.appendChild(img);
			cell.appendChild(_bi_popup_createCellText(menuIDPrefix + index + "S",label));				
			row.appendChild(cell);
		} else if( (type==2)||(type==5) ) // selected or selected with separator
		{
      var cell = _bi_popup_createCell(menuIDPrefix + index,"left",2,isSmallStyle);
      cell._bi_depth = depth;
      if(type==5)
      { // add separator
        cell.style.borderTopStyle = "solid";
        cell.style.borderTopWidth = "1";
        cell.style.borderTopColor = "black";        
      }
			var img = _bi_popup_createImage(1);
      img.id = menuIDPrefix + index + "I";
      img.align="left";
			cell.appendChild(img);
			cell.appendChild(_bi_popup_createCellText(menuIDPrefix + index + "S",label));				
			row.appendChild(cell);
		} else if(type==3) // separator
		{
			// TBD 			
		}
		if(parentObj!=(void 0))
			parentObj.appendChild(row);
	}
  return index-1;
}

function _bi_popup_submit(evt)
{
  if(evt==null)
    evt = event;
  var obj;
	if ( _bi_popup_is_ie5up )
    obj = evt.srcElement;
	else if (_bi_popup_is_nav5up)
    obj = this;
  obj = _bi_popup_getParentCell(obj);
  
  // construct a dynamic object based on the params 
  var params = new Object();
  for(var i=0;i<obj.bi_params.length;)
  {    
    params[obj.bi_params[i]] = obj.bi_params[i+1];
    i = i + 2;
  }
  if(this.isPPR)
    _submitPartialChange(obj.bi_formName,1,params);
  else
    submitForm(obj.bi_formName,1,params);
	_bi_popup_hideMenu(0);
  
}

function _bi_popup_createDIV(id,zindex)
{
	var div = document.createElement("DIV");
	div.id = id;  
	div.style.position = "absolute";
  div.style.zIndex=zindex; 
  div.style.visibility="hidden";
  div.style.borderWidth="1";
  div.style.borderStyle="solid";
  div.style.borderColor="#000000";
	return div;
}

function _bi_popup_createTable(id)
{
	var table = document.createElement("TABLE");
	table.cellPadding="2"; 
	table.cellSpacing="0";
  table.border = "0";
	return table;
}

function _bi_popup_createCell(id,align,colSpan,isSmallStyle)
{
  var cell = document.createElement("TD");
	cell.id = id;
	cell.noWrap=true;
  if(isSmallStyle)
  {
    cell.isSmall=true; // mark the cell as having a small style
    cell.className = "OraBIPopupCellLowlight_small";       
  } else
    cell.className = "OraBIPopupCellLowlight";         
	cell.align=align;
  cell.colSpan = colSpan;
  return cell;
}

function _bi_popup_createCellText(id,label)
{
  var cellText = document.createElement("SPAN");
  cellText.id = id;
	cellText.innerHTML = label;
  return cellText;
}

function _bi_popup_createImage(index)
{
	var image = document.createElement("IMG");
	image.style.borderWidth="";
  image.style.verticalAlign="baseline"
	image.width = "10";
	image.height = "10";
	image.src=_bi_imageCache[index].src;
	return image;
}

function _bi_popup_createTransparentImage()
{
	var image = document.createElement("IMG");
	image.style.borderWidth="0";
	image.style.width="10";
	image.style.height="1";
	image.src=_bi_imageCache[0].src;
	return image;
}

function _bi_popup_mergeMetadata( allHierLabel,
                                  collapseLabel,
                                  drillToRelatedLabel,
                                  drillOutLabel,
                                  hiers,
                                  drillToRelatedLabels,
                                  drillToRelatedParams,
                                  drillOutLabels,
                                  drillOutParams,
                                  curPathIndex,
                                  curTargetID,
                                  isCollapse,
                                  collapseParams,
                                  cxtParams)
{
  var numItems = 0;
  var defaultHier=(void 0);
  if(hiers!=(void 0))
  {
    for(var i=0;i<hiers.length;i++)
    {
      if(curPathIndex==i)
      { // add the items in the default drill hierarchy
        defaultHier = hiers[i]; 
        numItems = numItems + defaultHier[0].length - 1;
      }
      numItems = numItems + hiers[i][0].length;
    }
  }
  var isRelatedItemCollapse = false;
  if(isCollapse)
  {
    if(defaultHier!=(void 0))
      numItems = numItems + 2; // collapse will be displayed in the default drill hierarchy and in the submenu hierarchy
    else if(drillToRelatedLabels!=(void 0))
    {
      isRelatedItemCollapse = true;
      numItems = numItems + 1; // if only collapsing drill to related, then only add collapse to the top level menu
    }      
  }
  if(curPathIndex!=-1)// put all of the drill up/down hierarchies on the second level, if the drill hierachy isn't set
    numItems++;
  
  if(drillToRelatedLabels!=(void 0))
  {
    numItems = numItems + drillToRelatedLabels.length + 1;  
  }
  if(drillOutLabels!=(void 0))
  { 
    numItems = numItems + drillOutLabels.length;
    // if we only have drillOutLabels, then don't show them in a submenu
    if(numItems>0)
      numItems++;
  }
  var menuMD = new Array(4);
  var depths = new Array(numItems);
  menuMD[0] = depths;
  var labels = new Array(numItems);
  menuMD[1] = labels;
  var types = new Array(numItems);
  menuMD[2] = types;
  var params = new Array(numItems);
  menuMD[3] = params;

  var index = -1;
  var hierDepthOffset = 0;
  
  var addSep = false;
  // show collapse if there is a default hier or related items
  if( (defaultHier!=(void 0)) || (drillToRelatedLabels!=(void 0)))
  {
    // add "Collapse" 
    if(isCollapse)
    {
      addSep = true;
      index++;
      depths[index] = 1;
      labels[index] = collapseLabel;
      types[index] = 1;
      params[index] = _bi_popup_mergeParams(cxtParams,collapseParams);
    }
  }
  if(defaultHier!=(void 0))
  {
    hierDepthOffset = 1;
    // add the default hierarchy's menu items 
    for(var i=1;i<defaultHier[0].length;i++)
    {
      index++;
      depths[index] = 1;    
      labels[index] = defaultHier[1][i];
      if(defaultHier[0][i]==curTargetID)      
      {
        if(addSep)
          types[index] = 5;        
        else
          types[index] = 2;        
      } else {
        if(addSep)
          types[index] = 4;
        else
          types[index] = 1;        
      }
      params[index] = _bi_popup_mergeParams(cxtParams,defaultHier[2][i]);
      addSep = false; // only add the separator to the first item 
    }

    // add "All Hierarchies"
    index++;
    depths[index] = 1;
    labels[index] = allHierLabel;
    types[index] = 3;
    params[index] = null;    
  }
  
  if(hiers!=(void 0))
  {
    // add the hierarchies
    for(var i=0;i<hiers.length;i++)
    {
      var hierIDs = hiers[i][0];
      var hierLabels = hiers[i][1];
      var hierParams = hiers[i][2];
      index++;
      // add the hierarchy    
      depths[index] = 1 + hierDepthOffset;
      labels[index] = hierLabels[0];
      types[index] = 0;
      params[index] = null;
  
      addSep = false;
      // add collapse
      if( (curPathIndex==i) && isCollapse)
      {
        addSep = true;
        index++;
        depths[index] = 2 + hierDepthOffset;
        labels[index] = collapseLabel;
        types[index] = 1;
        params[index] = _bi_popup_mergeParams(cxtParams,collapseParams);
      }
  
      for(var j=1;j<hierLabels.length;j++)
      {
        index++;
        depths[index] = 2 + hierDepthOffset;      
        labels[index] = hierLabels[j];
        params[index] = _bi_popup_mergeParams(cxtParams,hierParams[j]);
        if(hierIDs[j]==curTargetID)      
        {
          if(addSep)
            types[index] = 5;        
          else
            types[index] = 2;        
        } else 
        {
          if(addSep)
            types[index] = 4;        
          else
            types[index] = 1;        
        }
        addSep = false; // only add the separator to the first item after collapse
      }
    }
  }
  // add Drill to Related links
  if(drillToRelatedLabels!=(void 0))
  {
    // add "Drill To Related" menu item
    index++;
    depths[index] = 1;
    labels[index] = drillToRelatedLabel;
    if(isRelatedItemCollapse) // if there is a collapse, but no hierarchies, then insert a separator between collapse and the related item menu
      types[index] = 3;
    else
      types[index] = 0;
    params[index] = null;    
    
    // add "Drill to Related" items    
    for(var i=0;i<drillToRelatedLabels.length;i++)
    {
      index++;
      depths[index] = 2;
      labels[index] = drillToRelatedLabels[i];
      types[index] = 1;
      params[index] = _bi_popup_mergeParams(cxtParams,drillToRelatedParams[i]);
    }
  }  
  
  // add Drill out links 
  if(drillOutLabels!=(void 0))
  {
    var showSubmenu = true;
    // if we only have drill out links, then don't show them in a submenu
    if(index==-1)
      showSubmenu = false;
    if(showSubmenu) 
    {
      // add "Drill Out" menu item
      index++;
      depths[index] = 1;
      labels[index] = drillOutLabel;
      types[index] = 3;
      params[index] = null;    
    }
    // add "Drill Out" links
    for(var i=0;i<drillOutLabels.length;i++)
    {
      index++;
      if(showSubmenu)
        depths[index] = 2;
      else
        depths[index] = 1;
      labels[index] = drillOutLabels[i];
      types[index] = 1;
      params[index] = _bi_popup_mergeParams(cxtParams,drillOutParams[i]);
    }
  }  
  return menuMD;
}

function _bi_popup_mergeParams(params1,params2)
{
  if(params1==(void 0))
    return params2;
  if(params2==(void 0))
    return params1;
  
  var params = new Array(params1.length + params2.length);
  var index = 0;
  for(var i=0;i<params1.length;i++)
  {
    params[index] = params1[i];
    index++;
  }
  for(var i=0;i<params2.length;i++)
  {
    params[index] = params2[i];
    index++;
  }
  return params;
}