/* JavaScript file for all script functions in the 12:01 web pages */

/* Created: 01/07/06 */
/*          Daniel Del Conte */

/* The menu code is based on the DHTML JavaScript Drop Down Menu Tutorial code */
/* (http://www.aspandjavascript.co.uk/javascript/) by James Doz
/* It is simplified because this menu doesn't have to support nested submenus */
/* Nevertheless it is configurable with special class definitions in the stylesheet *
/* and supports icons in front of the labels. */



/* Global variables, identifying executing browser software and important implementation details */
/* The variables are filled in by the function SniffBrowser() */
var dhtml=false;			/* Dynamic HTML is available */
var dom=false;				/* W3C-DOM syntax is possible */
var ns4=false;				/* Netscape Navigator Version 4.x */
var op5=false;				/* Opera Version 5.x */
var op6=false;				/* Opera Version 6.x */
var ie4=false;				/* Internet Explorer Version 4/5 */

var TimeOn=null;			/* Timer used to close an open menu */
var MaxMenus=10;			/* A maximum of 10 menus is allowed so far */
var MenuCount=0;			/* Counts the menus during creation */
var LabelCount=0;			/* Used to count labels and items during creation */
var Menus=new Array(MaxMenus);		/* Storage for the menus in the system */
var MenuActive=new Array(MaxMenus);	/* Stores the currently active menus */
var ImageCount=0;			/* Stores the number of arrow images */

var MenuArrImgs=new Array();		/* Stores the menu arrow images */
var MenuImgs=new Array();		/* Stores all the menu item images */
var MenuBackg=new Array();		/* Stores the menu background colors */
var ImgPath="";				/* Stores the path to the images used throughout the menu */


/* General functions to cope with JavaScript and the browser DOM */
/* ------------------------------------------------------------- */

/* Determines the web browser and the version the script will be running on. */
/* Fills in the global Variables agt, ns4, op5/6, mac, ie and mac_ie. */
function SniffBrowsers()
{
  var op=false;

  if (document.getElementById) {
    dhtml=true;
    dom=true;
  } else {
    if (document.all) {
      dhtml=true;
      ie4=true;
    } else {
      if (document.layers) {
        dhtml=true;
        ns4=true;
      }
    }
  }
  if (window.opera) {
    op=true;
    op5=(navigator.userAgent.indexOf("Opera 5")!=-1)||(navigator.userAgent.indexOf("Opera/5")!=-1);
    op6=(navigator.userAgent.indexOf("Opera 6")!=-1)||(navigator.userAgent.indexOf("Opera/6")!=-1);
  }
}

/* Searches for the object with the specified name in the whole document, starting with Object, */
/* Netscape 4-only */
function GetObjectNS4(Object,ObjectName)
{
  var x=Object.layers;
  var Found, Temp;
  for (var i=0;i<x.length;i++) {
    if (x[i].id==ObjectName) return x[i];
    if (x[i].layers.length) {
      Temp=GetObjectNS4(x[i],ObjectName);
      if (Temp) return Temp;
    }
  }
  return false;
}

/* Delivers the object of the specified id */
function GetObject(ObjectID)
{
  if (dom&&document.getElementById(ObjectID)) return document.getElementById(ObjectID);
  else if (ie4&&document.all(ObjectID)) return document.all(ObjectID);
  else if (ns4&&document.layers[ObjectID]) return GetObjectNS4(document,ObjectID);
}

/* Delivers the Style Object of the specified tag */
function GetStyleObject(ObjectID, Document)
{
  var obj=GetObject(ObjectID);
  if (!ns4&&obj) return obj.style; else return obj;
  
  return false;
}

/* Makes an object visible or hides it; uses the CSS style object to change the visibility state */
function Show(ObjectID,DoShow)
{
  var StyleObject=GetStyleObject(ObjectID,document);
  if (StyleObject) {
    if (DoShow) StyleObject.visibility="visible";
    else StyleObject.visibility="hidden";
    return true;
  }
  return false;
}

/* Returns the x location of the object with the specified ID */
function GetX(ObjectID)
{
  if (ns4) {
    var Object=GetObjectNS4(document,ObjectID);
    if (Object) return Object.pageX;
  } else {
    var Object;
    if (ie4) Object=document.all[ObjectID];
    else Object=document.getElementById(ObjectID);
    if (Object) {
      var x=Object.offsetLeft;
      Temp=Object.offsetParent;
      while (Temp) {
        x+=Temp.offsetLeft;
        Temp=Temp.offsetParent;
      }
      return x;
    }
  }
  return x;
}

/* Returns the y location of the object with the specified ID */
function GetY(ObjectID)
{
  if (ns4) {
    var Object=GetObjectNS4(document,ObjectID);
    if (Object) return Object.pageY;
  } else {
    var Object;
    if (ie4) Object=document.all[ObjectID];
    else Object=document.getElementById(ObjectID);
    if (Object) {
      var y=Object.offsetTop;
      Temp=Object.offsetParent;
      while (Temp) {
        y+=Temp.offsetTop;
        Temp=Temp.offsetParent;
      }
      return y;
    }
  }
  return 0;
}

/* Returns the pixel width of the object with the specified ID */
function GetWidth(ObjectID)
{
  if (ns4) {
    var Object=GetObjectNS4(document,ObjectID);
    if (Object) return Object.clip.width;
  } else {
    var Object=false;
    if (ie4) Object=document.all[ObjectID];
    else Object=document.getElementById(ObjectID);
    if (Object) {
      if (op5) return Object.style.pixelWidth;
      else return Object.offsetWidth;
    }
  }
  return 0;
}

/* Returns the pixel height of the object with the specified ID */
function GetHeight(ObjectID)
{
  if (ns4) {
    var Object=GetObjectNS4(document,ObjectID);
    if (Object) return Object.clip.height;
  } else {
    var Object=false;
    if (ie4) Object=document.all[ObjectID];
    else Object=document.getElementById(ObjectID);
    if (Object) {
      if (op5) return Object.style.pixelHeight;
      else return Object.offsetHeight;
    }
  }
  return 0;
}

/* Finds an image in a web page, Netscape 4 only */
function FindImage(ImageID,StartSearch)
{
  var i,Image;
  for (i=0;i<StartSearch.images.length;i++) {
    if (StartSearch.images[i].name==ImageID) return StartSearch.images[i];
  }
  for (i=0;i<StartSearch.layers.length;i++) {
    if ((Image=FindImage(ImageID,StartSearch.layers[i].document))!=null) {
       Image.container=StartSearch.layers[i];
       return Image;
    }
  }
  return null;
}

/* Moves an element on the page to another location */
function MoveTo(ObjectID,X,Y)
{
  var Object=GetStyleObject(ObjectID,document);
  if (Object) {
    if (ns4) {
      Object.top=Y;
      Object.left=X;
    } else {
      if (op5) {
        Object.pixelTop=Y;
        Object.pixelLeft=X;
      } else {
        Object.top=Y+'px';
        Object.left=X+'px';
      }
    }
    return true;
  }
  return false;
}

/* Changes the class of an element (and therefore the look) */
/* Not for Netscape 4 */
function ChangeClass(ObjectID,NewClass)
{
  var Object=false;
  if (ie4) Object=document.all[ObjectID];
  else Object=document.getElementById(ObjectID);
  if (Object) {
    if (op5||op6) Object.style.className=NewClass;
    else Object.className=NewClass;
  }
  return false;
}

/* Changes the background color of the object with the specified ID */
function SetBackground(ObjectID,NewColor)
{
  if (ns4) {
    var Object=GetObjectNS4(document,ObjectID);
    if (Object) Object.bgColor=NewColor;
  } else {
    var StyleObject=GetStyleObject(ObjectID,document);
    if (StyleObject) {
      if (op5) StyleObject.background=NewColor;
      else StyleObject.backgroundColor=NewColor;
    }
  }
}

/* Changes the text color of the object with the specified ID */
function SetColor(ObjectID,NewColor)
{
  var Object;
  if (ns4) Object=GetObjectNS4(document,ObjectID);
  else Object=GetStyleObject(ObjectID,document);
  if (Object) Object.color=NewColor;
}

/* Changes the image of the specified image element */
function SetImage(ObjectID,NewSource)
{
  var ImageObject;
  if (ns4) ImageObject=FindImage(ObjectID,document);
  else ImageObject=eval('document.images.'+ObjectID);
  if (ImageObject) ImageObject.src=eval(NewSource).src;
}

/* Stops event processing */
function StopEvent(evt)
{
  var e=(window.event)?window.event:evt;
  if (e.stopPropagation) e.stopPropagation();
  e.cancelBubble=true;
  return true;
}


/* Specific menu functions */
/* ----------------------- */

/* Installs an event handler which closes all menus when clicking on the document */
function InitMenuEvents()
{
  if (document.captureEvents) document.captureEvents(Event.MOUSEDOWN);
  document.onmousedown=HideAllMenus;
}

/* Hides all currently open menus */
function HideAllMenus()
{
  for (var i=1;i<=MenuCount;i++) Menus[i].Hide();
}

/* Reacts on the mouse hovering over a menu label. This cancels a timer established by the MenuOut() */
/* function which closes automatically all open menus. The menu for the label is shown in the function */
/* ShowMenu() afterwards. */
function MenuOver(MenuNo,PullDown,ImageNo)
{
  clearTimeout(TimeOn);
  HideAllMenus();
  Menus[MenuNo].Show(PullDown,ImageNo);
}

/* Sets a timer for one second, so that all menus are automatically closed when the mouse leaves the */
/* menu. When the mouse wanders to the next menu label, the timer is cancelled. */
function MenuOut()
{
  TimeOn=setTimeout("HideAllMenus()",1000);
}

/* Reacts on the mouse hovering over a menu item in a menu. This cancels the timer established by the */
/* MenuOut() or MenuItemOut() functions. */
function MenuItemOver(HighlightedItem)
{
  clearTimeout(TimeOn);
  
  /* Highlight the item and change the image */
  if (ns4) SetBackground('MenuItemLabel'+HighlightedItem,'#FFDB8B');
  else {
    SetBackground('LabelRow'+HighlightedItem,'#FFDB8B');
    ChangeClass('MenuItemLink'+HighlightedItem,'SubmenuClassActive');
  }
  SetImage('MenuItemImage'+HighlightedItem,MenuImgs[HighlightedItem*2+1]);
}

/* Reacts on the mouse leaving a menu item */
function MenuItemOut(HighlightedItem)
{
  TimeOn=setTimeout("HideAllMenus()",1000);
  
  /* Remove the highlight from the item and change the image */
  if (ns4) SetBackground('MenuItemLabel'+HighlightedItem,'transparent');
  else {
    SetBackground('LabelRow'+HighlightedItem,'transparent');
    ChangeClass('MenuItemLink'+HighlightedItem,'SubmenuClass');
  }
  SetImage('MenuItemImage'+HighlightedItem,MenuImgs[HighlightedItem*2]);
}


/* Creates a menu. A menu acts as container for several menu items that open up when the user hovers */
/* the mouse over its label in the menu bar. If the label doesn't have any items, no menu box is opened. */
/* Instead the label itself is a link that leads to a page. */
/* A menu highlights and opens itself upon request */
/* The menu is implemented as an HTML source stream that is written out into the web page and configurable */
/* through the stylesheet. Menus have to be created first and then added to the menu bar. */
function Menu(Label,URL,PullDown,ImageWidth,ImageHeight)
{
  this.MenuLabel=new String(Label);		/* Stores the label of the menu */
  this.MenuURL=new String(URL);                 /* Stores the URL for the menu label */
  this.MenuItemText=new Array();		/* Stores the HTML source of each menu item */
  this.ItemCount=0;				/* Stores the number of menu items in this menu */
  this.MenuNo=0;				/* Stores the number of this menu. This will be set */
                                                /* when adding the menu to the menu bar */
  this.LabelNo=0;				/* Stores the number of the menu label */
                                                /* Will be set when adding the menu to the menu bar */
  this.PullDown=PullDown;			/* Determines, if the menu will open below the label or above */
  this.ImageWidth=ImageWidth;			/* Stores the size of an image in this menu */
  this.ImageHeight=ImageHeight;
  this.ArrImgNo=0;				/* Stores the index of the menu arrow image */
  
  
  /* Adds an item to the menu; ItemText is the label text, ItemIcon the URL of an icon (null if none), */
  /* URL ist the URL of the web page that is opened by clicking on the menu item */
  this.AddItem=function(ItemText,ItemIcon,URL,PullDown)
  {
    /* Increment counters */
    this.ItemCount++;
    LabelCount++; 

    /* Save the image */
    MenuImgs[LabelCount*2]=new Image();
    MenuImgs[LabelCount*2].src=ImgPath+ItemIcon+'.gif';
    MenuImgs[LabelCount*2+1]=new Image();
    MenuImgs[LabelCount*2+1].src=ImgPath+ItemIcon+'s.gif';

    /* Create the HTML source for the menu item. This is a table row with only one cell. This cell */
    /* contains a div or a layer (for Netscape 4) which contains a one-rowed table with two cells, */
    /* one for the icon and one for the item text. */
    var Temp=new String('<tr><td id="LabelRow'+LabelCount+'" ');
    
    /* If it's only a separator, just draw a horizontal line */
    if (ItemText == "--") Temp += '<hr class="MenuSeparator">';
    
    else {

	    /* If the executing browser isn't Netscape 4, the events can be directly attached to the table cells */
	    /* otherwise there will be a new layer inserted */
	    if (!ns4) {

	      /* Attach events */
	      Temp+='onmouseout="MenuItemOut('+LabelCount+');" onmouseover="MenuItemOver('+LabelCount+');" onclick="document.location.href=\''+URL+'\';" ';
	    }
	    Temp+='>';
	    if (ns4) Temp+='<ilayer><layer onmouseout="MenuItemOut('+LabelCount+');" onmouseOver="MenuItemOver('+LabelCount+');" ';
	    else Temp+='<div ';

	    Temp+=' class="MenuItemLabel" id="MenuItemLabel'+LabelCount+'">';
	    Temp+='<table border="0" cellpadding="0" cellspacing="0"><tr><td><a href="'+URL+'" class="SubmenuClass" id="MenuItemLinkIcon'+LabelCount+'">';
	    if (ItemIcon) Temp+='<img src="'+MenuImgs[LabelCount*2].src+'" id="MenuItemImage'+LabelCount+'" class="MenuImage" style="width: '+this.ImageWidth+'; height: '+this.ImageHeight+';" />';
	    else Temp+='<img src="'+ImgPath+'noimg.gif" class="MenuImage" style="width: '+this.ImageWidth+'; height: '+this.ImageHeight+';" />';
	    Temp+='</a></td><td>';
	    Temp+='<a href="'+URL+'" class="SubmenuClass" id="MenuItemLink'+LabelCount+'">';
	    Temp+=ItemText;
	    Temp+='</a></td></tr></table>';

	    if (ns4) Temp+='</layer></ilayer>';
	    else Temp+='</div>';
	  }
    Temp+='</td></tr>';

    /* Store the HTML string for later */
    this.MenuItemText[this.ItemCount]=new String(Temp);    
  }

  /* Writes the code for the menu into the web page */
  this.Write=function() 
  {
    /* If there are no items, no HTML source is generated */
    if (this.ItemCount<=0) return true;    

    /* String holding the complete HTML source for the menu, combining all the menu labels in a table */
    var Temp=new String('<div class="Submenu" id="Menu'+this.MenuNo+'" style="background-color :'+MenuBackg[this.MenuNo]+';" onmousedown="return StopEvent(event);"><table border="0" cellpadding="0" cellspacing="0">');
    for (var i=1;i<=this.ItemCount;i++) {
      Temp+=this.MenuItemText[i];
    }
    Temp+='</table></div>';
    document.write(Temp);
    return true;
  }

  /* Write the code for the menu name (the label in the menu bar) into the web page */
  this.FormatLabel=function()
  {
    /* HTML source for one submenu label */
    /* This is basically a table cell with all the written out label elements */
    var Temp=new String('<td id="LabelCell'+this.LabelNo+'" ');

    /* If the browser isn't Netscape 4, all the events can be attached to the table cell directly. */
    /* Otherwise there is an additional layer object which receives all the events. */
    if (!ns4) {
      
      /* Attach events to the table cell tag */
      Temp+=' onmouseout="MenuOut();" onmouseover="MenuOver('+this.MenuNo+','+this.PullDown+');" onmousedown="return StopEvent(event);"';
      if (this.MenuURL) Temp+=' onclick="document.location.href=\''+this.MenuURL+'\';" ';
    
    }
    Temp+='>';

    if (ns4) Temp+='<ilayer><layer onmouseout="MenuOut();" onmouseOver="MenuOver('+this.MenuNo+','+this.PullDown+');" onmousedown="return StopEvent(event);" ';
    else Temp+='<div ';

    Temp+=' class="SubmenuLabel" id="MenuLabel'+this.LabelNo+'">';
    
    /* Create link for the menu item */
    Temp+='<a href="'+this.MenuURL+'"'+' class="SubmenuClass" id="MenuLink'+this.LabelNo+'">';
    Temp+=this.MenuLabel;
    if (this.ItemCount>0) Temp+='&nbsp;<img src="'+MenuArrImgs[this.ArrImgNo*2].src+'" id="MenubarImage'+this.LabelNo+'" class="MenuArrow"/>';
    Temp+='</a>';
    
    if (ns4) Temp+='</layer></ilayer>';
    else Temp+='</div>';
    
    Temp+='</td>';
    return Temp;
  }

  /* Highlights the label and shows the menu, if not empty */
  this.Show=function(PullDown)
  {
    /* Make the menu active */
    MenuActive[this.MenuNo]=true;
  
    /* Highlight the label and change the image, if necessary*/
    if (ns4) SetBackground('MenuLabel'+this.LabelNo,'#FFDB8B');
    else {
      SetBackground('LabelCell'+this.LabelNo,'#FFDB8B');
      ChangeClass('MenuLink'+this.LabelNo,'SubmenuClassActive');
    }
    SetImage('MenubarImage'+this.LabelNo,MenuArrImgs[this.ArrImgNo*2+1]);
  
    /* If the menu is not empty, display it */
    if (this.ItemCount) {
    
      /* Calculate correct position for menu. It should open below the menu label, aligned with the left */
      /* edge of the label. */
      var LabelObj;
      if (ns4) LabelObj='MenuLabel'+this.LabelNo;
      else LabelObj='LabelCell'+this.LabelNo;
      var LabelX=GetX(LabelObj);
      var LabelY=GetY(LabelObj);
      var LabelHeight=GetHeight(LabelObj);
      var MenuHeight=GetHeight('Menu'+this.MenuNo);
      if (PullDown) MoveTo('Menu'+this.MenuNo,LabelX,LabelY+LabelHeight);
      else MoveTo('Menu'+this.MenuNo,LabelX,LabelY-MenuHeight);
  
      /* Display it already! */
      Show('Menu'+this.MenuNo,true);
    }
  }
 
  /* Removes the highlight from the label and hides the menu, if shown */
  this.Hide=function()
  {
    /* Handle only when menu is active */
    if (MenuActive[this.MenuNo]) {    

      /* Make it inactive */
      MenuActive[this.MenuNo]=false;

      /* Remove the highlight and change the image back*/
      if (ns4) SetBackground('MenuLabel'+this.LabelNo,'transparent');
      else {
        SetBackground('LabelCell'+this.LabelNo,'transparent');
        ChangeClass('MenuLink'+this.LabelNo,'SubmenuClass');
      }
      SetImage('MenubarImage'+this.LabelNo,MenuArrImgs[this.ArrImgNo*2]);

      /* Remove the menu from display */
      Show('Menu'+this.MenuNo,false);
    }
  }
}

/* Creates a menu bar, i. e. the container for the menu system. The menu bar holds an array of menus */
/* which can be labels that are just links but also labels that open real menus. Each menu knows by itself */
/* if to open itself or not. */
/* After creation of all menus these are to be added to the menu bar which establishes the menu system. Without */
/* this step the menus are not usable */
/* The menus are not stored in the object but in the global Menus array because they must be accessible by */
/* the handler functions. */
function MenuBar(MenuCls,ArrowImage)
{
  this.MenuClass=new String(MenuCls);		/* Stores the class of the div containing the menu */
  this.MenuCount=0;				/* Stores the number of menu labels in this menu bar */
  this.BeginIndex=MenuCount;			/* Stores the first index of the label in this menu bar */

  /* Store the arrow images */
  ImageCount++;
  this.ImageNo=ImageCount;
  MenuArrImgs[ImageCount*2]=new Image();
  MenuArrImgs[ImageCount*2].src=ImgPath+ArrowImage+'.gif';
  MenuArrImgs[ImageCount*2+1]=new Image();
  MenuArrImgs[ImageCount*2+1].src=ImgPath+ArrowImage+'s.gif';

  /* Adds a menu to the menubar */
  this.AddMenu=function(Submenu,Background)
  {
    /* Increment counter */
    LabelCount++;
    MenuCount++;
    this.MenuCount++;

    /* Establish references */
    Submenu.LabelNo=LabelCount;
    Submenu.MenuNo=MenuCount;
    Submenu.ArrImgNo=this.ImageNo;
    
    /* Store menu in the system */
    Menus[MenuCount]=Submenu;
    MenuBackg[MenuCount]=Background;
  }

  /* Writes out the whole menu system */
  this.Write=function() 
  {    
    /* Write out the menu bar */
    var Temp=new String('<div class="'+this.MenuClass+'"> <table border="0" cellpadding="0" cellspacing="0">');
    Temp+='<tr>';
    for (var i=this.BeginIndex+1;i<=this.BeginIndex+this.MenuCount;i++) Temp+=Menus[i].FormatLabel(this.ImageNo);
    Temp+='</tr></table>';
    document.write(Temp);
    
    /* Write out all the menus */
    for (var i=this.BeginIndex+1;i<=this.BeginIndex+this.MenuCount;i++) Menus[i].Write();
    
    document.write('</div>');
  }
}


