<!--
/*****************************************************************************
 >> Rename to menu.html and reload for short informations.
 >> Umbenennen in menu.html und neu laden fuer kurze Informationen.
*****************************************************************************/

/*****************************************************************************
 (c) M.Boerger: mailto:marcus.boerger@post.rwth-aachen.de (p) 1999

 ! It is not allowed to change any instance of my email adress or name.
 ! Es ist nicht gestattet meine EMail Adresse oder Namen zu aendern.

 See Copyright-Info and Documentation
 Beachten Sie Copyright-Info und Dokumentation

 http://www.marcus-boerger.de/js/DynamicJavaScript.html#menu.js

 Strip of rest of documentation and rename to menu.js in order to shorten
 this file. It is not permitted to remove this block of dokumentation.

 Entfernen Sie den Rest der Dokumentation und benennen sie die Datei in
 menu.js um sie zu kuerzen. Es ist verboten diesen Block zu entfernen.
*******************************************************************************/

/* Documentation: 20%
-->

<h3>JavaScript (v1.1):</h3>
<h1><a href="http://www.marcus-boerger.de/js/DynamicJavaScript.html#menu.js"><em>js/menu.js</em></a></h1>
<h3>v1.1&nbsp;(04.12.1999)</h3>
<p></p><font SIZE="+1">&copy;</font> <a href="mailto:marcus.boerger@post.rwth-aachen.de">M.B&ouml;rger</a></p>
<a href="http://www.marcus-boerger.de/js/DynamicJavaScript.html">See Copyright-Info at / Beachten Sie Copyright-Info in Seite:<br />
http://www.marcus-boerger.de/js/DynamicJavaScript.html</a>
<p></p>
<h3>Version History:</h3>
<pre>
v1.0    25.01.1999  First Version

v1.0.1  30.01.1999  Changed Cookie Layot.
                    Length of cookies checked.
                    Read cookie by name compared based on maximum length for test first then by order.

v1.0.2  01.02.1999  MenuXxx_Key functions use new sCookieKey, cookieGet (may be used for databases and shorter Cookies).
                    Changed cookie layout (shorter: does not use cookiedevidesign between length and name).
                    Corrected expiration of cookie

v1.0.3  02.02.1999  Multiple cookies for oversized menues.
                    Extracted debugger.
                    New sEvalLate property for entry.
                    Fixed error writing undefined in ALINK Attribut of BODY Tag.

v1.0.4  13.10.1999  Set path and version of cookie.

v1.1    04.12.1999  Fix Problems with non whysiwyg browsers (all but netscape)

v1.1.1  19.03.2000  Mozilla works better with "whysiwig://". Without changing the menu results in displaying the frame-page.

v1.2    21.03.2000  Changed to XML. If Old Style is needed change doc.bXML property of menu to false.
                    Menu now uses tables. If Old Style is needed change bTable property of each entry to false.
                         This is used if text bloack should be displayed near an icon.
                         Other related new properties:
                         bTableImgColumn: A extra column for the image. (default=true)
                                          If set to true the text aligns to the right side of the image.
                                          If set to false the image is rendered with the text.
                    Fixup error: Writing StatusLine.

v1.2.1  25.03.2000  Fixup error: JavaScript: Nested Command in Line 2. Changed "/""*" to "/""/"

v1.2.2  28.03.2000  Fixup error: +If an entry had a target set then image-click did not work correctly
                                 +If changing sImageRoot the images are pre-loaded from wrong location

v1.2.3  03.04.2000  If iCookiesEnabled is set to false in initialisation it is temporarliy set to 2.

v1.2.4  01.05.2000  Changed Cookie from delimReplace/Restore to escape/unescape functions

v1.2.5  13.02.2002  Added sImgBaseUrl to support different base-directories
                    Corrected Status/DefaultStatus behaviour
                    When Status/DefaultStatus will receive html entities some of those are converted.
                    Now support for NS4, NS6, IE
                    XHTML corrections

todo:               Use sort for cookieinfo to write sorted cookie (fasten read), is sorting of indexes possible?
                    Cookie endsign
</pre><!-- */
/************************************************************************* -->
<h3>VARIABLES</h3>
<dl>
<dt>menuMain</dt>
<dd>Normally there is only one menu and this variable stores the menuinformation.
If not you have to keep track of it in your own variable. Therefore you then have
to declare your own variable and set the relation to it with the sEval parameter
of the <em><a href="#MenuInit">MenuInit</a></em> functioncall. This is done
automatically for the default relation <em>&quot;parent&quot;</em> and for
the varname <em>&quot;menuMain&quot;</em>. Example: <br>Nested frames and the
script is loaded on level 2 whereas the actual menu is on level 4.
<p></p>
Normalerweise ist nur ein Men&uuml; vorhanden. Wenn dies nicht der Fall ist, so
mu&szlig; eine eigene <em>menu</em> Variable erstellt werden und im Aufruf von
<em><a href="#MenuInit">MenuInit</a></em> mu&szlig; dann die Relation &uuml;bergeben
werden. Der Standard hierf&uuml;r ist <em>&quot;parent&quot;</em> f&uuml;r die
Relation und <em>&quot;menuMain&quot;</em> f&uuml;r den Variablennamen.
Beispiel:<br>Verschachtelte Frames, wobei das Script auf Ebene 2 geladen wird
und das aktuelle Men&uuml; auf Ebene 4.
<p></p>
<PRE>
var menu4;

<a href="#MenuInit">MenuInit</a>( &lt;framerelation&gt;,
          &quot;Name&quot;,
          &lt;cookies&gt;,
          &quot;this.sRelationUp = 'parent.parent'; this.sVarName = 'menu4'&quot;,
          &lt;entries&gt;);
</PRE>
</dl>
<!-- ************************************************************************/

var menuMain = null;
var bClearStatus = false;
var sNewStatus = '';
var tStatus = null;

/************************************************************************* -->
<h3>CONSTANTS</h3>
<!-- ************************************************************************/

// entry.iType      --><PRE>
var iMT_TOP = 0; // Level 1
var iMT_MEN = 1; // Level 2
var iMT_REG = 2; // Level 3
var iMT_SUB = 3; // Level 4</PRE><!--

// global buttons ( negative row-index)
var iGI_ABOUT   = -1;
var iGI_COOKIE  = -2;
var cCookieDevide = "*"
var cCookieDevideRepl = "_"
var cCookieDelimR  = '~'; // replacement for "cookie delimiter ;"

/****************************************************************************/
// FUNCTIONS: Accessing the Object window.status

function AmpDecode( sText) {
    sText = sText.replace(/&Auml;/,String.fromCharCode(196));
    sText = sText.replace(/&Ouml;/,String.fromCharCode(214));
    sText = sText.replace(/&Uuml;/,String.fromCharCode(220));
    sText = sText.replace(/&auml;/,String.fromCharCode(228));
    sText = sText.replace(/&ouml;/,String.fromCharCode(246));
    sText = sText.replace(/&uuml;/,String.fromCharCode(252));
    sText = sText.replace(/&szlig;/,String.fromCharCode(223));
    sText = sText.replace(/&quot;/,'"');
    sText = sText.replace(/&#39;/,String.fromCharCode(39));
    sText = sText.replace(/&acute;/,String.fromCharCode(180));
    return sText;
}

function StatusWrite( sDefaultStatus) {
    sDefaultStatus = AmpDecode(sDefaultStatus);
    window.defaultStatus = sDefaultStatus;
    if ( !bClearStatus && sNewStatus != null) {
        window.status = sNewStatus;
    } else {
        window.status = sDefaultStatus;
        //tStatus = setTimeout( "StatusWrite( '" + sDefaultStatus + "');", 10);
    }
}

function StatusClear( sDefaultStatus) {
    bClearStatus = true;
    StatusWrite( sDefaultStatus);
}

function StatusClear() {
    bClearStatus = true;
    StatusWrite( window.defaultStatus);
}

function StatusSet( sStatus, sDefaultStatus) {
    sStatus = AmpDecode(sStatus);
    sDefaultStatus = AmpDecode(sDefaultStatus);
    bClearStatus = false;
    sNewStatus = sStatus;
    if ( tStatus != null) clearTimeout( tStatus);
    window.defaultStatus = sDefaultStatus;
    tStatus = setTimeout( "StatusWrite( '" + sDefaultStatus + "');", 10);
}

/****************************************************************************/
// OBJECT: menuinfo

function menuinfo() {
    this.sVersion    = 'v1.2.5';
    this.sDate       = '13.02.2002';
    this.sHtmlVersion= this.sVersion + '&nbsp;' + this.sDate;
    this.sDJSRef     = 'http://www.marcus-boerger.de/js/';
    this.sCopyRef    = this.sDJSRef;
    this.sHelpRef    = this.sDJSRef + '#menu.js';
    this.sName       = 'menu.js ' + this.sVersion;
    this.sCopy       = this.sName + ' &copy;&nbsp;M.&nbsp;Boerger  -  ' + this.sHelpRef;
}

var menuinfo = new menuinfo();

/****************************************************************************/
// OBJECT: img ( one single image)

function strcat( s1, s2) {
    if ( s1 == null) return s2;
    if ( s2 == null) return s1;
    return s1 + s2;
}

function imgSourceGet( sRoot) {
    if ( this.sName >= "") {
//        if ( this.sName.charAt( 0) == '/')
    	return strcat( sRoot, this.sName);
    }
    return this.sName;
}

function imgLoadImage( sRoot) {
    if ( this.image == null) this.image = new Image()
    this.image.src = this.sourceGet( sRoot);
}

function img( sDir, sName, sType) {
    // methods
    this.loadImage = imgLoadImage;
    this.sourceGet = imgSourceGet;
    // properties
    this.sName     = strcat( strcat( sDir, sName), sType);
    this.image     = null;
    return this;
}

/****************************************************************************/
// OBJECT: imgopen ( array img(2) 1:default, 2:open

function imgmarkLoad( sRoot) {
    this[1].loadImage( sRoot);
    this[2].loadImage( sRoot);
}

function imgmark( sDir, sName1, sName2, sType) {
    // methods
    this.load = imgmarkLoad;
    // properties
    this.length = 2;
    this[1] = new img( sDir, sName1, sType);
    this[2] = new img( sDir, sName2, sType);
    return this;
}

/****************************************************************************/
// OBJECT: imgmark ( array imgopen(2) 1:unmarked, 2:marked

function imgopenLoad( sRoot) {
    this[1].load( sRoot);
    this[2].load( sRoot);
}

function imgopen( sDir, sName1, sName2, sOpen, sType) {
    // methods
    this.load = imgopenLoad;
    // properties
    this.length = 2;
    this[1] = new imgmark( sDir, sName1, strcat( sName1, sOpen), sType);
    this[2] = new imgmark( sDir, sName2, strcat( sName2, sOpen), sType);
    return this;
}

/****************************************************************************/
// OBJECT: imgtype ( array imgmark(4) 1:shelf, 2:book, 3:register, 4:document

function imgtypeLoad( sRoot) {
    this[1].load( sRoot);
    this[2].load( sRoot);
    this[3].load( sRoot);
    this[4].load( sRoot);
}

function imgtype( sDir, sName1, sName2, sName3, sName4, sOpen, sMark, sType) {
    // methods
    this.load = imgtypeLoad;
    // properties
    this.length = 4;
    this[1] = new imgopen( sDir, sName1, strcat( sName1, sOpen) ,sMark, sType);
    this[2] = new imgopen( sDir, sName2, strcat( sName2, sOpen) ,sMark, sType);
    this[3] = new imgopen( sDir, sName3, strcat( sName3, sOpen) ,sMark, sType);
    this[4] = new imgopen( sDir, sName4, strcat( sName4, sOpen) ,sMark, sType);
    return this;
}

/****************************************************************************/
// OBJECT: entry

function entryHtmlWrite( sText) {
    this.menu.doc.htmlWrite( sText);
}

function entryHtmlWriteln( sText) {
    this.menu.doc.htmlWriteln( sText);
}

function entryExpandAnchor( sAnchor) {
    var l = this.menu.sRoot.length;

    if ( sAnchor != "") {
        if ( this.menu.sRoot == null) {
            if ( sAnchor.charAt( 0) == '/' && this.menu.window.location.href.indexOf( "file") >= 0) {
                sAnchor = sAnchor.substring( 1, sAnchor.length);
            }
        } else if ( sAnchor.charAt( 0) == '/') {
            if ( this.menu.window.location.href.indexOf( "file") >= 0 && this.menu.sRoot == "") {
                sAnchor = sAnchor.substring( 1, sAnchor.length);
            } else if ( this.menu.sRoot.charAt( l - 1) == '/') {
                sAnchor = this.menu.sRoot.substring( 0, l-1) + sAnchor;
            } else {
            	sAnchor = this.menu.sRoot + sAnchor;
            }
    	}
    }
    return sAnchor;
}

function entryImageChange() {
    this.menu.window.document.images['IDX'+this.iIndex].src = this.imgInfos[(this.iOpenSub > 0) ? 2 : 1][this.bMarked ? 2 : 1].image.src;
}

function entryGetTabAttr() {
    return ' border="0" cellspacing="0" cellpadding="0" valign="top"';
}

function entryGetTabAttrText() {
    return '';
}

function entryGetName() {
    return this.sName;
}

function entryHtmlShow( bJavaScript) {
    var sLine = '', sLineEnd = '', sMouseOver, sMouseOut, sMouse;

    if ( this.iIndex == 0) {
        this.menu.iGlobalIndex =0;
    }
    sLine += this.menu.globalButton( bJavaScript);
    if ( this.iIndex != 0 && this.iType == iMT_TOP) {
        sLine += this.menu.globalButton();
        sLine += '<br clear=all />';
    }
    if ( bJavaScript) {
        sMouseOver = ' onMouseOver="' + this.menu.sRelationUp + '.' + this.menu.sVarName + '.mouseOver(' + this.iIndex + ');" ';
        sMouseOut  = ' onMouseOut="'  + this.menu.sRelationUp + '.' + this.menu.sVarName + '.mouseOut('  + this.iIndex + ');"';
        sMouse = sMouseOver+sMouseOut;
        sLine += '<a name="' + this.iIndex + '"></a>';//&nbsp;</a>';
    } else {
        sMouse = '';
        sLine += '&nbsp;';
    }
    if ( this.bTable) {
        sLine += '<table'+this.getTabAttr()+' summary="CD"><tr><td>';
    }
    if ( this.sURL != null) sAnchor = '<a href="' + this.expandAnchor( this.sURL) + '" target="' + this.sTarget + '"'+sMouse+'>';
    sLine += '<img src="' + this.menu.imgBlank.sourceGet( this.menu.sImageRoot) + '" alt="" border="0" hspace="0" vspace="0" width="' + (this.iDepth*20+1) + '" height="17" align="middle" />';
    if ( this.bTable) {
        sLine += '</td><td';
        if ( !this.bTableImgColumn) sLine += this.getTabAttrText();
        sLine += '>';
    }
/*    if ( !bJavaScript) {
        if ( this.sURL != null) {
            sLine += sAnchor;
            sLineEnd = '</a>';
        }
    } else {
    }*/
    if ( bJavaScript) {
        // objectreference
        sLine += '<a href="javascript:' + this.menu.sRelationUp + '.' + this.menu.sVarName + '.documentClick(' + this.iIndex + ');" ' + sMouse+ ' target="_self">';// + this.sTarget + '">';
    } else {
        if ( this.sURL != null) {
            sLine += sAnchor;
            sLineEnd = '</a>';
        }
    }
    sLine += '<img src="' + this.imgInfos[(this.iOpenSub > 0) ? 2 : 1][(this.bMarked) ? 2 : 1].sourceGet( this.menu.sImageRoot) + '" alt="' + this.sInfo + '" ' + this.sImgParam + ' name="IDX' + this.iIndex + '" />';
    if ( bJavaScript) {
        sLine += '</a>';
        if ( this.bTable & this.bTableImgColumn) sLine += '</td><td'+this.getTabAttrText()+'>';
        if ( this.sURL != null) {
            sLine += sAnchor;
            sLineEnd = '</a>';
        }
    }
    if ( this.iSize != this.menu.iBaseFontSize) {
        sLine += '<font size="' + this.iSize + '">';
        sLineEnd = '</font>' + sLineEnd;
    }
    sLine += this.getName();
    sLine += sLineEnd;
    if ( this.bTable) {
        sLine += '</td></tr></table>';
    } else {
        sLine += '<br />';
    }
    this.htmlWriteln( sLine);
}

function entryForEachOpen( sEval) {
    eval( sEval);
    if ( this.entrySub != null && this.iOpenSub > 0) this.entrySub.forEachOpen( sEval);
    if ( this.entryNext != null) this.entryNext.forEachOpen( sEval);
}

function entryForEach( sEval) {
    eval( sEval);
    if ( this.entrySub != null) this.entrySub.forEach( sEval);
    if ( this.entryNext != null) this.entryNext.forEach( sEval);
}

function entryIndexGet( iIndex) {
    var entry = null;

    if ( iIndex == this.iIndex) return this;
    if ( this.entrySub != null) entry = this.entrySub.indexGet( iIndex);
    if ( this.entryNext != null && entry == null) entry = this.entryNext.indexGet( iIndex);
    return entry;
}

function entryDefaultCookieKeyGet() {
    var sCookieKey = (this.sCookieKey == null) ? this.sName : this.sCookieKey;
    if ( sCookieKey.length == 0) sCookieKey = '@';
    return sCookieKey.substring( 0, Math.min(sCookieKey.length,this.menu.iCookieCmpLen));
}

function entryReadCookieInfo() {
    var cookieinfo;
    var sCookieKey = this.cookieKeyGet();
    cookieinfo = this.menu.cookieinfo[sCookieKey];
    if ( cookieinfo != null) {
        this.bMarked  = cookieinfo.bMarked;
        this.iOpenSub = cookieinfo.iOpenSub;
        //this.menu.cookieinfo[sCookieKey].next != null) { -> next unknown while writing cookie
        this.menu.cookieinfo[sCookieKey] = this.menu.cookieinfo[sCookieKey].next;
    }
}

function entryWriteCookieInfo() {
    this.menu.cookieinfo.add( this.cookieKeyGet(), this.bMarked, this.iOpenSub);
}

function entryInitImages() {
    for ( o=1; o<3; o++) {
        for ( m=1; m<3; m++) {
            if ( this.imgInfos[o][m].sName == null) {
                this.imgInfos[o][m] = this.menu.imgInfos[this.iType+1][o][m];
            } else if ( this.imgInfos[o][m].image == null) {
                this.imgInfos[o][m].loadImage( this.menu.sImageRoot);//xxx
            }
        }
    }
}

function entryInitialise( iIndex, iDepth, menu) {
    // initialisation for automatic properties from menu
    this.iIndex = ++iIndex;
    this.iDepth = iDepth;
    this.menu = menu;
    if ( this.sImgParam == null) this.sImgParam = menu.sImgParam;
    if ( this.iSize == 0) this.iSize = this.menu.iBaseFontSize;
    menu.iDepthMax  = Math.max( menu.iDepthMax, iDepth);
    this.iDepthMax  = this.iDepth;
    this.iDepthMaxN = this.iDepth;
    this.initImages();
    if ( this.entrySub != null) {
        // to show entries for first top-shelf on same column as shelf: +((iIndex==0)?0:1) instead of +1
        // to show entries of register on same column as shelf: +((this.iType==iMT_REG)?0:1) instead of +1
        this.entrySub.entryUp = this;
        iIndex = this.entrySub.initialise( iIndex, iDepth+1, menu);
        this.iDepthMax = Math.max( this.iDepthMax, this.entrySub.iDepthMax);
        this.iDepthMax = Math.max( this.iDepthMax, this.entrySub.iDepthMaxN);
    }
    if ( this.entryNext != null) {
        this.entryNext.entryUp = this.entryUp;
        iIndex = this.entryNext.initialise( iIndex, iDepth, menu);
        this.iDepthMaxN = Math.max( this.iDepthMaxN, this.entryNext.iDepthMaxN);
    }
    this.iDepthMaxN = Math.max( this.iDepthMax, this.iDepthMaxN);
    if ( this.sEvalLate != null) eval( this.sEvalLate);
    return iIndex;
}

function entry( iType, sName, sURL, sTarget, sInfo, bOpenSub, entrySub, entryNext, sEval, fCookieKeyGet, sCookieKey, oUser1, oUser2) {
    // methods
    this.htmlWrite      = entryHtmlWrite;
    this.htmlWriteln    = entryHtmlWriteln;
    this.htmlShow       = entryHtmlShow;
    this.initImages     = entryInitImages;
    this.initialise     = entryInitialise;  // called in menu constructor after calling eval
    this.indexGet       = entryIndexGet;
    this.forEach        = entryForEach;
    this.forEachOpen    = entryForEachOpen;
    this.expandAnchor   = entryExpandAnchor;
    this.readCookieInfo = entryReadCookieInfo;
    this.writeCookieInfo= entryWriteCookieInfo;
    this.imageChange    = entryImageChange;
    this.getName        = entryGetName;
    this.getTabAttr     = entryGetTabAttr;
    this.getTabAttrText = entryGetTabAttrText;
    // properties
    this.iType          = iType;
    this.sName          = sName;
    this.sURL           = sURL;
    this.sTarget        = (sTarget != null) ? sTarget : '_self';
    this.sInfo          = sInfo;
    this.entrySub       = entrySub;
    this.entryNext      = entryNext;
    this.iOpenSub       = (bOpenSub) ? 1 : 0;
    this.cookieKeyGet   = fCookieKeyGet != null ? fCookieKeyGet : entryDefaultCookieKeyGet;
    this.sCookieKey     = sCookieKey; // if null entryDefaultKeyCmp takes sName with entryDefaultCookieKeyGet
    this.oUser1         = oUser1;
    this.oUser2         = oUser2;
    this.sEvalLate      = null;
    // automatic properties: defined in entryInitialise called by menu Constructor
    this.bMarked        = false;
    this.imgInfos       = new imgopen( null, null, null, null);
    this.imgParam       = 0;
    this.iSize          = 0;
    this.entryUp        = null;
    // private properties
    this.iIndex         = -1;
    this.iDepth         = 0;
    this.iDepthMax      = 0;
    this.iDepthMaxN     = 0;
    this.bTable         = true;
    this.bTableImgColumn= true;
    this.menu           = null;
    if ( sEval != null) eval( sEval);
    return this;
}

/****************************************************************************/
// OBJECT: header

function headerHtmlWrite( sText) {
    this.doc.htmlWrite( sText);
}

function headerHtmlWriteln( sText) {
    this.doc.htmlWriteln( sText);
}

function headerWrite() {
    this.doc.strEmptyTag = ' /';
    if ( this.doc.bXML) {
        this.htmlWriteln( '<'+'?xml version="1.0" encoding="ISO-8859-1"?'+'>');
        this.htmlWriteln( '<'+'!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">');
        this.htmlWriteln( '<html xmlns="http://www.w3.org/1999/xhtml" lang="de">');
    } else {
        this.htmlWriteln( '<'+'!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 4.01 Transitional//EN">');
        this.htmlWriteln( '<html>');
        this.docstrEmptyTag = '';
    }
    this.htmlWriteln( '<head>');
    this.htmlWriteln( '  <title>' + this.doc.sTitle + '</title>');
    this.htmlWriteln( '  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"' + this.doc.strEmptyTag + '>');
    this.htmlWriteln( '  <meta name="Author" content="' + menuinfo.sCopy + '"' + this.doc.strEmptyTag + '>');
    this.htmlWriteln( '  <meta name="DESCRIPTION" content="' + this.doc.sTitle + '"' + this.doc.strEmptyTag + '>');
    if ( this.sRobots != null) this.htmlWriteln( '  <meta name="ROBOTS" content="' + this.sRobots + '"' + this.doc.strEmptyTag + '>');
    if ( this.sKeywords != null) this.htmlWriteln( '  <meta name="KEYWORDS" content="' + this.sKeywords + '"' + this.doc.strEmptyTag + '>');
    this.doc.extendHeader();
    if (this.doc.bXML) {
        this.htmlWriteln( '<style type="text/css">');
        this.htmlWriteln( '<!--');
        this.htmlWriteln( 'body {');
        this.htmlWriteln( '  background-color: this.doc.sBgcolor;');
        if (this.doc.sBackground.length) this.htmlWriteln('  background-image:'+this.doc.sBackground+';');
        this.htmlWriteln( '}');
        this.htmlWriteln( 'a,a:link {');
        this.htmlWriteln( '  text-decoration: none;');
        this.htmlWriteln( '  color: #0000ff;');
        this.htmlWriteln( '}');
        this.htmlWriteln( 'a:active,a:visited {');
        this.htmlWriteln( '  text-decoration: none;');
        this.htmlWriteln( '  color: #000080;');
        this.htmlWriteln( '}');
        this.htmlWriteln( 'a:hover {');
        this.htmlWriteln( '  text-decoration: underline;');
        this.htmlWriteln( '  color: #008000;');
        this.htmlWriteln( '  background-color: #FFFFE1;');
        this.htmlWriteln( '}');
        this.htmlWriteln( '-->');
        this.htmlWriteln( '</style>');
    }
    this.htmlWriteln( '</head>');
    if (this.doc.bXML) {
        this.htmlWriteln( '<body' + this.doc.sBodyEx + '>');
    } else {
        this.htmlWriteln( '<body bgcolor="'+this.doc.sBgcolor+(this.doc.sBackground.length?'" background="'+this.doc.sBackground+'"':'')+'" text="'+this.doc.sText+'" link="'+this.doc.sLink+'" vlink="'+this.doc.sVlink+'" alink="'+this.doc.sAlink+'" leftmargin="'+this.doc.iMarginLeft+'" topmargin="'+this.doc.iMarginTop+'" marginwidth="'+this.doc.iMarginLeft+'" marginheight="'+this.doc.iMarginTop+'"' + this.doc.sBodyEx + '>');
    }
//    this.htmlWrite( '<basefont size="' + this.doc.iBaseFontSize + '"');
//    if ( this.doc.sBaseFontFace != null) this.htmlWrite( ' face="' + this.doc.sBaseFontFace + '"');
//    this.htmlWriteln( '>');
}

function headerNoAction() {
}


function header( doc) {
    // methods
    this.extendHeader  = headerNoAction; // method writes between last <HEAD>... and </HEAD>
    this.write         = headerWrite; // method writes between Menu and </BODY>
    this.htmlWrite     = headerHtmlWrite;
    this.htmlWriteln   = headerHtmlWriteln;
    // properties
    this.doc           = doc;
    this.sRobots       = null; // Robot META-Information
    this.sKeywords     = null; // Keyword META-Information
    return this;
}

/****************************************************************************/
// OBJECT: header

function docHtmlWrite( sText) {
    this.window.document.write( sText);
}

function docHtmlWriteln( sText) {
    this.window.document.writeln( sText);
}

function docClear() {
    this.window.document.clear();
    this.window.document.open( 'text/html');
}

function docHtmlHeader() {
    this.header         = new header( this);
    this.header.write();
}

function docHtmlBody() {
    // Empty Page
}

function docHtmlFooter() {
    this.htmlWriteln( '</body>');
    this.htmlWriteln( '</html>');
    this.window.document.close();
}

function docRedraw() {
    this.clear();
    this.htmlHeader();
    this.htmlBody();
    this.htmlFooter();
}

function doc( window, sTitle, user) {
    // methods
    this.htmlWrite      = docHtmlWrite;
    this.htmlWriteln    = docHtmlWriteln;
    this.clear          = docClear;
    this.htmlHeader     = docHtmlHeader;
    this.htmlBody       = docHtmlBody;    // overwrite to create non emptypages
    this.htmlFooter     = docHtmlFooter;
    this.redraw         = docRedraw;
    // properties
    this.window         = window;
    this.bXML           = true;
    this.sTitle         = sTitle;
    this.user           = user;
    this.iBaseFontSize  = 4;
    this.sBaseFontFace  = null;
    this.sBgcolor       = "#FFFFFF";
    this.sText          = "#000000";
    this.sLink          = "#0000FF";
    this.sVlink         = "#FF0000";
    this.sAlink         = "#FF0000";
    this.sBodyEx        = ''; // Extension to <BODY ...>
    return this;
}

/****************************************************************************/
// OBJECT: entryinfo

function entryinfoGet() {
    var sCookieKey = this.sName;
    var sCookieLen = '' + sCookieKey.length;

    if ( sCookieLen.length < 2) sCookieLen = '0' + sCookieLen;
    return ((entryinfoNext.bMarked) ? '1' : '0') + (entryinfoNext.iOpenSub+0) + sCookieLen + sCookieKey;
}

function entryinfo( sName, bMarked, iOpenSub) {
    // methods
    this.get        = entryinfoGet;
    // properties
    this.sName      = sName;
    this.bMarked    = bMarked;
    this.iOpenSub   = iOpenSub;
    this.next       = null;
    this.sNetx      = null;
    return this;
}

/****************************************************************************/
// OBJECT: cookieinfo
// array-index is sName of entryinfo (fast search on array-indexes)
// simple concatenated list starts sFirst
// last entryinfo.sName stored in sLast for indexing last entryinfo
// while generating new entryinfo (this[this.sLast].sNext)

function cookieinfoGet() {
    var sCookie = '';
    var sNext;

    sNext = this.sFirst;
    while ( sNext != null) {
        entryinfoNext = this[sNext];
        sNext = entryinfoNext.sNext;
        do {
            sCookie += entryinfoNext.get();
            entryinfoNext = entryinfoNext.next;
        } while ( entryinfoNext != null);
    }
    return sCookie;
}

function cookieinfoAdd( sName, bMarked, iOpenSub) {
    var entryinfoNext;

    if ( this[sName] == null) {
        this.length++;
        this[sName] = new entryinfo( sName, bMarked, iOpenSub);
        if ( this.sFirst == null) this.sFirst = sName;
        if ( this.sLast != null) this[this.sLast].sNext = sName;
        this.sLast = sName;
    } else {
        entryinfoNext = this[sName];
        while ( entryinfoNext.next != null) {
            entryinfoNext = entryinfoNext.next;
        }
        entryinfoNext.next = new entryinfo( sName, bMarked, iOpenSub);
    }
}

function cookieinfoScan( sCookie, iCookieCmpLen) {
    while( sCookie.length > 4) {
        bMarked  = (parseInt( sCookie.substring( 0, 1), 10)==0) ? false : true;
        iOpenSub = parseInt( sCookie.substring( 1, 2), 10);
        l = parseInt( sCookie.substring( 2, 4), 10);
        if ( isNaN(l)) return;
        if ( sCookie.length < l + 4) return;
        l = Math.min( l, sCookie.length-2);
        sl = Math.min(l,iCookieCmpLen);
        sName = sCookie.substring( 4, 4+sl);
        this.add( sName, bMarked, iOpenSub);
        sCookie = sCookie.substring( 4+l, sCookie.length);
    }
}

function cookieinfo() {
    // methods
    this.get    = cookieinfoGet;
    this.add    = cookieinfoAdd;
    this.scan   = cookieinfoScan ;
    // properties
    this.length = 0;
    this.sFirst = null;
    this.sLast  = null;
    return this;
}

/****************************************************************************/
// OBJECT: menu

function menuStatusSet( iIndex) {
    if ( iIndex < 0) {
        if      ( iIndex==iGI_ABOUT ) StatusSet( 'About ' + menuinfo.sName, this.doc.sTitle);
        else if ( iIndex==iGI_COOKIE) StatusSet( 'Cookie - Information', this.doc.sTitle);
        else this.statusClear();
    } else StatusSet( this.entryGet( iIndex).sInfo, this.doc.sTitle);
}

function menuStatusClear() {
    StatusClear( this.doc.sTitle);
}

function menu_doc_WriteHtmlBody() { // function of objecttype  doc
    // user set to menu
    bJavaScript = true;
    this.user.entry.forEachOpen( 'this.htmlShow( ' + bJavaScript + ');');
}

function menuGlobalButton( bJavaScript) {
    var sLine, sHREF, sImgSrc, sImgName, sAlternate;

    this.iGlobalIndex++;
    sHREF = menuinfo.sHelpRef;
    if ( this.iGlobalIndex == 1) {
        iIndex = iGI_ABOUT;
        sImgSrc     = this.imgHelp.sourceGet( this.sImageRoot);
        sAlternate  = menuinfo.sCopy;
        sImgName    = 'ABOUT';
    } else {
        if ( !bJavaScript) return '';
        if ( this.iGlobalIndex == 2) {
            iIndex      = iGI_COOKIE;
            sImgSrc     = this.imgCookies[this.iCookiesEnabled?1:2].sourceGet( this.sImageRoot);
            sAlternate  = 'Cookies';
            sImgName    = 'COOKIES';
        } else {
            return '';
        }
    }
    if ( bJavaScript) {
        sHREF   = 'javascript:' + this.sRelationUp + '.' + this.sVarName + '.documentClick(' + iIndex +  ');';
        sMouse  = ' onMouseOver="' + this.sRelationUp + '.' + this.sVarName + '.mouseOver(' + iIndex + ');" onMouseOut="' + this.sRelationUp + '.' + this.sVarName + '.mouseOut(' + iIndex + ');"';
        sTarget = '';//' target="_self"';
    } else {
        sMouse  = '';
        sTarget =  ' target="_blank"';
    }
    sLine  = '<a href="' + sHREF + '"' + sTarget + sMouse + '>';
    sLine += '<img src="' + sImgSrc + '" alt="' + sAlternate + '" border="0" hspace="0" vspace="0" width="17" height="17" align="right" name="' + sImgName + '" />';
    sLine += '</a>';
    return sLine;
}

function menuHtmlDocument( iIndex) {
    this.doc.redraw();
    this.statusSet( iIndex);
}

function menuEntryGet( iIndex) {
    return this.entry.indexGet( iIndex);
}

function menuDocumentChange( iIndex, bDoubleClick) {
    var entry;

    entry = this.entryGet( iIndex);
    if ( iIndex < 0) {
        if ( iIndex == iGI_ABOUT) {
            new aboutwindow( this);
        } else if ( iIndex == iGI_COOKIE) {
            if ( bDoubleClick) {
                this.cookieSet( !this.iCookiesEnabled); // only executed once because bCookieEnabled can only be true here or after next statement
                this.iCookiesEnabled = !this.iCookiesEnabled;
                this.window.document.images['COOKIES'].src = this.imgCookies[this.iCookiesEnabled ? 1 : 2].image.src;
            } else {
                new cookiewindow( this);
            }
        }
    } else if ( entry.iType == iMT_SUB || bDoubleClick) {
        entry.bMarked = !entry.bMarked;
        entry.imageChange();
    } else {
        entry.iOpenSub = (entry.iOpenSub+1) % ( 2 + 2*( entry.iDepth+1 < entry.iDepthMax));
        if ( entry.entrySub != null) {
            entry.entrySub.forEach( 'this.iOpenSub = ' + ((entry.iOpenSub % 2 == 0) ? entry.iOpenSub : 0) + ';');
        }
        if ( (entry.iType == iMT_TOP || entry.iType == iMT_MEN || entry.iType == iMT_REG) || bDoubleClick) this.htmlDocument( iIndex);
        // reload:
        // 1) Netscape
        //    document.URL contains the actual 'WYSIWYG' information
        //    append the index as target and then reload
        //    use location = instead of location.reload() last one would reload the parent document!
        // 2) others? no wysiwyg interface -> so reload
        if ( navigator.appName.toLowerCase().indexOf( "netscape")>=0 || navigator.appName.toLowerCase().indexOf( "mozilla")>=0) {
            //alert(this.window.document.location+'=>'+this.window.document.URL + '#' + iIndex);
            if (document.layers && !document.getElementById) {
              // Old Netscape 4 solution
              this.window.document.location = this.window.document.URL + '#' + iIndex;
            } else {
              // IE6 && NS6
              this.window.document.location.hash = '#' + iIndex;
            }
        } else {
            this.window.document.location.reload();
        }
    }
    this.statusSet( iIndex);
    this.cookieSet( this.iCookiesEnabled);
}

function menuSetLastClick( iIndex, tTime) {
    // called from mouseOver AND mouseOut AND documentClick
    // if this routine would clear the timeout, then mousemovement after clicking
    // would result in missing reaction
    //if ( this.timerLastClick != null) clearTimeout( this.timerLastClick);
    this.tLastClick = tTime; // must be executed before iLastClick = iIndex
    this.iLastClick = iIndex;
}

function menuMouseOver( iIndex) {
    this.setLastClick( -1);
    this.statusSet( iIndex);
}

function menuMouseOut( iIndex) {
    this.setLastClick( -1, (new Date()).getTime());
    this.statusClear();
}

function menuDocumentClick( iIndex) {
    var tTime;
    var bDoubleClick;

    if ( this.timerLastClick != null) clearTimeout( this.timerLastClick);
    tTime = (new Date()).getTime();
    if ( this.iLastClick == iIndex && tTime-this.tLastClick < this.tDoubleClick) {
        this.documentChange( iIndex, true);
    } else {
        this.setLastClick( iIndex, tTime);
        this.timerLastClick = setTimeout( this.sRelationUp + '.' + this.sVarName + '.documentChange( ' + iIndex + ', false);', this.tDoubleClick+10);
    }
}

function menuCookieGet() {
    var sComplete, sNext, sCookie, sNum, info;
    var bMore;
    var iNum;

    if ( this.iCookiesEnabled == 2) {
        this.iCookiesEnabled = false;
        return;
    }
    iNum = 0;
    sCookie = '';
    sComplete = parent.window.document.cookie;
    do {
        sNum = iNum.toString();
        i = sComplete.indexOf( this.sVarName + sNum);
        sNext = sComplete.substring( i+this.sVarName.length+sNum.length, sComplete.length);
        bMore = ( sNext.charAt(0) == '+') ? true : false;
        if ( (i = sNext.indexOf( ";")) >= 0) sNext = sNext.substring( 0, i);
        sNext = sNext.substring( sNext.indexOf( cCookieDevide, 2)+1, sNext.length);
        // version
        sNext = sNext.substring( sNext.indexOf( cCookieDevide)+1, sNext.length);
        // iLastIndex
        sNext = sNext.substring( sNext.indexOf( cCookieDevide)+1, sNext.length);
        // iCookiesEnabled
        this.iCookiesEnabled = (parseInt( sNext.substring( 0, 1), 10)==0) ? false : true;
        if ( !this.iCookiesEnabled) return;
        sNext = sNext.substring( sNext.indexOf( cCookieDevide)+1, sNext.length);
        // Length of CookieInformation
        i = sNext.indexOf( cCookieDevide);
        l = parseInt( sNext.substring( 0, i), 10);
        sNext = sNext.substring( i+1, sNext.length);
        sNext = sNext.substring( 0, Math.min(l,sNext.length));
        sNext = unescape( sNext);
        sCookie += sNext;
        iNum++;
    } while ( bMore);
    this.cookieinfo = new cookieinfo();
    this.cookieinfo.scan( sCookie, this.iCookieCmpLen);
    this.entry.forEach( 'this.readCookieInfo()');
}

function menuCookieSet( iCookiesEnabled) {
// this.iCookiesEnabled is old state
// iCookieEnabled is new state
    var tExpires;
    var sInfo, sNext, sState, sNext, sPath, sExpires;
    var iLen, iCount;

    if ( this.iCookiesEnabled != 1) return;
    sState = '';
    this.cookieinfo = new cookieinfo();
    if ( iCookiesEnabled) {
        this.entry.forEach( 'this.writeCookieInfo();');
        sState = this.cookieinfo.get();
    }
    sState = escape( sState);
    tExpires = new Date();
    tExpires.setTime( tExpires.getTime()+(this.iCookieDays*86400000));
    sExpires = tExpires.toGMTString();
    sExpires = ';expires=' + sExpires;//escape(sExpires);
    sInfo  = menuinfo.sCopy + " ";
    sInfo  = sInfo.substring( 0, Math.min( sInfo.length, 128))
    while( (i=sInfo.indexOf( cCookieDevide)) >= 0) sInfo = sInfo.substing( 0, i) + cCookieDevideRepl + sInfo.substring( i+1, sInfo.length);
    sInfo += cCookieDevide                               // name
           + '1.0'+cCookieDevide                         // version
           + this.iLastIndex+cCookieDevide               // count
           + (iCookiesEnabled?'1':'0') + cCookieDevide   // enabled
    sInfo  = escape( sInfo);
    iCount = 0;
    sPath  = eval( this.sRelationUp + '.window.location.pathname');
    sPath  = sPath.substring( 0, Math.max( 0, sPath.lastIndexOf( '/')));
    if ( sPath == "") {
        sPath = "/";
    }
    //sPath = escape(sPath);
    do {
        sHeader= this.sVarName + iCount;
        iLen   = Math.min( sState.length, 4096-sHeader.length-2-sInfo.length-5-sExpires.length-1-17-sPath.length);
        sNext  = sState.substring( iLen, sState.length);
        sState = sState.substring( 0, iLen); // max 4096
        sState = sHeader + ((sNext.length>0)?'+':'-')+ '=' + sInfo + (sState.length) + cCookieDevide + sState + sExpires + ';path=' + sPath + ';version=1;';
        // referencing sVarName does function correct because the site
        // must have different sVarName names for the diferent menus.
        eval( this.sRelationUp + '.window.document.cookie = "' + sState + ';"');
        sState = sNext;
    } while ( sState.length > 0 && ++iCount < 300);
}

function menu( window, sInfo, bCookies, entryFirst, sEval, sImgBaseURL) {
    // methods
    this.globalButton   = menuGlobalButton;
    this.htmlDocument   = menuHtmlDocument;
    this.entryGet       = menuEntryGet;
    this.documentChange = menuDocumentChange;
    this.documentClick  = menuDocumentClick;
    this.statusSet      = menuStatusSet;
    this.statusClear    = menuStatusClear;
    this.mouseOver      = menuMouseOver;
    this.mouseOut       = menuMouseOut;
    this.setLastClick   = menuSetLastClick;
    this.cookieGet      = menuCookieGet;
    this.cookieSet      = menuCookieSet;
    this.window         = window;
    // properties
    this.entry          = entryFirst;
    // automatic properties
    this.sRoot          = '';
//    if ( window.location.href.indexOf( "file") >= 0) {
//        this.sRoot = "";
//    } else {
//        this.sRoot = "/";
//    }
    this.sImageRoot     = this.sRoot;
    this.sImgParam      = ' border="0" width="17" height="17" hspace="3" vspace="1" align="middle"';
    this.imgBlank       = new img( sImgBaseURL, 'blank', '.gif');
    this.imgHelp        = new img( sImgBaseURL, 'help', '.gif');
    this.imgCookies     = new imgmark( sImgBaseURL, 'cookies', 'cookies_off', '.gif');
    this.imgInfos       = new imgtype( sImgBaseURL, 'shelf', 'book', 'register', 'document', '_open', '_mark', '.gif');
    this.sRelationUp    = 'parent.window';
    this.sVarName       = 'menuMain';
    this.tDoubleClick   = 200; // [150..350] is o.k.
    this.iCookieDays    = 400;
    this.iCookiesEnabled= bCookies;
    this.cookieinfo     = null;
    this.iCookieCmpLen  = 10;
    this.iGlobalIndex   = 0;
    // private properties
    this.iLastIndex     = 0; // set in entry.initialise
    this.iDepthMax      = 0; // set in entry.initialise
    this.iLastClick     = -1;
    this.tLastClick     = (new Date()).getTime();
    this.timerLastClick = null;
    this.sInfo          = sInfo;
    this.bImgLoad       = true;
    this.bImgInfosLoad  = true;
    this.doc            = new doc( this.window, sInfo, this);
    this.doc.iBaseFontSize  = 3;
    this.doc.iMarginLeft= 3;
    this.doc.iMarginTop = 3;
    this.doc.sBackground= '';
    this.doc.sBgcolor   = "#BFBFBF";
    this.doc.sText      = "#00003F";
    this.doc.sLink      = "#0000FF";
    this.doc.sVlink     = "#0000FF";
    this.doc.sAlink     = "#0000FF";
    this.doc.htmlBody   = menu_doc_WriteHtmlBody; // overwrite default emptypage generation
    // initialise all entries and notice last index, index 0 is first entry (should be root)
    if ( sEval != null) eval( sEval);
    eval( this.sRelationUp + '.' + this.sVarName + ' = this;');
    if ( this.bImgLoad) {
        this.imgBlank.loadImage( this.sImageRoot);
        this.imgHelp.loadImage( this.sImageRoot);
        this.imgCookies.load( this.sImageRoot);
     }
    if ( this.bImgInfosLoad) {
        this.imgInfos.load( this.sImageRoot);
    }
    this.iLastIndex     = this.entry.initialise( -1, 0, this);
    this.entry.iOpenSub = 1; // opens first shelf as mainmenu (root)
    if ( !this.iCookiesEnabled) this.iCookiesEnabled = 2;
    this.cookieGet(); // overwrites menustructure if set and enabled
    this.htmlDocument( 0);
    return this;
}

/****************************************************************************/
// HELP: clientwindow, aboutwindow, cookiewindow

function clientwindowDisplay() {
//    if ( this.window != null) this.window.close();
    this.window         = window.open( "", this.sName, "TOOLBAR=NO,LOCATION=NO,DIRECTORIES=NO,STATUS=NO,MENUBAR=NO,SCROLLBARS=YES,RESIZABLE=YES,COPYHISTORY=NO,WIDTH=500,HEIGHT=580");
    this.doc            = new doc( this.window, this.sTitle, this.user);
    this.doc.htmlBody   = this.htmlBody; // overwrite default emptypage generation
    this.doc.iBaseFontSize  = 3;
    this.doc.sBgcolor   = "#BFBFBF";
    this.doc.sText      = "#00003F";
    this.doc.sLink      = "#0000FF";
    this.doc.sVlink     = "#0000FF";
    this.doc.sAlink     = "#0000FF";
    this.doc.redraw();
}

function clientwindow( sName, sTitle, __doc_WriteHtmlBody, user) {
    // methods
    this.display        = clientwindowDisplay;;
    this.htmlBody       = __doc_WriteHtmlBody;
    // properties
    this.sName          = sName;
    this.sTitle         = sTitle;
    this.user           = user;
    this.window         = null;
    // init
    this.display();
    return this;
}

function aboutwindowDisplay() {
    this.htmlWriteln( '<h3>JavaScript:</h3>');
    this.htmlWriteln( '<h1><a href="' + menuinfo.sHelpRef + '"><em>js/menu.js</em></a></h1>');
    this.htmlWriteln( '<h3>' + menuinfo.sHtmlVersion + '</h3>');
    this.htmlWriteln( '<p><font size="+1">&copy;</font>&nbsp;<a href="mailto:marcus.boerger@post.rwth-aachen.de">M.B&ouml;rger</a></p>');
    this.htmlWriteln( '<a href="' + menuinfo.sCopyRef + '">See Copyright-Info at / Beachten Sie Copyright-Info in Seite:<br>http://www.marcus-boerger.de/js/DynamicJavaScript.html</a>');
    this.htmlWriteln( '<p>');
    this.htmlWriteln( 'Das System verf&uuml;gt standardm&auml;&szlig;ig &uuml;ber hierarchisch gegliederte Men&uuml; Ebenen, die durch die folgenden Icons dargestellt werden:</p><br clear=all />');
    this.htmlWriteln( '<table border="1" cellspacing="3" cellpadding="3" summary="Info">');
    for ( i=0; i<=4; i++) {
        this.htmlWriteln( '<tr>');
        if ( i==0) {
            this.htmlWriteln( '<th>Ebene</th>');
        } else {
            this.htmlWriteln( '<th>' + i + '</th>');
        }
        for ( m=1; m<=2; m++) {
            for ( o=1; o<=2; o++) {
                if ( i==0) {
                    this.htmlWriteln( '<th>' + ((m==1)?'normal':'markiert') + '<br />' + ((o==1)?'geschlossen':'offen') + '</th>');
                } else {
                    this.htmlWriteln( '<td align=center><img src="' + this.user.menu.imgInfos[i][o][m].sourceGet( this.user.menu.sImageRoot) + '" ALT="Ebene ' + i + ', ' + ((m==1)?'normal':'markiert') + ', ' + ((o==1)?'geschlossen':'offen')+ '" border="0" hspace="0" vspace="0" width="17" height="17" /></td>');
                }
            }
        }
        this.htmlWriteln( '</tr>');
    }
    this.htmlWriteln( '</table>');
    this.htmlWriteln( 'Durch klicken der linken Maustaste auf das Men&uuml;icon wechselt der Men&uuml;eintrag zwischen offen, alle Untermen&uuml;s offen, offen und geschlossen.');
    this.htmlWriteln( '<br clear=all>');
    this.htmlWriteln( '<p>Dieses Men&uuml;system kannn sich selbst&auml;ndig an den Benutzer anpassen. Hierzu bitte im Men&uuml; auf ');
    this.htmlWriteln( '<img src="' + this.user.menu.imgCookies[this.user.menu.iCookiesEnabled?1:2].sourceGet( this.user.menu.sImageRoot) + '" alt="Cookies" border="0" hspace="0" vspace="0" width="17" height="17" name="COOKIE" />');
    this.htmlWriteln( 'clicken.</p>');
}

function aboutwindow( menu) {
    this.menu = menu;
    this.clientwindow = new clientwindow( 'About', 'About - ' + menuinfo.sName, aboutwindowDisplay, this);
    return this;
}

function cookiewindowDisplay() {
    this.htmlWriteln( '<h3>JavaScript:</h3>');
    this.htmlWriteln( '<h1><a href="' + menuinfo.sHelpRef + '"><em>js/menu.js</em></a></h1>');
    this.htmlWriteln( '<h3>' + menuinfo.sHtmlVersion + '</h3>');
    this.htmlWriteln( '<p><a href="' + menuinfo.sCopyRef + '">See Copyright-Info at / Beachten Sie Copyright-Info in Seite:<br />' + menuinfo.sCopyRef + '</a>');
    this.htmlWriteln( '</p>');
    this.htmlWriteln( 'F&uuml;r weitere Hilfe bitte im Men&uuml; auf ');
    this.htmlWriteln( '<img src="' + this.user.menu.imgHelp.sourceGet( this.user.menu.sImageRoot) + '" alt="' + menuinfo.sCopyRef + '" border="0" hspace="0" vspace="0" width="17" height="17" name="ABOUT" />');
    this.htmlWriteln( 'clicken.<p>');
    this.htmlWriteln( 'Wenn Cookies angeschaltet sind werden die Informationen dar&uuml;ber, welche Men&uuml;eintr&auml;ge ge&ouml;ffnet ');
    this.htmlWriteln( 'sind und deren Markierungszustand vom Browser des Benutzers abgespeichert. Diese Information kann <em>ausschlie&szlig;lich</em> ');
    this.htmlWriteln( 'von diesem Script auf genau dieser Seite abgefragt werden. Es keine M&ouml;glichkeit auf andere Weise an diese Informationen zu ');
    this.htmlWriteln( 'gelangen, nochweniger hat irgendjemand anderes die M&ouml;glichkeit diese zu bekommen.');
    this.htmlWriteln( '</p><p>');
    this.htmlWriteln( 'Durch einen Doppelclick auf das Cookie Symbol kann man die F&auml;higkeit des Systemes Cookies zu benutzen an- und abschalten.');
    this.htmlWriteln( '</p><br clear=all />');
    this.htmlWriteln( 'Wenn Cookies angeschaltet sind, so erscheint: ');
    this.htmlWriteln( '<img src="' + this.user.menu.imgCookies[1].sourceGet( this.user.menu.sImageRoot) + '" alt="Cookies angeschaltet" border="0" hspace="0" vspace="0" width="17" height="17" name="ABOUT" />');
    this.htmlWriteln( '<br clear=all />');
    this.htmlWriteln( 'Wenn Cookies abgeschaltet sind, so erscheint: ');
    this.htmlWriteln( '<img src="' + this.user.menu.imgCookies[2].sourceGet( this.user.menu.sImageRoot) + '" alt="Cookies abgeschaltet" border="0" hspace="0" vspace="0" width="17" height="17" name="ABOUT" />');
    this.htmlWriteln( '<br clear=all />');
}

function cookiewindow( menu) {
    this.menu = menu;
    this.clientwindow = new clientwindow( 'Cookies', 'Cookies - ' + menuinfo.sName, cookiewindowDisplay, this);
    return this;
}


/*************************************************************************
// FUNCTIONS: Accessing Menu -->
<a name="MenuTop"></a>
<a name="MenuAdd"></a>
<a name="MenuReg"></a>
<a name="MenuSub"></a>
<h3>MenuTop(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;entryFirst,&nbsp;entryNext)</h3>
<h3>MenuAdd(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;entrySub,&nbsp;entryNext)</h3>
<h3>MenuReg(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;entrySub,&nbsp;entryNext)</h3>
<h3>MenuSub(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;entryNext)</h3>
<p></p>
<h3>MenuTop_Key(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;sKey,&nbsp;entryFirst,&nbsp;entryNext)</h3>
<h3>MenuAdd_Key(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;sKey,&nbsp;entrySub,&nbsp;entryNext)</h3>
<h3>MenuReg_Key(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;sKey,&nbsp;entrySub,&nbsp;entryNext)</h3>
<h3>MenuSub_Key(&nbsp;sName,&nbsp;sURL,&nbsp;sTarget,&nbsp;sInfo,&nbsp;sEval,&nbsp;sKey,&nbsp;entryNext)</h3>
<dl>
<dt>sName (HTML-String)</dt>
<dd>Name to display as Reference.
<p>Name der im Men&uuml; angezeigt wird.
</p></dd>
<dt>sUrl (Escaped-String)</dt>
<dd>Destination as URL or <em>null</em> if none.
<p>Ziel f&uuml;r Men&uuml;eintrag oder <em>null</em> falls kein Ziel.
</p></dd>
<dt>sTarget</dt>
<dd>Windowname for destination or <em>null</em> if same window.
<p>Fenstername f&uuml;r Ziel oder <em>null</em> falls gleiches Fenster.
</p></dd>
<dt>sInfo</dt>
<dd>Name to Display as Image alternate and in Statusbar.
<p>Name der als Bildinformation oder in Statusbar angezeigt wird.
</p></dd>
<dt>sEval</dt>
<dd>JavaScript Statement to be executed after default initialisation.
<p>JavaScript Ausdruck, der nach der default Initialisierung ausgewertet wird.
</p></dd>
<dt>sKey</dt>
<dd>Key used as cookie name for menuentries (may generate shorter cookie).
<p>Key der als Cookiename f&uuml;r Men&uuml;eintr&auml;ge benutzt wird (ggf. k&uuml;rzere Cookies).
</p></dd>
<dt>entrySub</dt>
<dd>First submenuentry.
<p>Erster Unterme&uuml;eintrag.
</p></dd>
<dt>entryNext</dt>
<dd>Next menuentry on same level.
<p>N&auml;chster Men&uuml;eintrag auf gleicher Ebene.
</p>
<dt><b>return</b></dt>
<dd>The retrun variable is the generated entry. This can be used in subsequent calls or in <a href="#MenuInit">MenuInit</a>.
<p>Die R&uuml;ckgabe ist der generierte Eintrag. Dies kann in verschachtelten Aufrufen oder in <a href="#MenuInit">MenuInit</a> genutzt werden.
</p></dt>
</dl>
<!-- ************************************************************************/

// sEval, fCookieGet, sCookieKey, oUser1, oUser2

function MenuTop( sName, sURL, sTarget, sInfo, sEval, entrySub, entryNext) {
    return new entry( iMT_TOP, sName, sURL, sTarget, sInfo, false, entrySub, entryNext, sEval, null, null, null, null, null);
}

function MenuAdd( sName, sURL, sTarget, sInfo, sEval, entrySub, entryNext) {
    return new entry( iMT_MEN, sName, sURL, sTarget, sInfo, false, entrySub, entryNext, sEval, null, null, null, null, null);
}

function MenuReg( sName, sURL, sTarget, sInfo, sEval, entrySub, entryNext) {
    return new entry( iMT_REG, sName, sURL, sTarget, sInfo, false, entrySub, entryNext, sEval, null, null, null, null, null);
}

function MenuSub( sName, sURL, sTarget, sInfo, sEval, entryNext) {
    return new entry( iMT_SUB, sName, sURL, sTarget, sInfo, false, null, entryNext, sEval, null, null, null, null, null);
}

function MenuTop_Key( sName, sURL, sTarget, sInfo, sEval, sCookieKey, entrySub, entryNext) {
    return new entry( iMT_TOP, sName, sURL, sTarget, sInfo, false, entrySub, entryNext, sEval, null, sCookieKey, null, null);
}

function MenuAdd_Key( sName, sURL, sTarget, sInfo, sEval, sCookieKey, entrySub, entryNext) {
    return new entry( iMT_MEN, sName, sURL, sTarget, sInfo, false, entrySub, entryNext, sEval, null, sCookieKey, null, null);
}

function MenuReg_Key( sName, sURL, sTarget, sInfo, sEval, sCookieKey, entrySub, entryNext) {
    return new entry( iMT_REG, sName, sURL, sTarget, sInfo, false, entrySub, entryNext, sEval, null, sCookieKey, null, null);
}

function MenuSub_Key( sName, sURL, sTarget, sInfo, sEval, sCookieKey, entryNext) {
    return new entry( iMT_SUB, sName, sURL, sTarget, sInfo, false, null, entryNext, sEval, null, sCookieKey, null, null);
}

/************************************************************************* -->
<a name="MenuInit"></a>
<h3>MenuInit( window, sInfo, bCookies, sEval, entryFirst)</h3>
<h3>MenuInit( window, sInfo, bCookies, sEval, entryFirst, sImgBaseURL)</h3>
<dl>
<dt>window</dt>
<dd>Window to display menu in.
<p>Window in dem das Men&uuml; dargestellt werden soll.
</p></dd>
<dt>sInfo (Escaped-String)</dt>
<dd>Titel and default status of menu.
<p>Titel und default Status des Men&uuml;s.
</p></dd>
<dt>bCookies</dt>
<dd>Enable or disable Cookies, see Information behind Cookie in loaded menu-instance. This affects the menu only
if no cookie is written yet.
<p>Cookies aktivieren oder deaktivieren. Weitere Informationen &uuml;ber das Cookie Symbol in einer Menuanwendung.
Diese Einstellung wirkt sich nur aus, wenn noch kein Cookie geschrieben wurde.
</p></dd>
<dt>sEval</dt>
<dd>JavaScript Statement to be executed after default initialisation and before executing Statements of menuentries.
<p>JavaScript Ausdruck wird ausgewertet nach der default Initialisierung und vor der ausgewertung der Ausdr&uuml;cke der Bilder.
</p></dd>
<dt>entryFirst</dt>
<dd>rootmenuentry.
<p>Erster Me&uuml;eintrag.
</p></dd>
<dt>sImgBaseURL</dt>
<dd>Prefix to images src attribut, default: 'js/img/'
<p>Prefix f&uuml;r src Attribut von Bildern, default: 'js/img/'
</p></dd>
<dt><b>return</b></dt>
<dd>The return value is the generated menu Object, globally stored in the variable menuMain.
<p>Die R&uuml;gabe ist das generierte menu Object, global in der Variablen menuMain gespeichert.
</p></dt>
</dl>
<!-- ************************************************************************/

function MenuInit( window, sTitle, bCookies, sEval, entryFirst) {
    menuMain = new menu( window, sTitle, bCookies, entryFirst, sEval, 'js/img/');
    return menuMain;
}

function MenuInit( window, sTitle, bCookies, sEval, sImgBaseURL, entryFirst) {
    menuMain = new menu( window, sTitle, bCookies, entryFirst, sEval, sImgBaseURL);
    return menuMain;
}
// -->

