/*
ajax.js - adaptiert durch Tim Reeves aus Internet-Pro 11/05,

Diese Fassung für Biblische Reisen

Stand: 2011-06-24
Stand: 2011-09-28 Added persData()
Stand: 2011-10-08 Added reiseAnfrage() etc.
Stand: 2011-10-10 Added reiseLeiter to neueReiseNr (Direktbuchung)
Stand: 2011-11-04 Corrected onloadData(), Gruppen-Schnellsuche ohne Preis, Dauer
Stand: 2011-11-06 onloadHttpState() now does nothing when status 0 returned
Stand: 2011-11-11 Plätze auf Anfrage buchbar
Stand: 2011-12-15 Compensate IE-Bug bei AnzTouren
Stand: 2011-12-22 Compensate IE-Bug bei AnzTouren - now really fixed
Stand: 2012-01-16 Einfachere Ampel-Tipptexte

THE BASIS OF ALL AJAX

window.g_loading strategy:
- Declared true at start of ajax.js (some functions exit when false)
- Declared true at start of colorflow.js (which may not be included)
- Set false at end of colorflow.js (now flow events can be accepted)
- Set true in call of popups.js::closePops() (i.e. page is unloading)
- Set true in call of startup.js::unLoadPage() (not used, AdMuncher-Event)
- So now standard body onunload event (navi.inc.php) IS "window.g_loading=true;"
- Suppresses actual tip-flowing in startup.js::tipflow() if false
- In navi.inc.php all mouseover-events are directly protected by the
  following test: if (typeof window.g_loading == 'boolean')
*/

window.g_loading = true;

window.g_has_xhr = false;
window.g_xmlhttp = null;

// This version from Sitepoint 5.10.2010
// Native XMLHttpRequest object available in IE8 does not work
// at all for local files. Solution = instantiate ActiveX first.
function getXMLHttpRequest()
{
	var request = null;

	if (typeof window.ActiveXObject != "undefined") {
		try
		{
			// Some people test for multiple versions of XMLHTTP, to try
			// to select the most recent. In my view, it's completely
			// unnecessary to instantiate advanced versions of MSXML
			// unless you specifically need their advanced features.
			request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(err) { request = null; }
	}

	if (request === null && typeof window.XMLHttpRequest != "undefined") {
		try
		{
			request = new XMLHttpRequest();
		}
		catch(err) { request = null; }
	}

	return request;
}

function getFirefox() {
	var getFF = "Am Besten holen Sie den modernen Gratis-Browser \"Firefox\" \nper DownLoad. Wollen Sie jetzt Firefox herunterladen?"
	var ans = confirm(getFF);
	if (ans == true) location.href = 'http://www.mozilla-europe.org/de/';
	return;
}

function checkBrowser() {
	var agent=navigator.userAgent;
	if (agent.indexOf('Mac') != -1 && agent.indexOf('MSIE 5') != -1){
		// MSIE on Mac is a catastrophy - not supported
		alert("Sie verwenden den MSIE 5 - Mac Browser, mit\ndem diese Website nicht korrekt dargestellt wird.");
		getFirefox();
	}
	if (!document.getElementById){
		alert("Sie verwenden ein sehr veralteter Browser, mit\ndem diese Website nicht korrekt dargestellt wird.");
		getFirefox();
	}
	return;
}

function ajaxProbe() {
	window.g_xmlhttp = getXMLHttpRequest();
	if (window.g_xmlhttp)
		window.g_has_xhr = true;
	else
		alert("AJAX-Technologie nicht vorhanden");
	return;
}

// Standard functions to delete a subtree in DOM model
function delKids(prnt)
{
	// alert('delKids: ' + prnt.nodeName + ' / ' + prnt.nodeValue);
	var c = prnt.lastChild, p;
	while (c) {
		// Note previous while last is still there!
		p = c.previousSibling;
		delTree(prnt, c);
		c = p;
	}
	return;
}

function delTree(prnt, chld)
{
	// alert('delTree:: Parent: ' + prnt.nodeName + ' / ' + prnt.nodeValue +
	// 	  ' Child: ' + chld.nodeName + ' / ' + chld.nodeValue);
	var c = chld.lastChild, p;
	while (c) {
		p = c.previousSibling;
		delTree(chld, c);
		c = p;
	}
	prnt.removeChild(chld);
	return;
}

function debugToBreadcrumbs(txt) {
	var jetzt = new Date();
	var debugTxt = jetzt.getTime() + ' ' + txt;
	var objBreadcrumbs = document.getElementById('breadcrumbs');
	delKids(objBreadcrumbs);
	var objText = document.createTextNode(debugTxt);
	objBreadcrumbs.appendChild(objText);
	return;
}


// FUNCTIONS FOR UPDATING THE LAND LIST ON CONTINENT CHANGE

// Add a single option element to a select list
function add_option(obj, optext, optval, selval)
{
	// alert("add_element: " + optext);
	var newOption = new Option(optext, optval);
	var idx = obj.options.length;
	obj.options[idx] = newOption;
	obj.options[idx].selected = (optval == selval);
	return;
}

// Insert the number of tours which match the field values
// Used by optionData() and tourData()
function set_anztouren(anz)
{
	// Compensate bugs in IE <= 8
	// debugToBreadcrumbs('"' + anz + '"');
	var anztext = (anz == ' ' || anz == '') ? ' 0 ' : ' ' + anz + ' ';
	var spanObj = document.getElementById('sanztouren');
	if (spanObj.firstChild)
		spanObj.firstChild.nodeValue = anztext;
	else {
		var textObj = document.createTextNode(anztext);
		spanObj.appendChild(textObj);
	}
}

// Rebuild a complete list of select box options
// Called when continent changes for new list of lands
// JS::get_select_data() => get_options.php?typ={k|g}_land
function optionData()
{
	var xmlDocument = window.g_xmlhttp.responseXML;
	var optval='', optext='', base=null, i=0;

	// Remove all old options from the list
	// showProps(target_select_obj.options);
	while (target_select_obj.options.length > 0) {
		if (target_select_obj.remove)
			target_select_obj.remove(0);
		else
			target_select_obj.options.remove(0);
	}
	// Add new options to list
	for (i=0; i< xmlDocument.getElementsByTagName("llopt").length; i++)
	{
		base = xmlDocument.getElementsByTagName("llopt")[i];
		optval = base.getElementsByTagName("optval")[0].childNodes[0].nodeValue;
		optext = base.getElementsByTagName("optext")[0].childNodes[0].nodeValue;
		// No option will be selected, display defaults to the first
		add_option(target_select_obj, optext, optval, '');
	}
	// Enable the listbox again if it has more than one option
	if (i>1) target_select_obj.disabled = false;

	// ANZAHL TOUREN
	if (xmlDocument.getElementsByTagName("anztouren")[0]) {
		// IE <=8 sets no childNode when the value is " "
		if (xmlDocument.getElementsByTagName("anztouren")[0].childNodes[0])
			set_anztouren(xmlDocument.getElementsByTagName("anztouren")[0].childNodes[0].nodeValue);
		else
			set_anztouren(' ');
	}

	// Remove any old message
	if (document.getElementById('toursuchemsg')) {
		var chld = document.getElementById('toursuchemsg');
		var prnt = chld.parentNode;
		delTree(prnt,chld);
		// IE positioning bug - button slips down, although posn "bottom"
		document.getElementById('panztouren').className = 'panztouren';
		document.getElementById('danztouren').className = 'danztouren';
	}

	return;
}

function optionsHttpState()
{
	if (window.g_xmlhttp.readyState == 4)
	{
		if (window.g_xmlhttp.status == 200) {
			// Daten erfolgreich geladen: starte Verarbeitung
			optionData();
		} else {
			alert("Fehler beim Abrufen der Option-XML Daten - Status " + window.g_xmlhttp.status);
			alert("Statusmeldung vom Server: " + window.g_xmlhttp.statusText);
			// alert("Debug: Url=" + document.URL + " Prefix=" + window.g_pathPrefix);
		}
	}
	return;
}

function get_select_data(select_name, url, selected_id)
{
	// select_name = name of target dropdown to get new option list
	// url         = url to call which should deliver the new option data
	// selected_id = name of dropdown calling this function - delivers index
	// UND ZWAR: get_select_data('k_land','get_options.php?typ=k_land','k_ziel');
	//     ODER: get_select_data('g_land','get_options.php?typ=g_land','g_ziel');

	// var debugTxt = "get_select_data: " + select_name + " / " + url + " / " + selected_id;
	// debugToBreadcrumbs(debugTxt);

	// Do nothing if AJAX technology not available
	if (window.g_loading) return;

	if (select_name != "") {
		target_select_obj = eval("document.forms['toursuche']." + select_name);
		// Disable the target dropdown
		target_select_obj.disabled = true;
	}
	else
		target_select_obj = null;

	if (selected_id != ""){
		url += "&sel=" + eval("document.forms['toursuche']." + selected_id + ".value");
	}
	// Get the new option list via AJAX
	if (window.g_xmlhttp) {
		// window.g_xmlhttp.open("GET", window.g_pathPrefix + "cgi-bin/" + url, true );	// Fails at Strato
		// window.g_xmlhttp.open("GET", "asien.xml", true );				 		// Works at Strato
		// 3rd parameter is true for asynchronous, false for synchronous
		window.g_xmlhttp.open("GET", window.g_pathPrefix + 'scripts/' + url, true);
		// alert("XMLHttpObject geöffnet");
		window.g_xmlhttp.onreadystatechange = optionsHttpState;
		window.g_xmlhttp.send(null);
		}
	else {
		alert("XMLHttpObject fehlt!");
	}
	return;
}


// POPULATE SCHNELLSUCHE, EMAIL-ADRESSES AND AMPEL-GRAFIKEN ON PAGE LOADING

function onMouseOverTip(e) {
	if (typeof window.g_loading == 'boolean') showtip(this, 0, 0, 0, this.rel);
};
function onMouseNameTip(e) {
	if (typeof window.g_loading == 'boolean') showtip(this, 0, 0, 0, this.name);
};
function onMouseOutTip(e) {
	if (typeof window.g_loading == 'boolean') showtip(this, 0, 0, 0, '');
};

var ampelSrc = new Array('ampel-rot.gif', 'ampel-gelb.gif',
						 'ampel-gruen.gif', 'std/empty.gif' );
var ampelAlt1 = new Array('Die Reise ',
 'In der Reise ', 'In der Reise ', 'Der Belegungsstatus der Reise ');
var ampelAlt2 = new Array(' ist abgeschlossen, ausgebucht oder abgesagt',
 ' sind Plätze auf Anfrage buchbar', ' sind noch genügend Plätze frei', ' ist unbekannt');

// 2012-01-16 BiR wollte einfachere Texte ohne Reisenr.
var ampelAlt = new Array('Buchung nicht mehr möglich',
 'Plätze auf Anfrage buchbar', 'Buchung möglich');

function setSelectedIndex(s, v) {
	for ( var i = 0; i < s.options.length; i++ ) {
		if ( s.options[i].value == v ) {
			// s.options[i].selected = true;
			s.selectedIndex = i;
			return;
		}
	}
}

function onloadData()
{
	var xmlDocument = window.g_xmlhttp.responseXML;

	// Empty text values mean there is no child node - catch them
	// alert(window.g_xmlhttp.responseText);

	// DIE VOLLTEXT-SUCHE */
	if (xmlDocument.getElementsByTagName("vtsuche")[0] && document.forms['vtsuche'])
	{
		if (xmlDocument.getElementsByTagName("vtsuche")[0].childNodes[0])
			document.forms['vtsuche'].f_vtsuche.value =
				xmlDocument.getElementsByTagName("vtsuche")[0].childNodes[0].nodeValue;
		else
			document.forms['vtsuche'].f_vtsuche.value = ' ';
	}

	/**************************/
	/* DIE REISE-SCHNELLSUCHE */
	/**************************/

	var ssd = false, ksd = false;	// Schnellsuche-Dialog, Katalogsuche-Dialog

	// LOOK FOR PRESENCE OF SCHNELLSUCHE IN XML DATA - decided in ajaxOnload()
	var anz = xmlDocument.getElementsByTagName("leiter").length;
	if (anz > 0) {
		// leiter-Tag kommt nur bei Katalogreise-Suche vor
		ssd = true;
		ksd = true;
	}
	else {
		anz = xmlDocument.getElementsByTagName("ziel").length;
		if (anz > 0) {
			// ziel-Tag kommt bei beiden Suchen vor - muss Gruppenreise-Suche sein
			ssd = true;
		}
	}

	if (ssd) {
		// Field NAMES all with "f_", so access here via the forms object is the
		// same for Katalog- and Gruppenreisen, but IDs are with "k_" or "g_".

		// AKTUELLES GEBIET (beide)
		obj = document.forms['toursuche'].f_ziel;
		welches = xmlDocument.getElementsByTagName('ziel')[0].childNodes[0].nodeValue;
		setSelectedIndex(obj, welches);

		// DIE LÄNDERLISTE (beide)
		var land_list_obj = document.forms['toursuche'].f_land;
		welches = xmlDocument.getElementsByTagName('land')[0].childNodes[0].nodeValue;
		// Remove all old options from the list
		// showProps(target_select_obj.options);
		while (land_list_obj.options.length > 0) {
			if (land_list_obj.remove)
				land_list_obj.remove(0);
			else
				land_list_obj.options.remove(0);
		}
		// Add new options to the list
		for (i=0; i< xmlDocument.getElementsByTagName('llopt').length; i++)
		{
			obj = xmlDocument.getElementsByTagName('llopt')[i];
			optval = obj.getElementsByTagName('optval')[0].childNodes[0].nodeValue;
			optext = obj.getElementsByTagName('optext')[0].childNodes[0].nodeValue;
			add_option(land_list_obj, optext, optval, welches);
		}
		// Enable the listbox if it has more than one option
		land_list_obj.disabled = (i>1) ? false : true;

		// ANZAHL TOUREN (beide)
		if (xmlDocument.getElementsByTagName("anztouren")[0]) {
			// IE <=8 sets no childNode when the value is " "
			if (xmlDocument.getElementsByTagName("anztouren")[0].childNodes[0])
				set_anztouren(xmlDocument.getElementsByTagName("anztouren")[0].childNodes[0].nodeValue);
			else
				set_anztouren(' ');
		}

		if (ksd) {
			// Katalogreisen-Suche

			// MAX. PREIS (beide)
			obj = document.forms['toursuche'].f_maxpreis;
			welches = xmlDocument.getElementsByTagName('maxpreis')[0].childNodes[0].nodeValue;
			setSelectedIndex(obj, welches);

			// REISEDAUER (beide)
			obj = document.forms['toursuche'].f_dauer;
			welches = xmlDocument.getElementsByTagName('dauer')[0].childNodes[0].nodeValue;
			setSelectedIndex(obj, welches);

			// REISELEITER
			obj = document.forms['toursuche'].f_leiter;
			welches = xmlDocument.getElementsByTagName('leiter')[0].childNodes[0].nodeValue;
			setSelectedIndex(obj, welches);

			// ATTRIBUT
			obj = document.forms['toursuche'].f_attrib;
			welches = xmlDocument.getElementsByTagName('attrib')[0].childNodes[0].nodeValue;
			setSelectedIndex(obj, welches);

			// FRÜHESTER ABREISE
			if (xmlDocument.getElementsByTagName("abdatum")[0])
				document.forms['toursuche'].f_abdatum.value =
					xmlDocument.getElementsByTagName("abdatum")[0].childNodes[0].nodeValue;

			// SPÄTESTER RÜCKREISE
			if (xmlDocument.getElementsByTagName("rueckdatum")[0])
				document.forms['toursuche'].f_rueckdatum.value =
					xmlDocument.getElementsByTagName("rueckdatum")[0].childNodes[0].nodeValue;

		}

	}

	/**************************/
	/* END REISE-SCHNELLSUCHE */
	/**************************/

	// REISELEITER VOR- UND NACHNAME (falls Seite mit RL-Suche)
	if (document.forms['leitersuche']) {
		if (xmlDocument.getElementsByTagName("rlvorname")[0] &&
			xmlDocument.getElementsByTagName("rlvorname")[0].childNodes[0])
			document.forms['leitersuche'].f_rlvorname.value =
				xmlDocument.getElementsByTagName("rlvorname")[0].childNodes[0].nodeValue;
		if (xmlDocument.getElementsByTagName("rlnachname")[0] &&
			xmlDocument.getElementsByTagName("rlnachname")[0].childNodes[0])
			document.forms['leitersuche'].f_rlnachname.value =
				xmlDocument.getElementsByTagName("rlnachname")[0].childNodes[0].nodeValue;
	}

	// ALLE BUCHBARKEITSICONS EINSETZEN
	var rsnr = '', ampl = '', indx, obja;
	anz = xmlDocument.getElementsByTagName("reise").length;
	// alert(anz + ' Touren gefunden auf der Seite');
	for (i=0; i<anz; i++)
	{
		rsnr = xmlDocument.getElementsByTagName("reise")[i].childNodes[0].firstChild.data;
		ampl = xmlDocument.getElementsByTagName("reise")[i].childNodes[1].firstChild.data;
		indx = ampl == 'r' ? 0 : ampl == 'y' ? 1 : ampl == 'g' ? 2 : 3;
		// alert(rsnr + ': ' + ampl + ' / ' + indx);
		obja = document.getElementById('ampel' + (i+1));
		obja.src = window.g_pathPrefix + 'images/' + ampelSrc[indx];
		// tooltip = ampelAlt1[indx] + rsnr + ampelAlt2[indx];
		tooltip = ampelAlt[indx];
		obja.setAttribute('name', tooltip);
		obja.onmouseover = onMouseNameTip;
		obja.onmouseout = onMouseOutTip;
		if (ampl == 'r' && obja.nextSibling) {
			var chld = obja.nextSibling;	// Probably a junk text node
			if (chld.nodeName != 'A') chld = chld.nextSibling;
			// ALT: Nicht-buchbare Touren haben keinen "Buchen" Verweis, ggf. entfernen
			// var prnt = obja.parentNode;
			// delTree(prnt,chld);
			// NEU: Rot => "Anfragen" statt "Buchen", sonst gleich (direktbuchung)
			chld.setAttribute('name', 'Diese Reise trotzdem anfragen');
			chld.onmouseover = onMouseNameTip;
			chld.firstChild.data = 'Anfragen';
		}
	}

	// ETWAIGE EMAIL-ADRESSEN EINSETZEN
	var nr = '', link='', title='', subject='', href='';
	var textObj=null, linkObj=null, spanObj=null;
	anz = xmlDocument.getElementsByTagName("email").length;
	for (var i=0; i<anz; i++)
	{
		// Hier zählt 'i' lediglich durch die Antworten, doch
		// <nr> bezieht sich korrekterweise auf die Anfrage!!
		nr = xmlDocument.getElementsByTagName("email")[i].childNodes[0].firstChild.data;
		// childNodes[1] = ID => not needed (but good for debugging :)
		link = xmlDocument.getElementsByTagName("email")[i].childNodes[2].firstChild.data;
		show = xmlDocument.getElementsByTagName("email")[i].childNodes[3].firstChild.data;
		title = xmlDocument.getElementsByTagName("email")[i].childNodes[4].firstChild.data;
		subject = xmlDocument.getElementsByTagName("email")[i].childNodes[5].firstChild.data;
		href = subject == '' ? 'mailto:' + link
							 : 'mailto:' + link + '?subject=' + subject;
		// A title-Attribute in the img-Tag has precedence as visible link text
		spanObj = document.getElementById('email' + nr);
		imgObj = spanObj.firstChild;
		imgTitle = imgObj.getAttribute('title');
		if (imgTitle != null && imgTitle != '') show = imgTitle;
		// alert(show + ' / ' + link);
		// Prepare the new link object
		textObj = document.createTextNode(show);
		linkObj = document.createElement('a');
		linkObj.setAttribute('href',href);
		if (title != '' && title != ' ' && title != '&nbsp;' && title != 'notip') {
			linkObj.setAttribute('rel', title);
			linkObj.onmouseover = onMouseOverTip;
			linkObj.onmouseout = onMouseOutTip;
		}
		// Nun Grafik aushängen und Link einhängen
		delKids(spanObj);
		spanObj.appendChild(linkObj);
		// MSIE mag es nicht wenn der Textknoten vor dem Einhängen angehängt wird
		spanObj.childNodes[0].appendChild(textObj);
	}

	return;
}


function onloadHttpState()
{
	if (window.g_xmlhttp.readyState == 4)
	{
		if (window.g_xmlhttp.status == 200) {
			// Daten erfolgreich geladen: starte Verarbeitung
			onloadData();
		}
		else if (window.g_xmlhttp.status == 0) {
			// This comes too often to be displayed. In Blogs suggested causes:
			// - I believe the error code indicates that the response was empty,
			//   (as not even headers were returned). This means the connection was
			//   accepted and then closed gracefully (TCP FIN). There are a number
			//   of things which could cause this, but based on your description,
			//   some form of firewall seems the most likely culprit.
			// - We've found a status code of "0" usually means the user
			//   navigated to a different page before the AJAX call completed.
		}
		else {
			alert("Fehler beim Abrufen der Onload-XML Daten - Status " + window.g_xmlhttp.status);
			alert("Statusmeldung vom Server: " + window.g_xmlhttp.statusText);
		}
	}
	return;
}

// This is called at the <body onload> event of EVERY page
function ajaxOnload() {
	checkBrowser();
	ajaxProbe();
	if (window.g_loading || !window.g_has_xhr) return;
	var ziel='', curid='', touren='', emails='', sep='?', i, id, obj;
	// If page contains Reiseleitersuche then note initial values
	obj = document.getElementById('s_rlvorname');
	if (obj) {
		window.rlvorname = obj.value;
		// alert('RL-Vorname: ' + window.rlvorname);
	}
	obj = document.getElementById('s_rlnachname');
	if (obj) {
		window.rlnachname = obj.value;
		// alert('RL-Nachname: ' + window.rlnachname);
	}
	// Note if the calling page is within the katalogreisen or gruppenreisen
	var pagepath = window.location.href;	// PathSep always "/"
	if (pagepath.indexOf('/katalogreisen/') != -1) {
		ziel = sep + 'ziel=k';
		sep = '&';
	}
	else
	if (pagepath.indexOf('/gruppenreisen/') != -1) {
		ziel = sep + 'ziel=g';
		sep = '&';
	}
	// Get a list of all the Tour Numbers on the page
	// They are the text content of cells with id's like "tournr<n>"
	for (i=1; true; i++) {
		curid = 'tournr' + i;
		obj = document.getElementById(curid);
		if (obj && document.getElementById('ampel' + i)) {
			touren += sep + curid + '=' + obj.firstChild.nodeValue;
			sep = '&';
		}
		else break;
	}
	// Get a list of all the Email Numbers on the page
	// They are the content of span-elements with id's like "email<n>"
	for (i=1; true; i++) {
		curid = 'email' + i;
		obj = document.getElementById(curid);
		if (obj) {
			// Use id-Attr of img-Tag if set (legacy convention), otherwise alt-Attr
			// alt-Attr is better because it allows the same value more than once
			id = obj.firstChild.id;
			if (!id || id == '') id = obj.firstChild.alt;
			emails += sep + curid + '=' + id;
			sep = '&';
		}
		else break;
	}
	// Call "onload.php" on the server to return the email
	// values and insert them into the displayed page
	var url = window.g_pathPrefix + 'ajax/onload.php' + ziel + touren + emails;
	// alert(url);
	// debugToBreadcrumbs(url);
	window.g_xmlhttp.open("GET", url, true);
	window.g_xmlhttp.onreadystatechange = onloadHttpState;
	window.g_xmlhttp.send(null);
	return;
}

function onStartupHttpState()
{
	if (window.g_xmlhttp.readyState == 4)
	{
		if ( window.g_xmlhttp.status == 200) {
			// do nothing - the fact of JavaScript is noted in the session
			// alert("JavaScript OK");
		} else {
			alert("Fehler beim Abrufen der Startup-XML Daten - Status " + window.g_xmlhttp.status);
			alert("Statusmeldung vom Server: " + window.g_xmlhttp.statusText);
		}
	}
	return;
}

// This is called by startup.js / startUp() ONLY at the start of each PHP-Session
function ajaxStartUp() {
	checkBrowser();
	ajaxProbe();
	if (window.g_loading || !window.g_has_xhr) return;
	window.g_xmlhttp.open("GET", window.g_pathPrefix + 'ajax/startup.php', true);
	window.g_xmlhttp.onreadystatechange = onStartupHttpState;
	window.g_xmlhttp.send(null);
	return;
}


function dummyHttp() { return; }


// This is called by logingeneral.php.inc::writeShowFileLink(),
// it has already encoded the "target" parameter for direct use
function ajaxCount(target) {
	if (!window.g_has_xhr) ajaxProbe();
	if (!window.g_has_xhr || window.g_loading) return;
	var url = window.g_pathPrefix + 'ajax/webcount.php?tgt=' + target;
	// alert('ajaxCount: ' + url);
	window.g_xmlhttp.open("GET", url, true);
	window.g_xmlhttp.onreadystatechange = dummyHttp;
	window.g_xmlhttp.send(null);
	return;
}


window.g_winSizeTimerHandle = null;

// This is a sub-function to ajaxWindowSize()
function reportWinSizeViaXhr(strUrl, strValue) {
	window.g_xmlhttp.open("GET", strUrl, true);
	window.g_xmlhttp.onreadystatechange = dummyHttp;
	window.g_xmlhttp.send(null);
	window.g_win_size = strValue;
	window.g_winSizeTimerHandle = null;
	return;
}

// This is called by startup.js::neuAufbau() to report current sizes to server
function ajaxWindowSize(strParam, strValue) {
	if (!window.g_has_xhr) ajaxProbe();
	if (!window.g_has_xhr || window.g_loading) return;
	// Don't report if the current value matches the one at the server
	if (window.g_win_size == strValue) return;
	// Put the URL for XHR together
	var strUrl = window.g_pathPrefix + 'ajax/windowsize.php?' + strParam + '=' + strValue;
	// alert('ajaxWindowSize: ' + strUrl);
	if (window.g_reportWindowSize) {
		// Someones first call of the website
		reportWinSizeViaXhr(strUrl, strValue);
		window.g_reportWindowSize = false;
	}
	else {
		// Report via Timer to avoid multiple XHR during resizing
		var strCall = "reportWinSizeViaXhr('" + strUrl + "','" + strValue + "')";
		// Clear any superceded outstanding call
		if (window.g_winSizeTimerHandle != null)
			window.clearTimeout(window.g_winSizeTimerHandle);
		window.g_winSizeTimerHandle = window.setTimeout(strCall, 500);
	}
	return;
}

// THE FUNCTIONS TO UPDATE SERVER SESSION VARS ON SINGLE FIELD CHANGE

/*  Whenever the user changes a field value (in either form) then the
	new value is sent to the server and put in the session variables -
	which involves getting at least a small return document from the server.
	However, when the form is submitted this action is not required - in fact,
	a document would be returned to a page which no longer exists, so we want
	to suppress the onChange action when the event which triggers the onChange
	is the form submission. This in turn is caused by EITHER
	- the user is in a text input field and hits ENTER, or
	- he or she clicks on the submit button.
	In both cases the onChange happens BEFORE the onSubmit, so we have to
	add a small delay to the onChange action, and then not do it if we find
	we are at that time submitting the form.
	Note that onChange is triggered by onMouseDown on the submit button -
	it'll come up again and be a click soon enough! If we would wait for the
	onClick event we would have to wait too long - an indefinite period as the
	user may "sit" on the mouse button!
*/

var nowSubmitting = '';

function setNowSubmitting(typ) {
	// Note a form submission to suppress the onchange action - see neuWert()
	window.nowSubmitting = typ;
	// alert("setnowSubmitting: " + typ);
	return true;
}


// Decode the answer to a changed field value in the "Schnellsuche"
function tourData()
{
	// alert(window.g_xmlhttp.responseText);
	var xmlDocument = window.g_xmlhttp.responseXML;
	// Check for a value MODIFIED (e.g. rejected) by set_formval.php
	if (xmlDocument.getElementsByTagName("FLD")[0]) {
		// This can currently only be a normalised or rejected date
		var fld = xmlDocument.getElementsByTagName("FLD")[0].childNodes[0].nodeValue;
		var val = xmlDocument.getElementsByTagName("VAL")[0].childNodes[0].nodeValue;
		document.getElementById(fld).value = val;
	}
	// ANZAHL TOUREN - Insert the number of matching tours behind the button
	if (xmlDocument.getElementsByTagName("anztouren")[0])
	   set_anztouren(xmlDocument.getElementsByTagName("anztouren")[0].childNodes[0].nodeValue);
	// Display any message above the Schnellsuche
	if (xmlDocument.getElementsByTagName("MSG")[0]) {
		var msg='';
		msg = xmlDocument.getElementsByTagName("MSG")[0].childNodes[0].nodeValue;
		// Insert the message as first child of div#schnellsuche
		if (document.getElementById('toursuchemsg')) {
			var chld = document.getElementById('toursuchemsg');
			chld.firstChild.data = msg;
		}
		else {
			var myNode = document.createElement("p");
			// Give it the id attribute
			myNode.setAttribute('id', 'toursuchemsg');
			// Append the text node for the link
			var myText = document.createTextNode(msg);
			myNode.appendChild(myText);
			// Insert it into the DOM before the headline
			var prnt = document.getElementById('schnellsuche');
			var sblg = prnt.firstChild;
			prnt.insertBefore(myNode,sblg);
			// IE positioning bug - button slips up, although posn "bottom"
			document.getElementById('panztouren').className = 'panztouren';
			document.getElementById('danztouren').className = 'danztouren';
		}
	}
	else {
		// Remove any old message
		if (document.getElementById('toursuchemsg')) {
			var chld = document.getElementById('toursuchemsg');
			var prnt = chld.parentNode;
			delTree(prnt,chld);
			// IE positioning bug - button slips down, although posn "bottom"
			document.getElementById('panztouren').className = 'panztouren';
			document.getElementById('danztouren').className = 'danztouren';
		}
	}
	return;
}

// Preview of the matching Reiseleiter / Mitarbeiter as user types name in
function persData()
{
	// alert(window.g_xmlhttp.responseText);
	var xmlDocument = window.g_xmlhttp.responseXML;
	// We only get search results if there is at least one input char
	if (xmlDocument.getElementsByTagName("zuwenigzeichen")[0]) {
		// Make the result panel invisible
		document.getElementById('persergebnisse').style.display="none";
		// And the standard panel visible
		document.getElementById('col2').style.display="block";
		return;
	}
	// Prepare the content in the result panel
	var persname='', persrlid='', i=0, obj=null;
	var myNode=null, myText=null;
	var hitliste = document.getElementById('hitliste');
	var anzhits = xmlDocument.getElementsByTagName("pers").length;
	// alert(anzhits);
	if (document.getElementById('s_mavorname')) {
		var vn = 's_mavorname';
		var nn = 's_manachname';
	}
	else {
		var vn = 's_rlvorname';
		var nn = 's_rlnachname';
	}
	if (anzhits == 0) {
		document.getElementById(vn).style.backgroundColor = '#FFE4E4';
		document.getElementById(nn).style.backgroundColor = '#FFE4E4';
	}
	else if (anzhits == 1) {
		document.getElementById(vn).style.backgroundColor = '#E8F1E3';
		document.getElementById(nn).style.backgroundColor = '#E8F1E3';
	}
	else {
		document.getElementById(vn).style.backgroundColor = '';
		document.getElementById(nn).style.backgroundColor = '';
	}
	// First delete the previous content
	delKids(hitliste);
	// Now add a link for each person found
	for (i=0; i<anzhits; i++)
	{
		obj = xmlDocument.getElementsByTagName("pers")[i];
		persrlid = obj.getElementsByTagName("rlid")[0].childNodes[0].nodeValue;
		persname = obj.getElementsByTagName("name")[0].childNodes[0].nodeValue;
		perslang = obj.getElementsByTagName("lang")[0].childNodes[0].nodeValue;
		if (i>0) {
			// Add a <br /> Element so each Person on a new line
			myNode = document.createElement("br");
			hitliste.appendChild(myNode);
		}
		myText = document.createTextNode(persname);

		// Append the popup link node
		myNode = document.createElement("a");
		// Give it the href attribute
		var href = "javascript:openRlPop('" + persrlid + "', '" +
					perslang + "');";
		myNode.setAttribute('href', href);
		myNode.setAttribute('onmouseover',
		"if (typeof window.g_loading == 'boolean') { showtipwork(null, 0, 0, 'Mehr zu " +
		perslang + "...'); }");
		myNode.setAttribute('onmouseout',
		"if (typeof window.g_loading == 'boolean') { showtipwork(null, 0, 0, ''); }");
		// The following is more puristic for attributes, but IE5.5 can't
		// myAttr = document.createAttribute("href");
		// myAttr.nodeValue = href;
		// myNode.setAttributeNode(myAttr);
		// Append the text node for the link
		myNode.appendChild(myText);

		// Append it to the results
		hitliste.appendChild(myNode);
	}
	if (i == 0) {
		myText = document.createTextNode('Keine Treffer.');
		hitliste.appendChild(myText);
	}
	// Make the standard panel invisible
	document.getElementById('col2').style.display = "none";
	// and the result panel visible
	document.getElementById('persergebnisse').style.display = "block";
	return;
}

function ajaxFehler()
{
	alert("Fehler beim Notieren des neuen Feldwertes - Status " + window.g_xmlhttp.status);
	alert("Statusmeldung vom Server: " + window.g_xmlhttp.statusText);
	return;
}

function tourWertHttpState()
{
	if (window.g_xmlhttp.readyState == 4)
	{
		if ( window.g_xmlhttp.status == 200) {
			// daten erfolgreich geladen: starte Verarbeitung
			tourData();
		}
		else ajaxFehler();
	}
	return;
}

function vtsWertHttpState()
{
	if (window.g_xmlhttp.readyState == 4)
	{
		if ( window.g_xmlhttp.status == 200) {
			// Antwort erfolgreich - es gibt jedoch keine lokale Verarbeitung
			return;
		}
		else ajaxFehler();
	}
	return;
}

function persWertHttpState()
{
	if (window.g_xmlhttp.readyState == 4)
	{
		if ( window.g_xmlhttp.status == 200) {
			// daten erfolgreich geladen: starte Verarbeitung
			persData();
		}
		else ajaxFehler();
	}
	return;
}

function neuWert(typ, fld) {
	// Pass a new form field value to it's session variable via AJAX
	// But don't do it if the form is being submitted anyway
	// Since onchange() and onkeyup() are called BEFORE onsubmit(), we must wait...
	// Bekannte Typen: 'v' => Volltextsuche; 't' => Toursuche; 'r' => Reiseleiter
	//                 'm' => Mitarbeiter
	// var debugTxt = "neuWert: " + typ + " für " + fld.id + ", nowSubmitting=" + window.nowSubmitting;
	// alert(debugTxt);		// Triggers onBlur
	// debugToBreadcrumbs(debugTxt);
	if (window.g_loading) return;
	// When reacting on field input: Quietly do nothing if the value is unchanged
	// I mean onkeyup - we react to every change while in the field
	if (typ == 'r') {
		if (fld.id == 's_rlvorname') {
			if (window.rlvorname && window.rlvorname == fld.value) {
				// alert('Vorname unverändert: ' + window.rlvorname);
				return;
			}
			window.rlvorname = fld.value;
		}
		else {
			if (window.rlnachname && window.rlnachname == fld.value) {
				// alert('Nachname unverändert: ' + window.rlnachname);
				return;
			}
			window.rlnachname = fld.value;
		}
	}
	// We can't pass an object to setTimeout(), so pass the id
	var aufruf = "neuWertWaited('" + typ + "','" + fld.id + "')";
	window.setTimeout(aufruf,5);
	return;
}

function neuWertWaited(typ, fldid) {
	// alert("neuWertWaited: " + typ + " für " + fldid + ", nowSubmitting=" + window.nowSubmitting);
	if (typ == window.nowSubmitting || window.g_loading) return;
	window.g_xmlhttp = getXMLHttpRequest();
	// Call "set_formval.php" on the server to note new field value
	// It gets the tag id === session index, e.g. 'k_ziel' or 'g_land'
	// Note that the response can be ignored for a VollTextSuche
	var fld = document.getElementById(fldid);
	var url = window.g_pathPrefix + 'scripts/set_formval.php?fld=' +
			  fldid + '&val=' + encodeURIComponent(fld.value);
	window.g_xmlhttp.open("GET", url, true);
	// BIR has Reiseleiter- but not (yet) Mitarbeiter-Suche
	if (fldid == 's_rlvorname' || fldid == 's_rlnachname' ||
		fldid == 's_mavorname' || fldid == 's_manachname')
		// Send a request for Reiseleiter- or HauserTeam-Felder
		window.g_xmlhttp.onreadystatechange = persWertHttpState;
	else
		// A request for Volltext- oder Toursuche
		window.g_xmlhttp.onreadystatechange =
				fldid == "s_vtsuche" ? vtsWertHttpState : tourWertHttpState;
	window.g_xmlhttp.send(null);
	return;
}

// This populates the Reisedaten as per ReiseNr. in the booking form
function reiseDaten() {
	var xmlDocument = g_xmlhttp.responseXML;
	// alert(g_xmlhttp.responseText);
	var rsnr = xmlDocument.getElementsByTagName('rn')[0].firstChild.data;
	var titel = xmlDocument.getElementsByTagName('titel')[0].firstChild.data;
	var spanObj = document.getElementById('reiseShow');	// Text about Reise
	var textObj = document.createTextNode(titel);	// All cases: reisedaten.php
	var euroObj = document.getElementById('euro');
	var rsnrObj = document.getElementById('reisenummer');	// RN input field
	var land = '', von = '', bis = '', preis = '', leiter = 'N.N.', leitid = '-1';
	delKids(spanObj);
	if (rsnr == '-') {
		euroObj.style.visibility = "hidden";
		rsnrObj.className = 'loginField weissefarbe';
		spanObj.appendChild(textObj);
	}
	else {
		land = xmlDocument.getElementsByTagName('land')[0].firstChild.data;
		if (land == '-') {
			// We got no data
			land = '';
			spanObj.appendChild(textObj);
			euroObj.style.visibility = "hidden";
			rsnrObj.className = 'loginField fehlerfarbe';
		}
		else {
			// Link einsetzen
			linkObj = document.createElement('a');
			linkObj.setAttribute('href', xmlDocument.getElementsByTagName('file')[0].firstChild.data);
			linkObj.setAttribute('rel', 'Zur Reisebeschreibung');
			linkObj.onmouseover = onMouseOverTip;
			linkObj.onmouseout = onMouseOutTip;
			spanObj.appendChild(linkObj);	// <a> is first <span> child
			// MSIE mag es nicht wenn der Textknoten vor dem Einhängen angehängt wird
			spanObj.childNodes[0].appendChild(textObj);	// Linked text
			// Append an Ampel-Grafik, with tip
			var ampl = xmlDocument.getElementsByTagName('ampel')[0].firstChild.data;
			ampl = ampl.toLowerCase();
			var indx = ampl == 'r' ? 0 : ampl == 'y' ? 1 : ampl == 'g' ? 2 : 3;
			obja = document.createElement('img');
			obja.setAttribute('height', '12');
			obja.setAttribute('width', '46');
			obja.setAttribute('src', window.g_pathPrefix + 'images/' + ampelSrc[indx]);
			var attrName = (isIE6 || isIE7) ? 'className' : 'class';
			obja.setAttribute(attrName, 'reiseampel');
			obja.setAttribute('alt', '');
			var tooltip = ampelAlt1[indx] + rsnr + ampelAlt2[indx];
			obja.setAttribute('name', tooltip);
			obja.onmouseover = onMouseNameTip;
			obja.onmouseout = onMouseOutTip;
			spanObj.appendChild(obja);	// <img> is second <span> child
			// The rest of the visible output
			rsnrObj.className = 'loginField weissefarbe';
			euroObj.style.visibility = "visible";
			von = xmlDocument.getElementsByTagName('von')[0].firstChild.data;
			bis = xmlDocument.getElementsByTagName('bis')[0].firstChild.data;
			preis = xmlDocument.getElementsByTagName('preis')[0].firstChild.data + ',-';
			leitid = xmlDocument.getElementsByTagName('leitid')[0].firstChild.data;
			leiter = xmlDocument.getElementsByTagName('leiter')[0].firstChild.data;
		}
	}
	textObj = document.getElementById('reiseland');
	textObj.innerHTML = land;
	textObj = document.getElementById('reiseleiter');
	textObj.innerHTML = leiter;
	if (leitid == '-1') {
		textObj.setAttribute( 'href',
				"javascript:alert('Reiseleitung steht noch nicht fest');" );
		textObj.setAttribute( 'onmouseover',
			"if (typeof window.g_loading == 'boolean') " +
			"{ showtipwork(null, 0, 0, 'Reiseleitung steht noch nicht fest'); }" );
	}
	else {
		textObj.setAttribute( 'href', "javascript:openRlPop('" +
				leitid + "','" + leiter + "');" );
		textObj.setAttribute( 'onmouseover',
			"if (typeof window.g_loading == 'boolean') " +
			"{ showtipwork(null, 0, 0, 'Mehr zu " + leiter + "...'); }" );
	}
	textObj = document.getElementById('reisevon');
	textObj.value = von;
	textObj = document.getElementById('reisebis');
	textObj.value = bis;
	textObj = document.getElementById('reisepreis');
	textObj.value = preis;
	return;
}

function reiseDatenHttpState() {
	if (g_xmlhttp.readyState == 4) {
		if ( g_xmlhttp.status == 200) {
			// Daten erfolgreich geladen: starte Verarbeitung
			reiseDaten();
		} else {
			alert("Fehler beim Abrufen der Reisedaten - Status " + g_xmlhttp.status);
			alert("Statusmeldung vom Server: " + g_xmlhttp.statusText);
		}
	}
	return;
}

// This is called at onBlur() of the reisenr-Field of the booking form
function neueReiseNr(val) {
	if (window.g_loading) return;
	g_xmlhttp = getXMLHttpRequest();
	// Call "reisedaten.php" on the server
	var url = '../scripts/reisedaten.php?rn=' + val;
	g_xmlhttp.open("GET", url, true);
	g_xmlhttp.onreadystatechange = reiseDatenHttpState;
	g_xmlhttp.send(null);
	return;
}

function reiseAnfrageHttpState() {
	if (g_xmlhttp.readyState == 4) {
		if (g_xmlhttp.status == 200) {
			// Daten erfolgreich gesetzt in der Session: Jump!
			window.location.href = '../../gruppenreisen/angebotsanfrage.php';
		} else {
			alert("Fehler beim Setzen der Reisedaten - Status " + g_xmlhttp.status);
			alert("Statusmeldung vom Server: " + g_xmlhttp.statusText);
		}
	}
	return;
}

// This is called via the Angebotsanfrage-Link at the head of each Gruppen-DP
function reiseAnfrage(rsnr) {
	if (window.g_loading) return;
	window.g_xmlhttp = getXMLHttpRequest();
	// Call "set_formval.php" on the server to note new Reisedaten
	var url = window.g_pathPrefix + 'scripts/set_formval.php?fld=programmnr' +
			  '&val=' + encodeURIComponent(rsnr);
	window.g_xmlhttp.open("GET", url, true);
	window.g_xmlhttp.onreadystatechange = reiseAnfrageHttpState;
	window.g_xmlhttp.send(null);
	return;
}

