// For cross-browser compatibility.

var htmlClassAttributeName ;

var picList ;


//---------------------------------------------------------------------------------
// Class: FlyOutMenu
//
//
//----------------------------------------------------------------------------------

function FlyOutMenu(a_heading, a_cssID)
{
this.parentNodeID = "noParentNodeIDassigned" ;  // See initialize().
this.flyoutCnt    = 0 ;                         // Count of flyout items in a given column.
this.baseCnt      = 0 ;                         // Count of base menu items.
this.baseNode     = 0 ;
this.flyOutBase   = 0 ;

if (navigator.userAgent.indexOf('MSIE') > 0)    // If IE6, IE7
   htmlClassAttributeName = "className" ;       //
else
   htmlClassAttributeName = "class" ;           // Any other browser.

}


//----------------------------------------------------------------------------------------
// Items added to a FlyOutMenu are instances of FlyOutMenuItem.
//
//
//
//----------------------------------------------------------------------------------------

var cntMI1 = 0 ;


FlyOutMenu.prototype.addItem = function(a_menuItem)
{
var mi = document.createElement("div") ;                // Each menu item wrapped in a div.
var tn = document.createTextNode(a_menuItem.text) ;     // This text node will become a child of the mi div.

switch (a_menuItem.level)
   {
   case 1:                                              // If base menu item (non-flyout)
      
      mi.setAttribute(htmlClassAttributeName, 'MI1') ;  // For CSS rule (MI1 = Menu Item level 1).

      mi.setAttribute('id', this.baseCnt) ;				// To associate with a menu image (photo).
            
      mi.appendChild(tn) ;                              // Assign text of menu item.	
      
      if (a_menuItem.mouseOver)                         // On mouseOver event, server transaction occurs if this
         mi.setAttribute('transOnMouseOver', 'yes') ;   // attribute is 'yes'.
      else                                              //
      	 mi.setAttribute('transOnMouseOver', 'no') ;    //
         
      mi.onmouseover = onMouseOverHandler ;             // At least, item's style and associated photo
      mi.onmouseout = onMouseOutHandler ;               // will be modified.
      
      if (a_menuItem.mouseClick)                        // 
         mi.onclick = clickHandler ;                    //
         
      this.flyOutBase.appendChild(mi);                  // Add menu item to base-level container.
         
      this.baseNode = mi ;                              // Any subsequent flyouts will be children of baseNode.
         
      this.flyoutCnt = 0 ;                              // Prep. for calculating position of possible flyouts.
      ++this.baseCnt ;                                  // Account for this base menu item in the calculation.
      
      break ;
        
   case 2:
                      
      mi.setAttribute(htmlClassAttributeName, 'MI2') ;
      mi.style.top = (((this.baseCnt-1)*32)+2+(this.flyoutCnt*28))+'px' ;

      mi.onclick = clickHandler ;
      
      mi.onmouseover = onMouseOverHandler ;            // At least, item's style will be modified.
      mi.onmouseout = onMouseOutHandler ;              //
           
      mi.appendChild(tn) ;
      this.baseNode.appendChild(mi) ;
      ++this.flyoutCnt ;
      
      break ;

   } // end switch(

} // end method addItem()


//----------------------------------------------------------------------------------------
// a_menuDescription is an XML file that specifies how the menu is constructed.
// a_parentNodeID is the ID of the DOM element that will be the menu's parent node.
//
//----------------------------------------------------------------------------------------
FlyOutMenu.prototype.initialize = function(a_menuDescription, a_parentNodeID)
{         
this.parentNodeID = a_parentNodeID ;    // This is where the menu will be attached. DOM-wise, FlyOutMenu elements are
                                        // children of a_parentNodeID.

if (window.ActiveXObject)                                                       // If IE6
   var xmldoc = new ActiveXObject("Microsoft.XMLDOM") ;                         //
else if (document.implementation && document.implementation.createDocument)     // 
   xmldoc = document.implementation.createDocument("", "", null) ;              // If FF

xmldoc.async = false ;
xmldoc.load(a_menuDescription) ;            // Create a temporary DOM from XML file.

var mp = document.getElementById('MENUPARENT') ;    // Get the element that will contain the main
this.flyOutBase = document.createElement("div") ;   // navigation menu (the menu's parent node).
this.flyOutBase.setAttribute('id', 'FlyOutBase') ;  // Base menu items are contained in their own div.
mp.appendChild(this.flyOutBase) ;                   //

var miTags = xmldoc.getElementsByTagName("MenuItem") ;    // Create a list of items that comprise menu text.
                                                          // This list includes base menu items and flyout items.

for (var i=0; i<miTags.length; i++)                       // For each XML description of a menu item,
   {                                                      // create a javascript object.
   var menuItem = new FlyOutMenuItem() ;                  // 
      
   if (miTags.item(i).parentNode.nodeName == "MenuItem")  // Catch any flyout menu items: Only flyouts have a
      menuItem.level = 2 ;                                // MenuItem parent. Note that only one level of
   else                                                   // flyout is supported.
   	  menuItem.level = 1 ;                                // Level 1 is a base menu item.
   
   menuItem.text = miTags.item(i).firstChild.data ;       // Remove supurflous chars seen
   menuItem.text = menuItem.text.replace(/\n/g, "") ;     // during code development:
   menuItem.text = menuItem.text.replace(/ +$/, "") ;     // newline chars and trailing spaces.
       
   for (var j=0; j<miTags.item(i).childNodes.length; ++j)                   // Determine if menu item description
      {                                                                     // is calling for mouse event(s).
      if (miTags.item(i).childNodes[j].nodeName == 'Transaction')           // (a server transaction via HttpRequest)
         if (miTags.item(i).childNodes[j].firstChild.data == 'onmouseover')
            menuItem.mouseOver = true ;
         else if (miTags.item(i).childNodes[j].firstChild.data == 'onmouseclick')
        	menuItem.mouseClick = true ;
      }
    
   this.addItem(menuItem) ;    	   // Populate the HTML DOM.
   }
   
   
servTrans.tTarget = 'MENUPICDIV' ;           // Server's contribution to the menu area is
servTrans.tName   = 'MenuInitialize' ;       // inserted into the DOM at MENUPICDIV, which
doServerTransaction(servTrans) ;             // holds a group of overlayed images (hidden via css).

   
} // end method initialize()


//----------------------------------------------------------------------------------------
// Class: FlyOutMenuItem
//
// As XML-based menu description is parsed, FlyOutMenuItem objects are created and passed
// to FlyOutMenu::addItem().
//
//
//----------------------------------------------------------------------------------------
function FlyOutMenuItem()
{
this.level = 0 ;
this.text = '' ;
this.mouseOver = false ;
this.mouseClick = false ;

}

// end class FlyOutMenuItem

var previousMI ;          // Used by onMouseOverHandler()

//----------------------------------------------------------------------------------------
// To ensure no orphaned flyouts, all flyouts of all base menu items are hidden here.
//----------------------------------------------------------------------------------------
function hideFlyouts()
{
var baseContainer = document.getElementById('FlyOutBase') ;    // Get the element that contains all base menu items.

for (var i=0; i<baseContainer.childNodes.length; ++i)
   for (var j=1; j<baseContainer.childNodes[i].childNodes.length; ++j)
            baseContainer.childNodes[i].childNodes[j].style.visibility = 'hidden' ; 
}

//---------------------------------------------------------------------------------------
// Generally, we expect the mouse to be moved over a main menu used for site navigation.
// Elements having class name MI1 (Menu Item level 1) reside in the menu's base column. MI2
// elements reside in the first flyout column.
//
// 
//
//----------------------------------------------------------------------------------------
function onMouseOverHandler(a_event)
{
var mTarget ;         // Menu element on which the calling event occurred.
var mpc = null ;      // Menu-picture container element.
var mpCnt = 0 ;       // Count of menu pictures (children of mpc).


if (a_event == null)                            // If null then IE6
   a_event = window.event ;                     //

if (a_event.target == null)                     // If null then IE6
   mTarget = a_event.srcElement ;               //
else                                            //
   mTarget = a_event.target ;                   //
 	 
if (mTarget.getAttribute(htmlClassAttributeName) == 'MI1')       // Base (non-flyout) column of menu.
   {  
   mpc = document.getElementById('MENUPICDIV')                   // The container <div> for menu images.
   mpCnt = mpc.childNodes.length ;                               // The number of images.
      
   for (var i=0; i<mpCnt; ++i)                                   // By brute force hide the menu photo
      mpc.childNodes.item(i).style.visibility = 'hidden' ;       // going out of context.

   mpc.childNodes.item(parseInt(mTarget.id)).style.visibility = 'visible' ;  // Unhide the photo now in context.
      
   for (var i=0; i<mTarget.parentNode.childNodes.length; ++i)
      {
   	  if (mTarget.parentNode.childNodes[i].nodeName == 'DIV')
   	     mTarget.parentNode.childNodes[i].style.background = 'red' ;
   	  }
   	                	
   if (previousMI != null)               // If moving between menu elements.
      hideFlyouts() ;
      
   for (var i=1; i<mTarget.childNodes.length; i++)
      mTarget.childNodes.item(i).style.visibility = 'visible' ;              // Display in-scope flyouts.
              
   } // end if (mTarget...class
   
else if (mTarget.getAttribute(htmlClassAttributeName) == 'MI2')
	 {
		if (previousMI.getAttribute(htmlClassAttributeName) == 'MI1')
		   previousMI.style.background = '#8B0000' ;
	 }
	 
mTarget.style.background = '#8B0000' ;            // Accentuate selection.

if (mTarget.childNodes.length > 1)                             // If any flyouts, accentuate the
   mTarget.childNodes.item(1).style.background = '#8B0000' ;   // first one.

mTarget.style.cursor = 'pointer' ;
   
previousMI = mTarget ;          // Track where we were.

} // end onMouseOverHandler()


//------------------------------------------------------
function onMouseOutHandler(a_event)
{
var mTarget ;                      // Menu element on which the event occurred.
var mMovingTo ;                    // Node to which the mouse is moving.

if (a_event == null)               // If null then IE6
   {
   mTarget   = window.event.srcElement ;
   mMovingTo = window.event.toElement ;
   }

else
   {
   mTarget = a_event.target ;
   mMovingTo = a_event.relatedTarget ;
   }


if (mMovingTo.getAttribute(htmlClassAttributeName) == 'MI1' && mTarget.getAttribute(htmlClassAttributeName) == 'MI1')       
   mTarget.style.background = 'red' ;

if (mMovingTo.getAttribute(htmlClassAttributeName) == 'MI2' && mTarget.getAttribute(htmlClassAttributeName) == 'MI2')       
   mTarget.style.background = 'red' ;

} // end onMouseOutHandler()

//-------------------------------------------------------
function clickHandler(a_event)
{
var mTarget ;          // Menu element on which the event occurred.

if (a_event == null) a_event = window.event ;   // If null then IE6
if (a_event.target == null)                     //
   mTarget = a_event.srcElement ;                // If null then IE6
else                                            //
	 mTarget = a_event.target ;                    //

servTrans.tTarget = 'CONTENTDIV' ;              // ID of the target element of the server transaction.


var c = mTarget.getAttribute(htmlClassAttributeName) ;

if (c == 'MI1')
   {
   if (mTarget.childNodes.length > 1)       // If MI1 has one or more MI2 children (flyouts).
      {	
      servTrans.tName = mTarget.firstChild.data + ' ' +   // Procede as if first flyout was clicked.
                     mTarget.childNodes[1].firstChild.data + ' Click' ;           // 
      }
   else
   	  {                                              // A server transaction name is taken from menu text.
      servTrans.tName = mTarget.firstChild.data + ' Click' ;         //
      }
   }

else if (c == 'MI2')                                             // Debug note: two calls to this event handler
	                                                               // observed. Why double calls?
	{
   servTrans.tName = mTarget.parentNode.firstChild.data + ' ' +   //
                     mTarget.firstChild.data + ' Click' ;         //
                     
   // TODO: stop bubbling phase to prevent second call ??               
                     
   }                     
                     
if (c == 'MI2')
   {
   for (var i=0; i<mTarget.parentNode.childNodes.length; ++i)
      {
      if (mTarget.parentNode.childNodes[i].nodeName == 'DIV')
         {
         mTarget.parentNode.childNodes[i].style.background = 'red' ;
         mTarget.parentNode.childNodes[i].style.visibility = 'hidden' ;
        }
      }
   }
   
doServerTransaction(servTrans) ;      // Get appropriate page (div) content from server.
  
} // end clickHandler()
