// Tim Reeves JavaScript for BibTours2011, Stand 2012-01-19
// with xml-compliant code to insert an img node for the counter

// FAUSTREGEL: READ an attribute and SET a style (with a text string) !!!

// CONFIG (these values used both in 94% and fixed height)
var intMinSiteWidth = window.g_minSiteWidth;
var intMinSiteHeight = window.g_minSiteHeight;
// END CONFIG

// Recognise IE 6 - 9
var isIE = false, isIE6 = false, isIE7 = false, isIE8 = false, isIE9 = false;

function getElemId(ident) {
 var Elem;
 if (document.getElementById) {	// DOM; IE5, NS6, Mozilla, Opera
     if (typeof document.getElementById(ident) == "object")
     Elem = document.getElementById(ident);
     else Elem = void(0);
     }
 else if (document.all) {		// Proprietary DOM; IE4
     if (typeof document.all[ident] == "object")
     Elem = document.all[ident];
     else Elem = void(0);
   }
 else if (document[ident]) {	// Netscape alternative
     Elem = document[ident];
   }
 else Elem = void(0);
 return(Elem);
}

var intMinContHeight = 400;	// Real value noted at startup

function neuAufbau() {

	var objHtml = getElemId(window.g_htmlTagId);
	var objBody = getElemId('mybody');
	var objSite = getElemId('website');
	var objMain = getElemId('main');
	var objKopf = getElemId('kopf');
	var objFuss = getElemId('fuss');
	var objCont = getElemId('content');

	var objHeader = getElemId('header');
	var objFooter = getElemId('footer');
	var objAktuell = getElemId('topaktuell');
	var objScroller = getElemId('scroller');

	// 1: IE6 stupidly reduces the size of the <body> element...
	if (isIE6) {
		objBody.style.height = objHtml.clientHeight + 'px';
		objBody.style.width  = objHtml.clientWidth + 'px';
	}

	// 2: For div.website height 100% most browsers take objBody.offsetHeight
	// But we must modify this to objBody.clientHeight - or the min-height
	// This also cures the "old browser" problem of min-height not obeyed.
	var currViewHeight = objBody.clientHeight;
	var currSiteHeight = objSite.offsetHeight;
	var useHeight = (currViewHeight > intMinSiteHeight) ? currViewHeight : intMinSiteHeight;
	if (currSiteHeight != useHeight) {
		objSite.style.height = useHeight + 'px';
		currSiteHeight = useHeight;
	}
	// 2b: Same game for div.website width
	var currViewWidth = objBody.clientWidth;
	var currSiteWidth = objSite.offsetWidth;
	var useWidth = (currViewWidth > intMinSiteWidth) ? currViewWidth : intMinSiteWidth;
	if (currSiteWidth != useWidth) {
		objSite.style.width = useWidth + 'px';
		currSiteWidth = useWidth;
	}

	if (objHeader && objHeader.offsetHeight == 0) {
		// FIXED HEIGHT: The header is present but set to display:none
		if (window.g_vertCentering) {
			// Perform vertical centering.
			// Degrading mode has a top margin on div.main
			// Just overwrite that with (browser - main) / 2 (but not less than zero)
			var intMainHeight = objMain.offsetHeight;
			if (intMainHeight+1 < currSiteHeight) {
				var intMainTopMargin = Math.floor( (currSiteHeight - intMainHeight) / 2 );
			}
			else {
				var intMainTopMargin = 0;
			}
			objMain.style.marginTop = intMainTopMargin + 'px';
			// Report back to Server via XHR
			ajaxWindowSize('mainTopMargin', intMainTopMargin + '');
			var intScrollerHeight = objScroller.offsetHeight;
		}
	}	// fixed

	else {
		// 94% HEIGHT (or 97% if header is not present)

		// 3: Feature-Workaround - WebKit and IE8 calculate %-heights
		//    to nearest enclosing Fixed height (NOT % height) (here: Viewport).
		//    W3C: "Percentage intrinsic heights are evaluated with respect to
		//         the containing block's height, if that height is specified
		//         explicitly," - open to interpretation if percent is explicit.
		// Avoid rounding errors which may lead to <main> being too short or long
		// Correct rounding up on Header/Footer to rounding down (e.g. for IE7)
		// Since browsers differ a lot simply ALWAYS do it ourselves !!!
		// offsetHeight is the height including any margins, padding and borders
		var intMainHeight = objMain.offsetHeight;	// Should be 94% of 'website'

		var intAvailForHdrFtr3pc = Math.floor( currSiteHeight * 0.03 );
		var intAvailForMainBySubtractAvailHdrFtr =
			(objHeader) ? currSiteHeight - (2 * intAvailForHdrFtr3pc)
						: currSiteHeight - intAvailForHdrFtr3pc;

		var intCurrFooter = objFooter.offsetHeight, intCurrHeader = 0;
		if (objHeader) intCurrHeader = objHeader.offsetHeight;

		/*alert('availHdrFtr3pc=' + intAvailForHdrFtr3pc +
			', currHeader=' + intCurrHeader +
			', currFooter=' + intCurrFooter);
		alert('siteHeight=' + currSiteHeight +
			', mainHeight=' + intMainHeight +
			', AMBSAHF=' + intAvailForMainBySubtractAvailHdrFtr
			);*/

		if (intCurrHeader > 0 && intCurrHeader != intAvailForHdrFtr3pc) {
			objHeader.style.height = intAvailForHdrFtr3pc + 'px';
		}
		if (intCurrFooter != intAvailForHdrFtr3pc) {
			objFooter.style.height = intAvailForHdrFtr3pc + 'px';
		}
		if (intMainHeight != intAvailForMainBySubtractAvailHdrFtr) {
			intMainHeight = intAvailForMainBySubtractAvailHdrFtr;
			objMain.style.height = intMainHeight + 'px';
		}

		// 4: Set content scroller height
		// var objExtra = getElemId('extra');
		var intKopfHeight = objKopf.offsetHeight;
		var intFussHeight = objFuss ? objFuss.offsetHeight : 0;
		var intScrollerHeight = intMainHeight - intKopfHeight - intFussHeight;
		if (intScrollerHeight < 0) intScrollerHeight = 0;
		// alert(intMainHeight + ' / ' + intKopfHeight + ' / ' + intFussHeight + ' / ' + intScrollerHeight);
		objScroller.style.height = intScrollerHeight + 'px';

		// 5: Report back to Server via XHR
		var strVarSizeValues =	intAvailForHdrFtr3pc + '-' +
								intMainHeight + '-' + intScrollerHeight;
		ajaxWindowSize('varSizeValues', strVarSizeValues);

	}	// 94%

	// 5. BiR-Specific: Set height of div.contbody if that layout is used
	var objCthd = getElemId('conthead');
	if (objCthd) {
		// It's the conthead - contbody layout
		// Width of div.content extended by css style 05 from 714 to 736
		if (objCont.offsetWidth == 736) {
			// The intention is that contbody gets the scroller
			// - the default setup is that div.scroller gets it. So
			// set a fixed height on contbody so it shows the scroller
			// contbody height = scrollerHeight - contheadHeight
			var intCtbdHeight = intScrollerHeight - objCthd.offsetHeight;
			// alert(intScrollerHeight + ' / ' + objCthd.offsetHeight + ' / ' + intCtbdHeight);
			var objCtbd = getElemId('contbody');
			objCtbd.style.height = intCtbdHeight + 'px';
			// - 1 for contframe border-bottom
			intCtbdHeight -= 1;
			// And another - 1 if it has a contframetopborder
			if (getElemId('contframetopborder')) intCtbdHeight -= 1;
		} else {
			// TR : Not sure if this branch is used or would work...
			// Default setup, div.scroller gets a fixed height (see above)
			// and therefore also the scroller. div.content remains 714px
			// wide or it would obscure the scrollbar of div.scroller.
			var objCtbd = null;
			var intCtbdHeight = intScrollerHeight;
		}
	}
	else {
		var objCtbd = null;
		var intCtbdHeight = intScrollerHeight;
	}

	// 6. BiR-Specific: Set shorter of col1 / col2 to same height as longer
	// But both at least as high as div.scroller
	var objCol1 = getElemId('col1');
	var objCol2 = getElemId('col2');
	if (objCol1 && objCol2) {
		var intCol1Height = objCol1.offsetHeight;	// Includes any borders
		var intCol2Height = objCol2.offsetHeight;	// margin-top added below
		if (objCtbd) {
			// col1 has 1px top + bottom border, EXCEPT in contbody
			var intCol1BorderHeight = 0;
			// col2 has no borders but margin-top 30px when in contbody
			// - except when 03.css is included for 50-50 columns
			// - also not when using contframetopborder
			var intCol2MarginTop = (objCol2.offsetWidth == 334) ? 0 : 30;
			if (getElemId('contframetopborder')) intCol2MarginTop = 0;
			intCol2Height += intCol2MarginTop;
		}
		else {
			var intCol1BorderHeight = 2;
			var intCol2MarginTop = 0;
		}
		var intMaxHeight = intCol1Height > intCol2Height
						 ? intCol1Height : intCol2Height;
		// intCtbdHeight set in (5) (above) to the real available col1/2 height
		if (intMaxHeight < intCtbdHeight) intMaxHeight = intCtbdHeight;
		// alert(intMaxHeight + ' / ' + intCtbdHeight + ' / ' + intCol1Height + ' / ' + intCol2Height);
		// Set up col1
		if (intCol1Height < intMaxHeight) {
			// Extend col1
			var intNewHeight = intMaxHeight - intCol1BorderHeight;
			objCol1.style.height = intNewHeight + 'px';
		}
		else
		if (intCol1Height > intCtbdHeight &&
			intCol1Height > intMinContHeight) {
			// Window being sized smaller
			var intNewHeight = intCtbdHeight > intMinContHeight
							 ? intCtbdHeight - intCol1BorderHeight
							 : intMinContHeight - intCol1BorderHeight;
			objCol1.style.height = intNewHeight + 'px';
		}
		// Set up col2
		if (intCol2Height < intMaxHeight) {
			// Extend col2
			objCol2.style.height = (intMaxHeight - intCol2MarginTop) + 'px';
		}
		else
		if (intCol2Height > intCtbdHeight &&
			intCol2Height > intMinContHeight) {
			// Window being sized smaller
			var intNewHeight = intCtbdHeight > intMinContHeight
							 ? intCtbdHeight : intMinContHeight;
			objCol2.style.height = (intNewHeight - intCol2MarginTop) + 'px';
		}
	}	// objCol1 && objCol2

	else {
		// Monolithic Pages (from PLM / Proto)
		if (objCol1) {
			// e.g. Presse, Kontaktformular (class = col12)
			var intCol1Height = objCol1.offsetHeight;	// Includes any borders
			// col1 has 1px top + bottom border, EXCEPT in contbody
			var intCol1BorderHeight = (objCtbd) ? 0 : 2;
			// intCtbdHeight set in (5) (above) to the real available col1/2 height
			if (intCol1Height < intCtbdHeight) {
				// Extend col1
				var intNewHeight = intCtbdHeight - intCol1BorderHeight;
				objCol1.style.height = intNewHeight + 'px';
			}
			else
			if (intCol1Height > intCtbdHeight &&
				intCol1Height > intMinContHeight) {
				// Window being sized smaller
				var intNewHeight = intCtbdHeight > intMinContHeight
								 ? intCtbdHeight - intCol1BorderHeight
								 : intMinContHeight - intCol1BorderHeight;
				objCol1.style.height = intNewHeight + 'px';
			}
		}
		else {
			var intContHeight = objCont.offsetHeight;
			if (intContHeight < intScrollerHeight) {
				// Extend div.content - here with padding-bottom + 2 x border
				var intNewHeight = intScrollerHeight - 12;
				objCont.style.height = intNewHeight + 'px';
			}
			else
			if (intContHeight > intScrollerHeight &&
				intContHeight > intMinContHeight) {
				// Window being sized smaller
				var intNewHeight = intScrollerHeight > intMinContHeight
								 ? intScrollerHeight - 12 : intMinContHeight - 12;
				objCont.style.height = intNewHeight + 'px';
			}
		}
	}

	// 7: Top-Aktuell, falls vorhanden, bekommt seine Höhe gesetzt
	//                 sonst gibt es keine Scrollbalken.
	if (objAktuell) {
		// To intScrollerHeight - Menu-Height - (12 Margin + 8 Padding + 2 Border)
		var objMenu = getElemId('menu');
		var intTopHeight = intScrollerHeight - objMenu.offsetHeight - 22;
		var objGreeting  = getElemId('logingreeting');
		if (objGreeting) intTopHeight -= objGreeting.offsetHeight;
		objAktuell.style.height = intTopHeight + 'px';
	}

	// 8: IE fixes - sigh...
	if (isIE6) {
		// alert('IE6');
		// Add any IE6 fix here
	}
	if (isIE7) {
		// alert('IE7');
		// Add any IE7 fix here
	}

	return;
}	// neuAufbau()


// This is called by the onload-event of every page
function startUp(testforjavascript) {

	if (window.g_mobil)
		window.g_reportWindowSize = false;
	else
		window.g_reportWindowSize = testforjavascript;

	// Recognise IE versions (store in global variables)
	if (navigator.appName.indexOf('Microsoft') >= 0) {
		var ua = navigator.userAgent.toLowerCase();
		// alert(ua);
		isIE = true;
		// Test ua for higher versions first - may contain lower as compatible
		if (ua.indexOf('msie 9') != -1) isIE9 = true; else
		if (ua.indexOf('msie 8') != -1) isIE8 = true; else
		if (ua.indexOf('msie 7') != -1) isIE7 = true; else
		if (ua.indexOf('msie 6') != -1) isIE6 = true;
	}

	// BiR: Zeige "Nach oben" wenn die Seite diesen Absatz enthält
	// - before the heights of col1 / col2 are matched in neuAufbau()
	var objCont = getElemId('content');
	var objNachOben = getElemId('nachoben');
	if (objNachOben != null) {
		var objCtbd = getElemId('contbody');
		var objScro = getElemId('scroller');
		var objCol1 = getElemId('col1');
		var objCol2 = getElemId('col2');
		// alert(objCont + ' / ' + objCtbd + ' / ' + objScro + ' / ' + objCol1 + ' / ' + objCol2);
		if (objCol1 && objCol2 && objScro) {
			if (objCtbd) {
				// Compute final height of contbody
				var objCthd = getElemId('conthead');
				var intScroHeight = objScro.offsetHeight - objCthd.offsetHeight;
			}
			else {
				var intScroHeight = objScro.offsetHeight;
			}
			var intMaxHeight = objCol1.offsetHeight > objCol2.offsetHeight
							 ? objCol1.offsetHeight : objCol2.offsetHeight;
			// alert(objCol1.offsetHeight + ' / ' + objCol2.offsetHeight +
			// 	  ' / ' + intMaxHeight + ' / ' + intScroHeight);
			if (intMaxHeight > intScroHeight)
				objNachOben.style.display = 'block';
		}
		else
		if (objCont && objScro) {	// Monolithic Pages (from PLM / Proto)
			if (objCont.offsetHeight > objScro.offsetHeight)
				objNachOben.style.display = 'block';
		}
	}

	// Deal with the client height topic - after maybe activating nachoben

	if (!window.g_mobil) {
		// First note the true required content height
		intMinContHeight = objCont.offsetHeight;
		var objCthd = getElemId('conthead');
		if (objCthd) intMinContHeight -= objCthd.offsetHeight;

		var objMain = getElemId('main');
		if (objMain != null && typeof objMain.clientHeight == 'number') {
			if (isIE6) {
				// IE6 has some crazy css styles for degrading mode; reset them
				var objHtml = getElemId(window.g_htmlTagId);
				var objBody = getElemId('mybody');
				var objSite = getElemId('website');
				objHtml.style.overflow = 'hidden';
				objBody.style.overflow = 'auto';
				objBody.style.height = '100%';
				objBody.style.width = '100%';
				objSite.style.width = '100%';
			}
			neuAufbau();
			// IE6+7 benötigen einen 2. Aufruf für die richtige Höhe von div.scroller
			if (isIE6 || isIE7) neuAufbau();
			window.onresize = neuAufbau;
		}
	}

	// DONT Perform the ajax-based test for JavaScript
	// if (testforjavascript) { ajaxStartUp(); }

	// Because now we ALWAYS do the Ajax-Magic
	ajaxOnload();

	// Note initial website entry
	var re = new RegExp('^' + window.g_win_name, '');
	if (! re.test(window.name)) {
		// It IS the initial website entry - set the window name
		// alert('Setting window.name to: ' + window.g_win_name);
		window.name = window.g_win_name;
		// And do whatever else you may need ...
	}
	// Caveat: Since hardly any site sets the window name, it tends to stay this way
	//         meaning that subsequent visits - even hours later - are not noted

	// Display the font size selection elements
	if (typeof setUserOptions == 'function') setUserOptions();

	// Preload onmouseover images to prevent initial response lag
	if (window.g_preload) {
		var bi = new Array;
		for (l=0; l<window.g_preload.length; l++) {
			bi[l] = new Image();
			bi[l].src = window.g_pathPrefix + window.g_preload[l];
		}
	}

	return;
}

// This would be called by the onunload-event of every page
// Except that AdMuncher overwrites that event by default
function unLoadPage() {
	window.g_loading = true;	// For colorflow
	saveSettings();		// For font size
	return;
}


// BEGIN Code for custom tooltips

// 1: lixlpixel Javascript tooltips - http://lixlpixel.org/javascript-tooltips/

var ie5 = (document.getElementById && document.all);
var ns6 = (document.getElementById && !document.all);
var ua = navigator.userAgent.toLowerCase();
var isapple = (ua.indexOf('applewebkit') != -1 ? 1 : 0);

function getmouseposition(e) {
	if (document.getElementById) {
		var iebody=(document.compatMode &&
			document.compatMode != 'BackCompat') ?
			document.documentElement : document.body;
		// (IE) scrollLeft/Top  (W3) page{X|Y}Offset:
		// Aktuelle horizontale/vertikale (Scroll)Position innerhalb der Seite,
		// gemessen am linken bzw. oberen Fensterrand (i.e. how much scrolled)
		pagex = (isapple == 1 ? 0:(ie5)?iebody.scrollLeft:window.pageXOffset);
		pagey = (isapple == 1 ? 0:(ie5)?iebody.scrollTop:window.pageYOffset);
		// clientX/Y: Mauszeiger-Position relativ zur oberen linken Ecke des Anzeige-
		// bereichs des Fensters, in dem das aktuellen Dokument dargestellt wird.
		mousex = (ie5)?event.x:(ns6)?clientX = e.clientX:false;
		mousey = (ie5)?event.y:(ns6)?clientY = e.clientY:false;
		// if (isIE6 || isIE7) {
		if (isIE) {
			var objMain = getElemId('main');
			mousex += objMain.offsetLeft;
			mousey += objMain.offsetTop;
		}
		var tip = document.getElementById('fotooltip');
		var tipX = mousex + pagex + window.g_tipoffsetx + window.tipAddleft;
		var tipY = mousey + pagey + window.g_tipoffsety + window.tipAddtop;
		tip.style.left = tipX + 'px';
		tip.style.top  = tipY + 'px';
		// var mainTopMargin = getElemId('main').offsetTop;
		// msgDebug = 'mousey=' + mousey + ', pagey=' + pagey +
		// 		   ', offsety=' + offsety + ', mainTopMargin=' + mainTopMargin;
		// getElemId('breadcrumbs').innerHTML = '<p>' + msgDebug + '</p>';
	}
}

function ignoreevent(e) {
}

// 2: http://blogs.korzh.com/progtips/2008/05/28/absolute-coordinates-of-dom-element-within-document.html
//    Many thanks to Sergiy Khorz !

function __getIEVersion() {
    var rv = -1; // Return value assumes failure.
    if (navigator.appName == 'Microsoft Internet Explorer') {
        var ua = navigator.userAgent;
        var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
            rv = parseFloat(RegExp.$1);
    }
    return rv;
}

function __getOperaVersion() {
    var rv = 0; // Default value
    if (window.opera) {
        var sver = window.opera.version();
        rv = parseFloat(sver);
    }
    return rv;
}

var __userAgent = navigator.userAgent;
var __isIE =  navigator.appVersion.match(/MSIE/) != null;
var __IEVersion = __getIEVersion();
var __isIENew = __isIE && __IEVersion >= 8;
var __isIEOld = __isIE && !__isIENew;

var __isFireFox = __userAgent.match(/firefox/i) != null;
var __isFireFoxOld = __isFireFox && ((__userAgent.match(/firefox\/2./i) != null) || (__userAgent.match(/firefox\/1./i) != null));
var __isFireFoxNew = __isFireFox && !__isFireFoxOld;

var __isWebKit =  navigator.appVersion.match(/WebKit/) != null;
var __isChrome =  navigator.appVersion.match(/Chrome/) != null;
var __isOpera =  window.opera != null;
var __operaVersion = __getOperaVersion();
var __isOperaOld = __isOpera && (__operaVersion < 10);

function __parseBorderWidth(width) {
    var res = 0;
    if (typeof(width) == "string" && width != null && width != "" ) {
        var p = width.indexOf("px");
        if (p >= 0) {
            res = parseInt(width.substring(0, p));
        }
        else {
     		//do not know how to calculate other values (such as 0.5em or 0.1cm) correctly now
    		//so just set the width to 1 pixel
            res = 1;
        }
    }
    return res;
}


//returns border width for some element
function __getBorderWidth(element) {
	var res = new Object();
	res.left = 0; res.top = 0; res.right = 0; res.bottom = 0;
	if (window.getComputedStyle) {
		//for Firefox
		var elStyle = window.getComputedStyle(element, null);
		res.left = parseInt(elStyle.borderLeftWidth.slice(0, -2));
		res.top = parseInt(elStyle.borderTopWidth.slice(0, -2));
		res.right = parseInt(elStyle.borderRightWidth.slice(0, -2));
		res.bottom = parseInt(elStyle.borderBottomWidth.slice(0, -2));
	}
	else {
		//for other browsers
		res.left = __parseBorderWidth(element.style.borderLeftWidth);
		res.top = __parseBorderWidth(element.style.borderTopWidth);
		res.right = __parseBorderWidth(element.style.borderRightWidth);
		res.bottom = __parseBorderWidth(element.style.borderBottomWidth);
	}

	return res;
}


//returns the absolute position of some element within document
function getElementAbsolutePos(elemID) {
	var element;
	if (typeof(elemID) == "string")	{
		element = document.getElementById(elemID);
	}
	else {
		element = elemID;
	}

	var res = new Object();
	res.x = 0; res.y = 0;
	if (element !== null) {
        if (__isIENew) {
	    	res.x = element.scrollLeft;
		    res.y = element.scrollTop;
		}
		else {
	    	res.x = element.offsetLeft;
		    res.y = element.offsetTop;
		}

		var offsetParent = element.offsetParent;
		var parentNode = element.parentNode;
		var borderWidth = null;

		while (offsetParent != null) {
			res.x += offsetParent.offsetLeft;
			res.y += offsetParent.offsetTop;

			var parentTagName = offsetParent.tagName.toLowerCase();

			if ((__isIEOld && parentTagName != "table") || (__isFireFoxNew && parentTagName == "td")) {
				borderWidth = __getBorderWidth(offsetParent);
				res.x += borderWidth.left;
				res.y += borderWidth.top;
			}

			if (offsetParent != document.body && offsetParent != document.documentElement) {
				res.x -= offsetParent.scrollLeft;
				res.y -= offsetParent.scrollTop;
			}


			//next lines are necessary to support FireFox problem with offsetParent
   			if (!__isIE && !__isOperaOld || __isIENew) {
    			while (offsetParent != parentNode && parentNode !== null) {
					res.x -= parentNode.scrollLeft;
					res.y -= parentNode.scrollTop;
					if (__isFireFoxOld && __isWebKit) {
						borderWidth = __getBorderWidth(parentNode);
						res.x += borderWidth.left;
						res.y += borderWidth.top;
					}
    				parentNode = parentNode.parentNode;
    			}
			}

   			parentNode = offsetParent.parentNode;
    		offsetParent = offsetParent.offsetParent;
		}
	}
    return res;
}

// 3. My code

function findMenuPos(obj) {
	// Internal function - find position of obj (a menu <a>) relative to viewport
	// This is simple and it only works when no scrolling involved - ok for menu
    var res = new Object();
    res.x = 0; res.y = 0;

	if (obj.offsetParent) {
		res.x = obj.offsetLeft;
		res.y = obj.offsetTop;
		var isLink = (obj.tagName == 'A');
		while (obj = obj.offsetParent) {
			if (isLink && obj.tagName == 'TABLE') {
				// Only IE5 / IE6 have a table, they miss counting an LI Element
				// alert('TABLE class:' + obj.className +
				//  ' offsetLeft: ' + obj.parentElement.parentElement.offsetLeft +
				//  ' offsetTop: ' + obj.parentElement.parentElement.offsetTop);
				res.x += obj.parentElement.parentElement.offsetLeft;
				res.y += obj.parentElement.parentElement.offsetTop;
			}
			else {
				// alert(obj.tagName + ' id:' + obj.id + ' class:' + obj.className +
				//  ' offsetLeft: ' + obj.offsetLeft + ' offsetTop: ' + obj.offsetTop);
				res.x += obj.offsetLeft;
				res.y += obj.offsetTop;
			}
		}
	}
	return res;
}


var currentflyoutsublevel = 0;
var currentTimerHandle = null;


function showtip(currobj, sublevel, addleft, addtop, text) {
	// External function. At onmouseout text is the empty string.
	// Called at onmouseover / onmouseout to display / hide a tooltip
	// alert(currobj.tagName + ' ' + currobj.id + ' ' + currobj.className + ' ' + sublevel);
	// If sublevel == 0 then position tip below mousecursor - but move
	// left if need be for whole tip to be in window (extra-menu).
	// Otherwise sublevel => 1 / 2 / 3 for main menu level, and
	// offsets refer to the top left corner of the menu item.
	if (sublevel == 0) {
		showtipwork(null, addleft, addtop, text);
	}
	else {
		if (sublevel < currentflyoutsublevel) return;
		currentflyoutsublevel = (text == '') ? sublevel - 1 : sublevel;
		showtipwork(currobj, addleft, addtop, text);
	}
	return true;
}


function displaytip() {
	// Internal function - called via timer
	var tip = getElemId('fotooltip');
	tip.style.display = 'block';
	currentTimerHandle = null;
	return true;
}


function showtipwork(currobj, addleft, addtop, text) {
	// Internal function - do the actual work of displaying / hiding a tooltip
	// If currobj is null then under cursor (and shifted left if need be to fit
	// on the page); otherwise at (addleft, addtop) in respect of the DOM 'currobj'.
	if (currobj == null) {
		// Tip under cursor
		if (!window.g_otherTooltips) return;
	}
	else {
		// In relation to a particular DOM object (main menu item)
		if (!window.g_mainTooltips) return;
	}
	var tip = getElemId('fotooltip');
	if (text == '') {
		// Clear any timer and hide the tooltip
		if (currentTimerHandle != null) {
			window.clearTimeout(currentTimerHandle);
			currentTimerHandle = null;
		}
		tip.style.display = 'none';
		return true;
	}
	// Put the new text into the tip (we need its new length)
	if (tip.innerHTML)
		tip.innerHTML = text;	// Allows <b>, <i> etc. in Tooltips
	else
		tip.firstChild.data = text;
	// Get the position for the top left corner of the tip
	if (currobj == null) {
		// Under cursor
		window.tipAddleft = addleft;
		window.tipAddtop  = addtop;
		document.onmousemove = getmouseposition;
	}
	else {
		// In relation to a particular DOM object (main menu item)
		document.onmousemove = ignoreevent;
		if (currobj.id != '' && currobj.id.indexOf('flow') == 0)
			var objpos = findMenuPos(currobj);		// main menu item
		else
			var objpos = getElementAbsolutePos(currobj);  // any item
		// alert(objpos.x + ' ' + objpos.y);
		// Set up the tooltip position and content
		tip.style.left = (objpos.x + addleft) + 'px';
		tip.style.top = (objpos.y + addtop) + 'px';
	}
	// Have it displayed after a delay of 600ms
	currentTimerHandle = window.setTimeout('displaytip()', 600);
	return true;
}


function tipflow(sublevel, addleft, addtop, text, ti, blnUp) {
	// External function - like showtip() but also handle color flow
	if (sublevel < currentflyoutsublevel) return;
	currentflyoutsublevel = (text == '') ? sublevel - 1 : sublevel;
	var obj = getElemId('flow' + ti);
	showtipwork(obj, addleft, addtop, text);
	if (!window.g_loading) {
		// alert('flow ' + ti + ' ' + cssclass);
		if (blnUp) flowupmenu(ti); else flowdownmenu(ti);
	}
	return true;
}


// END Code for custom tooltips


// Sweet little routines to scroll the page to the top or bottom
function pgtop(elem) {
	var obj = getElemId(elem);
	if (obj && typeof(obj.scrollTop) == 'number') obj.scrollTop = 0;
	else window.location.href = window.location.href;
	return;
}
function pgbot(elem) {
	var obj = getElemId(elem);
	if (obj && typeof(obj.scrollTop) == 'number') obj.scrollTop = obj.scrollHeight;
	return;
}

// More little BiR-Specifics

// Schnellsuche - Hilfe für die Eingabe der Reisenummer
function reisenrSyntax() {
	alert("Entering a tour number\n\n1.+2. characters: ISO 3166 A2 country code e.G. 'DE' for Germany\n3. character: Always '0'\n4. character: Always 'Q'\nFurther characters: Acronym for the tour name\n\nExample: Germany - Switzerland: DE0QCDCH\n\nWildcards: You can select several tours using wildcards\n    _   (Unterscore; ? works too) matches any one character\n    % (Percent sign; * works too) matches >=0 characters (any characters)\n\nA % sign will automatically be added at the end of your input.\n");
}

