///////////////////////////////////////////////////////////////////
// some JavaScript routines for www.stephan-brumme.com
// this code is copyrighted !
//
// send me a short eMail (mail@stephan-brumme.com) if you like to
// include some stuff in your own web sites
///////////////////////////////////////////////////////////////////



////////////////////////////////////
// browser settings
var userAgent = navigator.userAgent.toLowerCase();
var n4    = document.layers;
var ie    = document.all;
var opera = (userAgent.indexOf('opera')>0)?true:false;
var moz   = (document.getElementById && !document.all);
var w3c   = document.documentElement;
var dhtml = (ie || w3c) && !opera;

var ns4 = (document.layers)?true:false;
var ns6 = (document.getElementById)?true:false;
var ie4 = (document.all)?true:false;
var ie5 = false; // includes 5.0, 5.5, 6.0, ...

var ie6 = (userAgent.indexOf('msie 6')>0)?true:false;
// Microsoft Stupidity Check(tm)
if (ie4)
{
   if (userAgent.indexOf('msie')>0 &&
      userAgent.indexOf('msie 4')<0)
      ie5 = true;
   ns6 = false;
}

var dotnet = (userAgent.indexOf('net clr')>0)?true:false;
// browser settings
////////////////////////////////////


// --------------------------------------------------------------------------------------

var tooltipshown    = false;
var tooltipheight   =     0;
var searchfocus     = false;

// hyperlinks
var normalcolor = new Array(255, 160,   0, "#FFA000");
var hovercolor  = new Array(221, 221, 136, "#DDDD88");


// --------------------------------------------------------------------------------------
// use German language only on demand, English is default
var isEnglish = (mainlanguage=="en");
function i18n(base, offset)
{
 if (!isEnglish)
    return base+offset;
 else
    return base;
}

// --------------------------------------------------------------------------------------
// mouse capture stuff, partially taken from Erik Bosrup's overLIB (+tooltip code below)

var mousex = -100;
var mousey = -100;
var mousescrollbar = false;

// DOM mousemove capture
function DOM_MouseMove(e)
{
   mousex = e.screenX;
   mousey = e.screenY;

   return false;
}

// IE mousemove capture
function MS_MouseMove(e)
{
   if (!dhtml)
      return;

   // determine mouse cursor position (depends on browser vendor/version)
   if (ie)
   {
      mousex = window.event.clientX;
      mousey = window.event.clientY;
      if (mousey >= document.body.clientHeight-tooltipheight)
         mousey  = document.body.clientHeight-tooltipheight;
      mousex += document.body.scrollLeft;
      mousey += document.body.scrollTop;

      //window.status = "x"+mousex+" y"+mousey+" obj"+window.event.srcElement.href+"-";
   }
   else
   {
      mousex = e.pageX;
      mousey = e.pageY;
   }

   // move tooltip
   if (tooltipshown)
   {
      document.getElementById("tooltipDiv").style.left  = mousex+15;
      document.getElementById("tooltipDiv").style.top   = mousey;
   }

   if (ie)
      // colorize scrollbar if mouse hovers over it
      // boost performance by using mousescrollbar to avoid unneccessary redraws
      if ((window.event.clientX > document.body.clientWidth +2 ||
           window.event.clientY > document.body.clientHeight+2))
      {
         if (mousescrollbar == false)
         with (document.body.style)
         {
            scrollbarArrowColor      = "#000000";
            scrollbarBaseColor       = "#46468F";
            scrollbarShadowColor     = "#46468F";
            scrollbarDarkShadowColor = "#46468F";
            scrollbarTrackColor      = "#46468F";
            mousescrollbar = true;
         }
      }
      else
      {
         if (mousescrollbar == true)
         with (document.body.style)
         {
            scrollbarArrowColor      = "#26267D";
            scrollbarBaseColor       = "#26267D";
            scrollbarShadowColor     = "#26267D";
            scrollbarDarkShadowColor = "#26267D";
            scrollbarTrackColor      = "#26267D";
            mousescrollbar = false;
         }
      }
}


// --------------------------------------------------------------------------------------
// change an image (if mouse hovers over it)
function SwitchImage(id, newimage)
{
   if (document.images && dhtml)
      document.images[id].src = eval(newimage+'.src');
}


// --------------------------------------------------------------------------------------
// tranparency helper function
function SetOpacity(element, alpha)
{
   if (ie)
      document.getElementById(element).style.filter = "alpha(opacity="+alpha+
                                                      ", finishopacity="+alpha+")";
   if (moz)
      document.getElementById(element).style.MozOpacity = alpha/100.0;
}


// --------------------------------------------------------------------------------------
// Class "Menu"

var mnu = new Menu();

function Menu()
{
   // menu layout
   var menux     = new Array(  9,  88, 193, 333, 423, 508, 608);
   var menuy     = new Array(129, 129, 129, 129, 129, 129, 129);
   var menuwidth = new Array(150, 520, 170,  95, 185, 110, 110);

   // submenus
   var subMenuHTML    = new Array();
   var subMenus       = 0;

   // timeout control for menu fading
   var menuTimer      = new Array();
   var menuFadeSteps  =    6;
   var menuMaxOpacity =   85;
   var activeMenu     = null;

   // timespan before fading out
   var menuTimeOut    =   250;
   var menuShown      =  null;


   // initialize the menu
   this.Init = function()
   {
      if (!dhtml)
         return;
      this.Hide();
   }


   // add a submenu
   this.AddSubMenu = function(newSubMenu)
   {
      subMenuHTML[subMenus++] = newSubMenu.GetHTML();
   }


   // display the menu
   this.Show =  function(title, parentID, menuID)
   {
      window.status = title;

      // DHTML must be available
      if (!dhtml)
         return;

      // hide menu if already shown
      if (menuShown)
      {
         clearTimeout(menuShown);
         this.Hide();
         clearTimeout(menuShown);
      }

      // submenu is not properly initialized
      if (subMenuHTML[menuID] == null)
         return;

      // prepare this submenu
      with (document.getElementById("menuDiv"))
      {
         newHTML     =  '<table border="0" cellspacing="0" cellpadding="0" width="100%">';

         // BEGIN HACK: use background-studies.gif in the studies section !!!
         if (menuID == 1)
            style.background = "url(/images/background-studies.gif) no-repeat";
         else
            style.background = "url(/images/background-column.gif) repeat";
         // END HACK

         // align background for Internet Explorer
         if (ie)
            newHTML += '<tr height="1"><td></td></tr>';
         newHTML    += subMenuHTML[menuID] + '</table>';

         // set new menu
         innerHTML   = newHTML;
         style.left  = menux[menuID];
         style.top   = menuy[menuID];
         style.width = menuwidth[menuID];
         SetOpacity('menuDiv', 0);
         style.visibility = "visible";
      }

      // fade in
      for (var i = 0; i <= menuFadeSteps; i++)
         clearTimeout(menuTimer[i]);

      for (var i = 0; i <= menuFadeSteps; i++)
         menuTimer[i] = setTimeout("SetOpacity('menuDiv', "+i*menuMaxOpacity/menuFadeSteps+");", i*30);

      // highlight background image
      with (document.getElementById(parentID))
      {
         style.backgroundImage = "url(/images/background.gif)";
         activeMenu = parentID;
      }

      return true;
   }


   // avoid any menu-hiding timeouts
   this.KeepAlive = function()
   {
      if (menuShown)
         clearTimeout(menuShown);
      return true;
   }


   // hide menu
   this.Hide = function()
   {
      // fade out
      for (var i = 0; i <= menuFadeSteps; i++)
      {
         clearTimeout(menuTimer[i]);
         menuTimer[i] = setTimeout("SetOpacity('menuDiv', "+(menuMaxOpacity-i*menuMaxOpacity/menuFadeSteps)+");", i*50);
      }

      // hide menu layer
      menuShown = setTimeout("document.getElementById('menuDiv').style.visibility='hidden';", menuFadeSteps*50);

      // remove background image
      if (activeMenu != null)
         document.getElementById(activeMenu).style.backgroundImage = "";
   }


   // hide menu after a short delay
   this.PrepareToHide = function()
   {
      menuShown = setTimeout('mnu.Hide()', menuTimeOut);
      return true;
   }
}


// --------------------------------------------------------------------------------------
// class "SubMenu"

// hover "hot" gifs
var hotnormal = new Image();
    hotnormal.src = "/images/hot.gif";
var hothover  = new Image();
    hothover.src  = "/images/hot-hover.gif";
var hotName = 'hot';

var preloadStudiesBackground = new Image();
    preloadStudiesBackground.src = "/images/background-studies.gif";

function SubMenu()
{
   // initialize submenu
   var subMenuHTML = "";


   // add a string
   this.Add = function(theString)
   {
      subMenuHTML += theString;
   }


   this.GetHTML = function()
   {
      return subMenuHTML;
   }


   // add an item to a menu
   this.AddItem = function(itemName, itemLink, isHot, isGerman)
   {
      var result = "";

      // remove HTML tags
      var noHTML = itemName.replace(/<.{1,2}>/, '');
          noHTML =   noHTML.replace(/<.{1,2}>/, '');

      // default style for a menu entry
      result += '<tr height="15"><td class="menu" width="100%" ' +
                'onmouseover="this.className = \'menu-hover\'; return true;" ' +
                'onmouseout ="this.className = \'menu\'; return true;" ' +
                'onclick="location.href=\''+itemLink+'\'">' +
                '<a href="'+itemLink+'" class="menu" ';

      // contains an highlightable image ?
      if (isHot)
      {
         // generate unique name (just add some zeros)
         hotName+= '0';
         result += "onmouseover=\"SwitchImage('"+hotName+"','hothover'); window.status='" +
                   noHTML+" ... hot !!!'; return true;\"" +
                   " onmouseout =\"SwitchImage('"+hotName+"','hotnormal');\"" +
                   '>&nbsp;&nbsp;&nbsp;'+itemName+
                   ' <img name="'+hotName+'" src="/images/hot.gif" ' +
                   'width="23" height="12" alt="" />';
      }
      else
         // just show some info
         result += "onmouseover=\"window.status='"+noHTML+"'; return true;\">&nbsp;&nbsp;&nbsp;"+itemName;


      // menu entry refers to a German page
      if (isGerman)
         result += ' <img src="/images/german.gif" width="12" height="9" alt="" />';

      // finish entry
      result += '</a></td></tr>';

      // add to the submenu
      this.Add(result);
   }


   // add an seperator to a menu (called on initialization)
   this.AddSeperator = function(text, noHLine)
   {
      var result = '';

      if (!noHLine)
      {
         if (ie)
            // horizontal line
            result += '<tr height="3"><td><hr class="hr-menu" /></td></tr>';
         else
            // no line
            result += '<tr height="7"></tr>';
      }

      // show some text after the line/break
      if (text)
         result += '<tr height="15"><td class="menu" width="100%">&nbsp;'+text+'</td></tr>';

      // add to the submenu
      this.Add(result);
   }

   // combine two submenus
   this.Combine = function(newSubMenu)
   {
      // HACK: use background-studies.gif !
      subMenuHTML = '<tr style="background: url(/images/background-studies.gif"><td valign="top">'+
                    '<table cellspacing="0" cellpadding="0">'+subMenuHTML+
                    '</table></td><td valign="top"><table>'+newSubMenu.GetHTML()+
                    '</table></td></tr>';
   }
}



// --------------------------------------------------------------------------------------
// tooltips

var fadeelement   =  null;
var fadeoffset    =     5;
var fadeincrement =     0;
var fadevalue     =     0;
var fadetimeout   =    10;
var fadetimer     =    -1;

var fadeover = 0;
var fadeout  = 0;
function showtooltip(text)
{
   if (!dhtml)
      return;

   with (document.getElementById("tooltipDiv"))
   {
      style.left  = mousex+15;
      style.top   = mousey;
      innerHTML   = text;
      style.visibility = "visible";
   }

   if (ie6 || moz)
   {
      // alpha fade effect
      if (fadeincrement <= 0)
         fadeincrement = fadeoffset;
      else
         fadeincrement *= 2;

      if (fadetimer == -1)
         setTimeout("fadetooltip()", fadetimeout);
   }
   else
   {
      fadevalue = 100;
      fadeincrement = 0;
   }

   tooltipshown = true;
}


// called by IE and Mozilla only
function fadetooltip()
{
   with (document.getElementById("tooltipDiv"))
   {
      // keep on moving !!!
      style.left  = mousex+15;
      style.top   = mousey;
   }

   // clamp to 0..80%
   fadevalue += fadeincrement;

   if (fadevalue >= 100)
   {
      fadevalue = 100;
      fadeincrement = 0;
   }

   // hide tooltip
   if (fadevalue <= 0)
   with (document.getElementById("tooltipDiv").style)
   {
      fadevalue = 0;
      fadeincrement = 0;
      visibility = "hidden";
      left  = -100;
      top   = -100;
   }

   // set alpha
   if (fadevalue >= 0)
      SetOpacity("tooltipDiv", fadevalue*0.8);

   // initiate next fade step
   if (fadeincrement != 0)
      fadetimer = window.setTimeout("fadetooltip()", fadetimeout);
   else
      fadetimer = -1;
}


// generate HTML code for the tooltip
function showinfotooltip(element, info, url, filename, size, date)
{
   // save reference to element
   var fadeelement = element;

   // text for status bar
   var status = "";

   // translations
   var name = new Array("info", "info", "URL", "URL", "file", "datei",
                        "size", "gr&ouml;&szlig;e", "upload", "datum");

   tooltipheight = 0;

   var trackDescription = '';
   //if (info)     trackDescription = 'info='+info;
   if (url)      trackDescription = 'url=' +url;
   if (filename) trackDescription = 'file='+filename;
   var tracker = '';
   if (trackDescription != '')
      tracker = '<img src="/images/show_tooltip.gif?'+trackDescription+'" width="1" height="1" border="0" alt="" />';


   // info section
   var infoHtml = '';
   if (info)
   {
      var parts = info.split("|");
      if (parts.length == 2)
      {
         infoHtml = '<tr><td class="header" colspan="3">'+tracker+'&nbsp;' + name[i18n(0,1)] +
                    '</td></tr><tr>'+
                    '<td class="main"><b>'+parts[0]+'</b></td>'+
                    '<td class="main">&nbsp;</td>'+
                    '<td align="right" class="main">'+parts[1]+'</td></tr>';
      }
      else
         infoHtml = '<tr><td class="header" colspan="3">'+tracker+'&nbsp;' + name[i18n(0,1)] +
                    '</td></tr><tr><td class="main" colspan="3">'+info+'</td></tr>';
      status = info;
      tooltipheight += 32;

      // multi-line tooltips ...
      zeilen = status.match(/<br>/);
      if (!zeilen)
         zeilen = status.match(/<br \/>/);
      if (zeilen)
         tooltipheight += zeilen.length*13;
   }

   // URL
   var urlHtml = '';
   if (url)
   {
      urlHtml = '<tr><td class="header" colspan="3">&nbsp;' + name[i18n(2,1)] +
                '</td></tr><tr><td class="main" colspan="3">'+url+'</td></tr>';
      if (url.charAt(0) == '/')
         url = 'www.stephan-brumme.com'+url;
      status = 'go to "'+url+'"';
      tooltipheight += 32;
   }

   // filename (status bar depends on extension !)
   var filenameHtml = '';
   if (filename)
   {
      filenameHtml = '<tr><td class="header" colspan="3">&nbsp;' + name[i18n(4,1)] +
                     '</td></tr><tr><td class="main" colspan="3"><b>'+filename+'</b></td></tr>';
      status = 'download ';

      var tempfilename = filename.toLowerCase();
      if (tempfilename.indexOf(".pdf") > 0 ||
         tempfilename.indexOf(".jpg") > 0 ||
         tempfilename.indexOf(".gif") > 0 ||
         tempfilename.indexOf(".chm") > 0)
         status = 'view ';
      if (tempfilename.indexOf(".exe") > 0)
         status = 'start ';

      status += '"'+filename+'"';
      tooltipheight += 32;
   }

   // size 'n' date
   var sizeDateHtml = '';
   if (size && date)
   {
      sizeDateHtml = '<tr><td class="header">&nbsp;'+name[i18n(6,1)]+'</td>'+
                     '<td class="header" width="10">&nbsp;</td>'+
                     '<td align="right" class="header">'+name[i18n(8,1)]+'&nbsp;</td></tr>'+
                     '<tr><td class="main"><b>'+size+'</b></td>'+
                     '<td class="main">&nbsp;</td>'+
                     '<td align="right" class="main">'+date+'</td></tr>';
      status += " ("+size+", "+date+")";
      tooltipheight += 32;
   }

   // show tooltip
   if (filename && info)
      showtooltip('<table border="0" cellspacing="0" cellpadding="0">'
                  +urlHtml+filenameHtml+sizeDateHtml+infoHtml+'</table>');
   else
      showtooltip('<table border="0" cellspacing="0" cellpadding="0">'
                  +infoHtml+urlHtml+filenameHtml+sizeDateHtml+'</table>');

   // fade out if element loses focus
   element.onmouseout = hidetooltip;

   // show status bar, remove HTML tags
   window.status = status.replace(/<.*>/, ' ');

   // fade the corresponding hyperlink, too
   fadeHyperlink = new FadingHyperlink(element, normalcolor, hovercolor);
   return true;
}


// well, hide those tooltips ;-)
function hidetooltip()
{
   if (!tooltipshown)
      return;

   // fading works only for IE and Mozilla
   if (!ie6 && !moz)
   {
      fadevalue = 0;
      fadeincrement = 0;
   }

   // fade out much slower than fade in
   fadeincrement = -0.5*fadeoffset;
   if (fadetimer == -1)
      setTimeout("fadetooltip()", fadetimeout);

   // no tooltip visible anymore
   tooltipshown = false;

   // clear status bar
   window.status = "";

   // fade the corresponding hyperlink, too
   fadeHyperlink = new FadingHyperlink(this, hovercolor, normalcolor, 5);
}


// --------------------------------------------------------------------------------------
// class "FadingHyperlink"

// kind of a singleton
var fadeHyperlink    = null;
var fadeElementTimer = new Array();

function FadingHyperlink(srcElement, from, to, speed)
{
   // fading behaviour
   this.fadeElementSteps = 10;
   this.fadeSpeed        = 15;


   // convert binary number to its hex equivalent (0..255 => 0..FF)
   this.ToHex = function(value)
   {
      var hextable = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                               'A', 'B', 'C', 'D', 'E', 'F');
      return hextable[Math.floor(value/16)] + hextable[Math.floor(value) % 16];
   }

   // change color of a given element
   this.SetColor = function(r,g,b, element)
   {
      element.style.color = '#'+this.ToHex(r)+this.ToHex(g)+this.ToHex(b);
   }


   // tooltips may be used for any HTML element, but we fade only hyperlinks !
   if (srcElement.tagName != "A")
      return;

   // hyperlink fade works only on IE
   if (!ie)
   {
      // set final color and leave
      srcElement.style.color = '#'+this.ToHex(to[0])+this.ToHex(to[1])+this.ToHex(to[2])
      return;
   }

   // generate unique ID
   var element = srcElement.uniqueID;

   // clear all pending timeouts
   if (fadeElementTimer[0] == element)
   {
      var i = 1;
      while (i < fadeElementTimer.length)
      {
         clearTimeout(fadeElementTimer[i]);
         i++;
      }
   }

   // calculate fading speed
   if (speed == null)
      speed = 1;
   speed *= this.fadeSpeed;

   // set timeouts
   for (var i = 0; i <= this.fadeElementSteps; i++)
   {
      var percentage = i*1.0/this.fadeElementSteps;
      var r = percentage*(to[0]-from[0])+from[0];
      var g = percentage*(to[1]-from[1])+from[1];
      var b = percentage*(to[2]-from[2])+from[2];

      fadeElementTimer[i+1] = setTimeout("fadeHyperlink.SetColor("+r+","+g+","+b+","+element+")", i*speed);
   }
   fadeElementTimer[0] = element;
}


// --------------------------------------------------------------------------------------
// class "Clock" and some number conversion

function Clock()
{
   // some language-dependent constants ...
   var dayofweek = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday',
                             'Thursday', 'Friday', 'Saturday',
                             'Sonntag', 'Montag', 'Dienstag', 'Mittwoch',
                             'Donnerstag', 'Freitag', 'Samstag');
   var month = new Array('January', 'February', 'March', 'April', 'May', 'June',
                         'July', 'August', 'September', 'October', 'November', 'December',
                         'Januar', 'Februar', 'M&auml;rz', 'April', 'Mai', 'Juni',
                         'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember');
   // Clock's last output
   var oldTime = null;


   // ensures to always display at least 2 digits of a number
   this.TwoDigits = function(number)
   {
      // dummy for very large numbers
      number %= 100;
      // prepend zero if neccessary
      if (number < 10)
         number = '0' + number;

      return number;
   }

   this.NumberSuffix = function(number)
   {
      if (number == 11 || number == 12 || number == 13)
        return 'th';

      // get right-most digit
      number %= 10;

      switch (number)
      {
      case 1: return 'st';
      case 2: return 'nd';
      case 3: return 'rd';
      default: return 'th';
      }
   }


   this.Init = function()
   {
       // renew it each 1/4 second
       setInterval("myClock.DisplayClock()", 250);
       // ... and show it now
       this.DisplayClock();
   }


   // display clock
   this.DisplayClock = function()
   {
      // contains current time
      var now = new Date();

      // leave immediately if time hasn't change since last refresh
      if (now == oldTime)
         return;
      oldTime = now;

      // show ':' or whitespace every 2 seconds
      var ShowDots = ((now.getSeconds()%2==0) ? ':' : ' ');

      // filled with date and time
      var day = '';
      var time = '';

      // English date/time
      if (isEnglish)
      {
         // get current day
         day = month[i18n(now.getMonth(), 12)] + ' ' + now.getDate() +
               '<sup>'+this.NumberSuffix(now.getDate())+'</sup>, ' + (now.getYear()%100 + 2000);

         // in the afternoon ?
         var isPM = now.getHours()>12 ? 1 : 0;
         time = now.getHours() - isPM*12 + ShowDots + this.TwoDigits(now.getMinutes());
         if (now.getHours() == 0 || now.getHours() == 12)
            isPM = 1 - isPM;

         // append "am" or "pm"
         if (isPM == 0)
            time += '<font size="-1">am</font>';
         else
            time += '<font size="-1">pm</font>';
      }
      else
      {
         // German date/time
         day = now.getDate() + '. ' + month[i18n(now.getMonth(),12)] +
               ' ' + (now.getYear()%100 + 2000);
         time = now.getHours() + ShowDots + this.TwoDigits(now.getMinutes());
      }

      // date and time together
      var output = dayofweek[i18n(now.getDay(), 7)] + ',<br />' + day +
                   '<br />'+
                   //'<img src="/images/clock.gif" border="0" alt="">&nbsp;'+
                   '<font size="+1">' + time + '</font>';

      // show it
      document.getElementById("clockDiv").innerHTML = output;
   }
}


// --------------------------------------------------------------------------------------
// various runtime functionality

// wrapper functions for bottom line
function goback()
{
   history.back();
}

function doprint()
{
   window.print();
}

function addfavourite()
{
   window.external.AddFavorite(location.href, document.title);
}

function zoom()
{
   top.location = document.location;
}

// determine time needed to load the whole page (incl. pictures), only works for ie4+
function ShowLoadingTime()
{
   stoptime = new Date();
   diff = (stoptime - LoadingStartTime) / 1000;

   document.getElementById("loadingTimeSpan").innerHTML = ' and loaded in '+diff+' seconds';
}


// show detected browser (not navigator.appName)
function ShowBrowser()
{
   // operating system
   var os = navigator.platform;
   if (os == "Win32")
   {
       var platform = navigator.userAgent;

       var pos = platform.indexOf("Windows ");
       var version = platform.substr(pos+8, platform.length-pos-8);
       version = version.substr(0, version.indexOf(";"));

       if (version == "95")
          version = "Windows 95";
       if (version == "98")
          version = "Windows 98";
       if (version == "ME")
          version = "Windows ME";
       if (version == "NT 5.0")
          version = "Windows 2000";
       if (version == "NT 5.1")
          version = "Windows XP";

       os = version;
   }


   // show detected browser
   var browser = "search engines";
   if (ie4)
      browser = "Microsoft Internet Explorer 4";
   if (ie5)
      browser = "Microsoft Internet Explorer 5";
   if (ie6)
      browser = "Microsoft Internet Explorer 6+";
   if (opera)
      browser = "Opera";
   if (ns4)
      browser = "Netscape Navigator 4.x";
   if (ns6)
      browser = "Mozilla/Gecko";

   // DHTML activated ?
   var output = "code generated on-the-fly for "+browser+"/"+os+". "
   output += "DHTML";

   // ActiveX available ?
   if (ie)
   {
      try
      {
         dummy = new ActiveXObject("Shell.UIHelper");
      }
      catch (e) {}
      output += ", scripting";
   }

   // .NET installed ?
   if (dotnet)
      output += " and .NET";

   // show browser and its enabled features
   document.getElementById("browserSpan").innerHTML = output+" enabled.";
}


// open an info pop-up window
function InfoWindow(text, width, height)
{
   if (width == null)
      width = 300;
   if (height == null)
      height = 300;

   wnd = window.open("", "InfoWindow",
           "menubar=no, status=no, resizable=yes, location=no, dependent=yes, width="+width+", height="+height);
   wnd.document.close();
   wnd.document.write('<head>'+
                       '<title>info</title>'+
                       '<link rel="stylesheet" href="/stylesheet.css" type="text/css">'+
                      '</head>'+
                      '<body background="/images/background.gif" text="#FFFFFF" bgcolor="#000066" class="main" '+
                      'onclick="self.close();">'+
                       text+
                       '<br /><center><a href="javascript:self.close();" style="font-size: 11px">Fenster schliessen</a></center>'+
                       '<br />'+
                      '</body>');

   document.body.onunload = wnd.window.close;
   return wnd;
}


// keep an ad at a fixed position
var adTopOffset   = 25;
var oldAdPosition = adTopOffset;
var adDiv = null;
function KeepAdFixed()
{
   // delayed initialisation to give the browser some time to create the adDiv
   if (adDiv == null)
       adDiv = document.getElementById("adDiv");
   if (adDiv == null)
       return;

   if (dhtml)
       pos = document.body.scrollTop;

   if (pos == oldAdPosition)
       adDiv.style.top = document.body.scrollTop + adTopOffset;

   oldAdPosition = pos;

   setTimeout('KeepAdFixed()', 250);
}


// --------------------------------------------------------------------------------------
// Debugging code

function alwaysTrue()
{
   return true;
}

function alwaysFalse()
{
   return false;
}

function Debug(message)
{
   window.status = message;
}

function Assert(condition, message)
{
   if (!condition)
       Debug(message);
}

// --------------------------------------------------------------------------------------


function InitializeNavigation()
{
   ////////////////////////////////////
   // menu system
   mnu.Init();

   var mnuHome = new SubMenu();
    mnuHome.AddItem("Home", "/");
    mnuHome.AddSeperator();
    //mnuHome.AddItem("Message Board", "/forum/", true);
    mnuHome.AddItem("Search", "/misc/search.html", true);
    mnuHome.AddItem("Sitemap", "/misc/sitemap.html");
    mnuHome.AddItem("Impressum / Legal Issues", "/misc/legal.html");
    mnuHome.AddItem("Website Internals", "/misc/technical.html");
    mnuHome.AddSeperator();
    mnuHome.AddItem("maxtive.<b>NET</b>", "http://www.maxtive.net");
   mnu.AddSubMenu(mnuHome);

   var mnuStudies = new SubMenu();
    mnuStudies.AddItem("Überblick", "/studies/");
    mnuStudies.AddSeperator("Vorlesungen");
    mnuStudies.Add('</table>'+
                   '<table cellspacing="0" cellpadding="0"><tr><td width="155" valign="top">'+
                    '<table cellspacing="0" cellpadding="0" width="100%">');

    mnuStudies.AddItem("Benutzerschnittstellen", "/studies/benutzerschnittstellen.html");
    mnuStudies.AddItem("Betriebssysteme", "/studies/betriebssysteme.html");
    mnuStudies.AddItem("Computergrafik", "/studies/grafik.html", true);
    mnuStudies.AddItem("Datenbanken", "/studies/datenbanken.html");
    mnuStudies.AddItem("Kommunikationssysteme", "/studies/netzwerke.html");
    mnuStudies.AddItem("Mathematik", "/studies/math.html", true);
    mnuStudies.AddItem("Softwarebasistechnologien", "/studies/basistech.html");
    mnuStudies.AddItem("Softwarebauelemente", "/studies/bauelemente.html");
    mnuStudies.AddItem("Technische Informatik", "/studies/techinf.html", true);

    mnuStudies.Add('</table></td>'+
                   '<td width="180" valign="top"><table cellspacing="0" cellpadding="0" width="100%">');
    mnuStudies.AddItem("CMMI und Softwareprozesse", "/studies/cmmi.html");
    mnuStudies.AddItem("CORBA Component Model", "/studies/corba.html");
    mnuStudies.AddItem("ERP-Systeme", "/studies/erp.html");
    mnuStudies.AddItem("Geoinformationssysteme", "/studies/gis.html");
    mnuStudies.AddItem("Performance Evaluation", "/studies/performance.html");
    mnuStudies.AddItem("Statistische Datenanalyse", "/studies/statistik.html");
    mnuStudies.AddItem("Visualisierung", "/studies/visualisierung.html", true);

    mnuStudies.Add('</table></td>'+
                   '<td width="185" valign="top"><table cellspacing="0" cellpadding="0" width="100%">');
    mnuStudies.AddItem("Advanced Image Synthesis" /* Techniques */, "/studies/raytracing.html");
    mnuStudies.AddItem("Building Intelligent Agents", "/studies/agents.html", true);
    mnuStudies.AddItem("Digital Graphics", "/studies/photoshop.html");
    mnuStudies.AddItem("Game Programming", "/studies/games.html", true);
    mnuStudies.AddItem("Object-Oriented Modelling", "/studies/oom.html");
    mnuStudies.Add( '</table></td></tr>'+
                   '</table>'+
                   '<table cellspacing="0" cellpadding="0" width="100%">');

    mnuStudies.AddSeperator("Seminare");
    mnuStudies.Add('</table>'+
                   '<table cellspacing="0" cellpadding="0"><tr><td width="155" valign="top">'+
                    '<table cellspacing="0" cellpadding="0" width="100%">');
    mnuStudies.AddItem("Anwendungsanalyse", "/studies/diverse.html#Anwendungsanalyse");
    mnuStudies.AddItem("Bachelorprojektvorbereitung", "/studies/diverse.html#Bachelorseminar");
    mnuStudies.AddItem("Computergrafik", "/studies/diverse.html#Computergrafik");
    mnuStudies.AddItem("Turing Award Lectures", "/studies/diverse.html#TuringAward");
    mnuStudies.Add('</table></td>'+
                   '<td width="180" valign="top"><table width="100%" cellspacing="0" cellpadding="0">');
    mnuStudies.AddItem("OpenGL Shading Language", "/studies/shader.html", true);
    mnuStudies.AddItem("Enterprise Appl. Integration", "/studies/diverse.html#EAI");
    mnuStudies.AddItem("UniCert III/2 English", "/studies/diverse.html#UniCert");
    mnuStudies.Add('</table></td>'+
                   '<td width="185" valign="top"><table cellspacing="0" cellpadding="0" width="100%">');
    mnuStudies.AddItem("Advanced Data Communications", "/studies/internet.html");
    mnuStudies.Add( '</table></td></tr>'+
                   '</table>'+
                   '<table cellspacing="0" cellpadding="0" width="100%">');

    mnuStudies.AddSeperator();
    mnuStudies.Add('</table>'+
                   '<table cellspacing="0" cellpadding="0"><tr><td width="155" valign="top">'+
                    '<table cellspacing="0" cellpadding="0" width="100%">');
    mnuStudies.AddItem("Bachelorprojekt", "/studies/projekte.html#bachelor");
    mnuStudies.Add('</table></td><td width="180" valign="top">'+
                   '<table cellspacing="0" cellpadding="0" width="100%">');
    mnuStudies.AddItem("Master's Thesis", "/studies/projekte.html#master");
    mnuStudies.Add('</table>'+
                   '</td><td></td></tr></table>'+
                   '<table cellspacing="0" cellpadding="0" width="100%">');
   mnu.AddSubMenu(mnuStudies);

   var mnuProgramming = new SubMenu();
    mnuProgramming.AddItem("Overview", "/programming/");
    mnuProgramming.AddSeperator();
    mnuProgramming.AddItem("Real-time Sunshine Calculator", "http://sunshine.stephan-brumme.com");
    mnuProgramming.AddItem("Real-time Moon Calculator", "http://moon.stephan-brumme.com");
    mnuProgramming.AddItem("The Bit Twiddler", "http://bits.stephan-brumme.com");
    mnuProgramming.AddItem("Code Archive", "http://code.stephan-brumme.com");
    mnuProgramming.AddSeperator();
    mnuProgramming.AddItem("CD-AutoRun Creator", "/programming/autorun.html");
    mnuProgramming.AddItem("ActiveX OpenGL Demo", "/download/grafik/ActiveXOpenGL.html");
    mnuProgramming.AddItem("Joole", "/programming/Joole/", true);
    mnuProgramming.AddItem('LieMachine', "/programming/Joole/LieMachine.html", false, true);
    mnuProgramming.AddItem('Geldscheintester (für DM)', "/programming/Geldscheintester/", false, true);
    mnuProgramming.AddSeperator();
    mnuProgramming.AddItem("maxtive.<b>NET</b>", "http://www.maxtive.net");
   mnu.AddSubMenu(mnuProgramming);

   var mnuGames = new SubMenu();
    mnuGames.AddItem("Overview", "/games/");
    mnuGames.AddSeperator("Non-Computer");
    mnuGames.AddItem("Schach", "/chess/", false, true);
    mnuGames.AddSeperator("Computer");
    mnuGames.AddItem("Blox", "/games/dosgames.html#Blox");
    mnuGames.AddItem("Twister", "/games/dosgames.html#Twister");
   mnu.AddSubMenu(mnuGames);

   var mnuLinks = new SubMenu();
    mnuLinks.AddItem("Overview", "/links/");
    mnuLinks.AddSeperator();
    mnuLinks.AddItem("The Useful Classics", "/links/#classics");
    mnuLinks.AddItem("They Survived The Internet, Too", "/links/#friends");
    mnuLinks.AddItem("Lets Code The World", "/links/#coding");
    mnuLinks.AddItem("Where to hang around", "/links/#hangout");
    mnuLinks.AddItem("The Internet Re-Wired", "/links/#net");
    mnuLinks.AddItem("Working 24/7", "/links/#work");
   mnu.AddSubMenu(mnuLinks);

   var mnuAboutMe = new SubMenu();
    mnuAboutMe.AddItem("Curriculum Vitae", "/aboutme/vitae.html");
    mnuAboutMe.AddItem("Publications", "/aboutme/publications.html");
    // mnuAboutMe.AddItem("About Me", "/aboutme/");
   mnu.AddSubMenu(mnuAboutMe);

   var mnuMail = new SubMenu();
    mnuMail.AddItem("Web eMail", "/misc/email.html", true);
    mnuMail.AddItem("Your eMail Client", "mailto:www@stephan-brumme.com");
   mnu.AddSubMenu(mnuMail);
   ////////////////////////////////////


   // capture mouse
   document.onmousemove = MS_MouseMove;

   // default: no status text (overridden by file hyperlinks)
   window.defaultStatus = " ";
   window.status = " ";

   // block errors
   window.onerror = alwaysTrue;

   // prevent users from selecting text or using drag'n'drop
   document.onselectstart = alwaysFalse;
   document.ondragstart   = alwaysFalse;

   //KeepAdFixed();
}


// called when page was completely loaded (incl. all pictures)
function InitPage()
{
   ShowBrowser();
   ShowLoadingTime();
}
