/*******************************************************************************
 * 
 * $HeadURL: svn://192.168.99.42/objects/js/ferienhaus.js $ (UTF-8)
 *
 * @author $Author:joerg.thoennissen $
 * 
 * $Id: ferienhaus.js 708 2008-06-02 16:17:53Z joerg.thoennissen $
 * 
 * $Date: 2008-06-02 18:17:53 +0200 (Mo, 02 Jun 2008) $
 * 
 * Description:
 * 
 * 		Wahres Wissen beruht auf Erfahrung, alles andere ist nur Information. 
 * 		(Albert Einstein)
 *
 * Revision:
 * 2008-08-17	Initiale Version.
 *
 ******************************************************************************/  



function showProcessing() {
	myProcess.process(true);
}



function hideProcessing() {
	myProcess.process();
}



function message(type, text) {
	topOfPage();

	if ($('message') == null) {
		$('innerContent').insert({ 'top': '<div id="message" class="message"></div>' });
	}

	(function(){	
		if (type) {
			$('message').removeClassName('message').removeClassName('information');
			$('message').removeClassName('warning').removeClassName('critical');			
			$('message').addClassName((type.length > 0) ? type : 'information');			
		}
		if (text && (text.length > 0)) {
			$('message').update(text);
		}

		$('message').show();
	
		($('message').visible()) ? Effect.Pulsate('message', { pulses: 7 }) 
								 : Effect.Appear('message');
	}).defer();
}




var map = {
    //----------------- properties -------------------
    //
    regions: [], // integer-Werte der in der Map vorhandenen Regionen (RegionCode)

    //----------------- methods ----------------------
    //
    setCountry: function() {
		var iso2CountryCode = search.getParam('iso2CountryCode').strip();
        this.regions = new Array();

        if ((iso2CountryCode == '') || (!$('map' + iso2CountryCode))) {
            $('mapImage').src = '../objects/icons/blank.gif'
            $('mapImage').useMap = '';
            $('map').setStyle({ backgroundImage: 'url("../objects/icons/blank.gif")' });
        } else {
            $('mapImage').src = '../objects/images/maps/' + iso2CountryCode + '/r00.gif';
            $('mapImage').useMap = '#map' + iso2CountryCode;
            $('map').setStyle({ backgroundImage: 'url("../objects/images/maps/'
                                           + iso2CountryCode + '/r00.gif")' });
        }
		
		// Ist das search.regions-Array bereits bestückt, erfolgt die Übernahme in map.regions
		if (search.regions && search.regions.length > 0) {			
			map.setRegions();
			// Markiere die angewählte Region, falls ein RegionCode angewählt wurde  
			if ((+search.regionCode) > 0) {
				map.setRegionCode((+search.regionCode));
			}
		}
	},

	setRegions: function() {
		var iso2CountryCode = search.getParam('iso2CountryCode').strip();

        if ((iso2CountryCode != '') && (!!$('map' + iso2CountryCode))) {		
	        var areas = $('map' + iso2CountryCode).getElementsByTagName('area');

	        for (var i = 0; i < areas.length; i++) {
    	        if (((+areas[i].alt) > 0) || ((+areas[i].name) > 0)) {
        	        for (var j = 0, len = search.regions.length; j < len; j++) {
            	        if ((search.regions[j].Released) &&
							((search.regions[j].RegionCode == (+areas[i].alt)) ||
                    	     (search.regions[j].RegionCode == (+areas[i].name)))) {
                        	this.regions[this.regions.length] = search.regions[j].RegionCode;
	                        areas[i].name = search.regions[j].RegionCode;
    	                    areas[i].alt = search.regions[j].RegionName;
        	                areas[i].title = search.regions[j].RegionName;
            	            areas[i].href = "javascript:map.clicked('" 
										  + search.regions[j].RegionCode + "');";
                    	    break;
	                    }
        	        }
    	            if (j == len) {
            	        areas[i].parentNode.removeChild(areas[i]);
                	    i--;
	                }
    	        } else {
        	        areas[i].parentNode.removeChild(areas[i]);
            	    i--;
	            }
			}
        }
    },

    //
    clicked: function(regionCode) {
        var regionCodeSelect = $('regionCode');
        if (regionCode != (+regionCodeSelect.value)) {
            // if the regionCode differs from the select-value, then
            // search regionCode in the options for the selectIndex
            for (var i = 0, len = regionCodeSelect.length; i < len; i++) {
                if (regionCode == (+regionCodeSelect.options[i].value)) {
                    // select the regionCode in the select-Element
                    regionCodeSelect.selectedIndex = i;
                    search.regionCodeSelected();
                    break;
                }
            }
        }
    },

    //
    onMouseOver: function(regionCode) {
		// Den regionCode für den img.src in einen mindestens zweistelligen, mit führenden
		// Nullen versehenen String umwandeln.
		// Die Funktion kann mit String oder Number aufgerufen werden.
		var iso2CountryCode = search.getParam('iso2CountryCode').strip();
        if (iso2CountryCode != '') {
	        $('mapImage').src = '../objects/images/maps/' + iso2CountryCode 
							  + '/r' + (+regionCode).toPaddedString(2) + '.gif';
		}
    },

    //
    onMouseOut: function() {
        this.setRegionCode(search.regionCode);
    },

    setRegionCode: function(regionCode) {
        for (var i = 0, len = this.regions.length; i < len; i++) {
            if (regionCode == this.regions[i]) {
                break;
            }
        }
        this.onMouseOver(((i == this.regions.length) ? 0 : regionCode));
    }
}



var search = {
    //----------------- properties -------------------
    //
    countries: [],
    regions: [],
    places: [],
    count: -1,
    regionCode: -1,
    placeCode: -1,
    subRegions: [],

    //----------------- methods ----------------------
    //
    // prepare tab, all elements and actions to display the 'search'-tab
	setTitle: function(title, h1) {
		$('header').select('h1')[0].update((!!h1) ? h1 : title);
		document.title = title;	
	},
	
    init: function(responseJSON) {
		// Aktiviere die Überwachung der aktiven Formfelder, falls diese bereits geladen sind
		($('searchCriterias') != null) && search.observe();

		if (!!responseJSON) {
			// Bestücke den Title im Dokument und im Header-Bereich des Contents
			search.setTitle(responseJSON.title);
			
			// Bestücke die Ergebnisanzahl aus dem responseJSON-Ergebnis
			search.updateCount(responseJSON.resultCount);	

			// Liegen die search-Werte als responseJSON Variablen vor, werden diese übernommen  
			search.countries = responseJSON.countries;
			search.regions = responseJSON.regions;
			search.subRegions = responseJSON.subRegions;
			search.places = responseJSON.places;
		} else {
			// Bestücke die Ergebnisanzahl aus dem 'count'-Element (von <i> umschlossen)
			var count = $('count').down();
			search.count = (count) ? (+count.innerHTML) : -1;

			// Liegen die search-Werte als globale Variablen vor, werden diese übernommen  
			search.countries = (typeof (countries) != 'undefined') ? countries : new Array();
			search.regions = (typeof (regions) != 'undefined') ? regions : new Array();
			search.places = (typeof (places) != 'undefined') ? places : new Array();
			search.subRegions = (typeof (subRegions) != 'undefined') ? subRegions : new Array();
		}
	
		search.regionCode = (+search.getParam('regionCode'));
		search.placeCode = (+search.getParam('placeCode'));
	
	    // Setze den Hintergrund für die Karte oder 'blank' (falls kein Land angewählt wurde) und
		// initialiere die 'map' und deren 'areas' (spätestens hierfür brauchen wir die regions).
		if ($('iso2CountryCode') != null) {
			map.setCountry();
			(search.regions.length > 0) || search.requestRegions();
		}

	},

    // the <enter>-key was pressed by user interaction
    enter: function() {
        if ($F('searchNref').length > 0) {
            search.requestNrefCheck();
        } else {
			message('warning', ENTER_NREF);
        }
    },

	observe: function() {
		(function(){
			['fromDate', 'days', 'iso2CountryCode', 'placeCode',
			 'pax', 'quali', 'maxPricePerWeek', 'pets', 'bedrooms', 'seaLake', 'ski', 'houseType'].each(
			 	function(element) { Event.observe($(element), 'change', search.optionSelected); });

			['swimmingPool', 'sauna', 'whirlpool', 'television', 'kidBeds', 'heating', 
			 'aircondition', 'firePlace', 'washmachine', 'dishwasher', 'wheelChair', 'garage',
			 'internet', 'nonSmoking', 'fishing', 'tennis', 'golf', 'boat', 'panoramaHouse',
			 'specialOffer', 'lastMinute'].each(
			 	function(element) { Event.observe($(element), 'click', search.requestCount); });
				
			Event.observe($('regionCode'), 'change', search.regionCodeSelected);
		}).defer();
	},

	updateCount: function(count) {
		(typeof (count) != 'undefined') && (search.count = count);

		$('count').update(((search.count > 0) ? '<i>' + search.count + '</i>' : ''));
		$('count').setStyle({ left: ((search.count > 0) ? '3px' : '-999px') });
        $('resultLink').select('b')[0].update(((search.count > 0) ? search.count : '') + SHOW_RESULTS);
		
        (search.count == 0) ? message('warning', NO_OBJECTS_FOUND) 
							: ($('message') != null) && $('message').hide();		
	},
	
	getParam: function(name, defaultValue) {
		var param = $(name); 
		param = ((!!param) ? param.getValue()
			  : ((typeof (params.get(name)) != 'undefined') ? params.get(name) 
				 : ((typeof (defaultValue) == 'undefined') ? '' : defaultValue)));

		return param;
	},

	getCheckboxParam: function(name, defaultValue) {
		var param = $(name); 
		param = ((!!param) ? param.checked  
			  : ((typeof (params.get(name)) == 'undefined') 
				 ? ((typeof (defaultValue) == 'undefined') ? false : defaultValue)
			     : ((params.get(name) == 'Y') || (params.get(name) == 'true')))); 

		return (param) ? 'Y' : '';
	},
	
	getRequestParam: function(request) {
		
		var param = new Hash({ request: request, tab: Params._get('tab'), 
							   json: (request == 'json') });
		['languageCode', 'agency', 'db', 'debug'].each(
			function(key) { param.set(key, search.getParam(key)); });			
				
		if (['resultCount', 'objects', 'cookie', 'json'].indexOf(request) >= 0) {
	        var regionCodes = '';
    	    if (search.regionCode > 0) {
        	    if ((search.subRegions) && (search.subRegions.length > 0)) {
            	    regionCodes = search.subRegions.concat(search.regionCode).join(',');
	            } else {
    	            regionCodes = search.regionCode;
        	    }
        	}
			param.update({ regionCodes: regionCodes,
						   regionCode: ((search.regionCode > 0) ? search.regionCode : ''),
						   placeCode: ((search.placeCode > 0) ? search.placeCode : '') });

			['iso2CountryCode', 'fromDate', 'days', 'pax', 'quali',
			 'maxPricePerWeek', 'pets', 'bedrooms', 'seaLake', 'ski', 'houseType'].each(
				function(key) { param.set(key, search.getParam(key)); });

			['swimmingPool', 'sauna', 'whirlpool', 'television', 'kidBeds', 'heating',
			 'aircondition', 'firePlace', 'washmachine', 'dishwasher', 'wheelChair', 'garage',
			 'internet', 'nonSmoking', 'fishing', 'tennis', 'golf', 'boat', 'panoramaHouse'].each(
			 	function(key) { param.set(key, search.getCheckboxParam(key)); })

			param.set('specialOfferCode', ((search.getCheckboxParam('lastMinute') == 'Y') 
				  						  ? 'L' : search.getCheckboxParam('specialOffer')));
		}

		switch (request) {
			case 'countries':
				// Benutze den als globale Variable übergebenen iso2CountryCode, falls definiert 
				param.update({ iso2CountryCode: (typeof ((params.get('iso2CountryCode')) != 'undefined') 
				                                 ? params.get('iso2CountryCode') : ''),
							   json: true });
				break; 
			case 'regionsTree':
		        param.set('iso2CountryCode', search.getParam('iso2CountryCode'));
				break;
			case 'places':			
				param.update({ iso2CountryCode: search.getParam('iso2CountryCode'), json: true });			
				break; 
			case 'nrefCheck':
				param.update({ iso2CountryCode: search.getParam('iso2CountryCode'),
					           nref: encodeURIComponent(search.getParam('searchNref').strip()) });
				break;			
			case 'objects':
				var objectsPerPage = (+search.getParam('objectsPerPage'));

				param.set('offset', results.offset);
			
				var requestObjects = new Array();
					
				for (var i = results.offset, len = results.offset + objectsPerPage; i < len; i++) {
					if (!!results.objects[i]) {
						requestObjects.push(results.objects[i].object)
					} else {
						// Da keine Gesamtliste mehr requested wird, können Löcher in der Liste 
						// auftreten, dann darf die Objektliste nicht benutzt werden. 
						requestObjects.clear();
						break;
					}
				}
				if (requestObjects.length > 0) {
					param.set('objects', requestObjects.join(','));
				} else {
			  		param.update({ objectsPerPage: objectsPerPage,
					  	           orderBy: search.getParam('orderBy') });
				}
				
				break;
			case 'json':
			case 'cookie':
				['objectsPerPage', 'orderBy'].each(
					function(key) { param.set(key, search.getParam(key)); })
				break;
		}

		// Aktualisierung des globalen 'params'-Hashs, indem die durch den 'request'
		// benötigten Schlüssel im 'params'-Hash aktualisiert werden. 
		// Anschließend werden alle Schlüssel ohne Werte entfernt. 
		params.update(param).each(
			function(pair) { (!!pair.value) || params.unset(pair.key) });							 		

		// Entferne alle Schlüssel ohne Wert ('', 0, false usw.)
		param.each(function(pair) { (!!pair.value) || param.unset(pair.key) });							 

		return param.toQueryString();
	},

	request: function(requestType, callback, hidden) {
		((hidden) || showProcessing());
		
        var param = search.getRequestParam(requestType);
        var myAjax = new Ajax.Request(
            (requestType == 'objects' ? '../objects/ferienhaus2.php5' : '../objects/requestXML.php5'),
            {
                parameters: param,
                onComplete: callback 
            }
        );
	},
	
    // request the nref, if any valid is entered
    requestNrefCheck: function() {
		search.request('nrefCheck', search.nrefCheckRequestCompleted, true);
    },

    // the request for nrefCheck was completed successfully and any data should be available
    nrefCheckRequestCompleted: function(response) {
		// Lösche den nref-Parameter aus dem globalen Parametern (params)
		params.unset('nref');
		
        if ((response.responseText == null) || (response.responseText == '')) {
			message('warning', UNKNOWN_HOUSENUMBER);
            return;
        } else {
			($('message') != null) && $('message').hide();
		}

		Params._set('tab', 'details');
		Params._set('object', response.responseText);
		$('mainContent').select('form')[0].writeAttribute(
			{ 'action': '?' + Params.toQueryString(null, false) }).submit();
    },



    // prepare (load) the iso2CountryCode-Select for display
    setIso2CountryCode: function(iso2CountryCode) {
        if (this.countries.length == 0) {
            // if no data is available, then try to get some countries from the server
            // and set Elements after the request was processed
            this.requestCountries();
        } else {
            if ($('iso2CountryCode').selectedIndex < 0) {
                // if the iso2CountryCode-select is not filled, try it
                this.setIso2CountryCodeSelect(iso2CountryCode);
            } else {
                var iso2CountryCodeSelect = $('iso2CountryCode');
                for (var i = 2, len = iso2CountryCodeSelect.length; i < len; i++) {
                    if (iso2CountryCode == iso2CountryCodeSelect[i].value) {
                        // select the iso2CountryCode in the select-Element
                        iso2CountryCodeSelect.selectedIndex = i;
                        $('countryName').update(iso2CountryCodeSelect[i].text + 
												' ' + URLAUB_UND_REISEN);
                        break;
                    }
                }
                if (i >= iso2CountryCodeSelect.length) {
                    iso2CountryCodeSelect.selectedIndex = 0;
                    $('countryName').update(URLAUB_UND_REISEN);
                }
            }

			// regions- und places-Arrays sowie das subRegions-Array initialisieren
        	search.regions = new Array();
			search.places = new Array();
			search.subRegions = new Array();

            // Setze das map-Hintergrundbild und leere das map.regions-Array
            map.setCountry();

			// Initialisiere die select-optionen der regionCode und placeCode-select's
			search.setRegionCodeSelect();
			search.setPlaceCodeSelect();
            search.regionCode = -1;
   	        search.placeCode = -1;
			// Eventuell sollte search.count zurücksetzt werden und während der folgenden 
			// Ermittlungen das count-Image ausgeblendet werden. 

			// Da kein regionCode und placeCode ausgewählt wurde, kann bereits jetzt das
			// Ergebnis (Zahl) ermittelt werden.
			// Die Regions und Places können losgelöst hiervon ermittelt werden, da keinerlei
			// Abhängigkeiten existieren (da search.subRegions für den Place-Request leer ist).
			search.requestCount(true);
			if (search.getParam('iso2CountryCode').strip() != '') {
	            search.requestRegions();
   		        search.requestPlaces();					
			}
        }
    },

    // request the countries from the server using ajax
    requestCountries: function() {
		search.request('countries', search.countriesRequestCompleted);
    },

    // the request for countries was completed successfully and any data should be available
    countriesRequestCompleted: function(response) {
		search.countries = eval(response.responseText);

		// Entferne die <select> <option>en, mit Ausnahme der ersten beiden
        var iso2CountryCodeSelect = $('iso2CountryCode');
		while (iso2CountryCodeSelect.options.length > 2) {
			iso2CountryCodeSelect.removeChild(iso2CountryCodeSelect.lastChild);
		}

        // set the iso2CountryCode-select using the global iso2CountryCode
        search.setIso2CountryCode(params.get('iso2CountryCode'));
    },



    // prepare (load) the regionCode-Select for display
    setRegionCode: function(regionCode) {
        if (regionCode) {
            // if a regionCode is supplied, this is used instead of this.regionCode
            search.regionCode = regionCode;
        }

        if ((search.regions.length == 0) && (search.getParam('iso2CountryCode').strip() != '')) {
            // if no data is available, then try to get some regions from the server
            // and set Elements after the request was processed
            search.requestRegions();
        } else {
            if ($('regionCode').selectedIndex < 0) {
                // if the regionCode-select is not filled, try it
                search.setRegionCodeSelect();				
            } else {
                var regionCodeSelect = $('regionCode');
                if (search.regionCode != (+regionCodeSelect.value)) {
                    // if the regionCode differs from the select-value, then
                    // search regionCode in the regions-array for the selectIndex
                    for (var i = 0, len = regionCodeSelect.length; i < len; i++) {
                        if (search.regionCode == (+regionCodeSelect[i].value)) {
                            // select the regionCode in the select-Element
                            regionCodeSelect.selectedIndex = i;
                            break;
                        }
                    }
                }
            }
			
			// Übernehme den regionCode aus dem 'select', um fehlerhafte Werte zu erkennen
			search.regionCode = (+search.getParam('regionCode'));

			// Aktualisiere die 'map'-Markierung
	        map.setRegionCode(search.regionCode);

			if (search.regionCode > 0) {
    	    	// Fälle die subRegions mit den aktuellen Werten der Region
        		for (var i = 0, len = search.regions.length; i < len; i++) {
            		 if (search.regionCode == search.regions[i].RegionCode) {
		                  search.subRegions = search.regions[i].SubRegions;
    		              break;
        		     }
	        	}
			} else {
				// Lösche die subRegions, wenn kein regionCode angewählt wurde
				search.subRegions = new Array();
			}
        }
    },

    // request the regions from the server using ajax
    requestRegions: function() {
		search.request('regionsTree', search.regionsRequestCompleted, true);
    },

    // the request for regions was completed successfully and any data should be available
    regionsRequestCompleted: function(response) {
		search.regions = eval(response.responseText);

        // Initialiere die 'map' und deren 'areas', bevor setRegionCode eventuell eine anzeigt
        map.setRegions();

        // Bestücke einige Werte und das regionCode-select (indirekt, indem selectedIndex < 0 ist)
        $('regionCode').selectedIndex = -1;
        search.setRegionCode();
    },

    // prepare (load) the placeCode-Select for display
    setPlaceCode: function() {
        if ((search.places.length == 0) && (search.getParam('iso2CountryCode').strip() != '')) {
            // if no data is available, then try to
            // get some places from the server and set Elements after the request was processed
            search.requestPlaces();
        } else {
            if ($('placeCode').selectedIndex < 0) {
                // if the placeCode-selects are not filled, try it
                search.setPlaceCodeSelect();
            } else {
                var placeCodeSelect = $('placeCode');
                if (search.placeCode != (+placeCodeSelect.value)) {
                    // if the placeCode differs from the select-value, then
                    // search placeCode in the data-array for the selectIndex
                    for (var i = 0, len = placeCodeSelect.length; i < len; i++) {
                        if (search.placeCode == (+placeCodeSelect[i].value)) {
                            // select the placeCode in the select-Element
                            placeCodeSelect.selectedIndex = i;
                            break;
                        }
                    }
                }
            }

			// Übernehme den placeCode aus dem 'select', um fehlerhafte Werte zu erkennen
			search.placeCode = (+search.getParam('placeCode'));						
        }
    },

    // request the places from the server using ajax
    requestPlaces: function() {
		search.request('places', search.placesRequestCompleted, true);
    },

    // the request was completed successfully and any data should be available
    placesRequestCompleted: function(response) {
		search.places = eval(response.responseText);
		
        // Bestücke einige Werte und das placeCode-select (indirekt, indem selectedIndex < 0 ist)
		$('placeCode').selectedIndex = -1;
        search.setPlaceCode();
    },

    // request the count from the server using ajax
    requestCount: function(requestCrpInfo) {
        // Neuanzeige der Ergebnisse anfordern.
        results.offset = -1;
        results.objects = new Array();

		// Ausblenden der letzten Ergebnisanzahl (ohne die Zahl zu löschen, als Platzhalter) 
		$('count').setStyle({ left: '-999px' });
        $('resultLink').select('b')[0].update(SEARCH_RESULTS);

		showProcessing();
		
		search.getRequestParam('resultCount');
		new Ajax.Request('../objects/ferienhaus2.php5',
			{
				parameters: params.toQueryString() + ((requestCrpInfo == true) ? '&crpInfo=Y' : ''),
				onSuccess: function(transport) {
					// Aktualisiere die Anzeige der Ergebnismenge und .count
					search.updateCount(transport.responseJSON.resultCount);
					
					// Aktualisierung der URL
					// alert('HREF = ' + transport.responseJSON.href);
					// top.location.href += '#' + transport.responseJSON.paramString;
					$('container').select('#results', '#resultLink')
						.invoke('writeAttribute', { 'href': transport.responseJSON.href })					

					// Speichere die letzten Parameter, die eine Ergebnismenge lieferten
					// (search.count > 0) && setCookie();
					if (search.count > 0) {
						setCookie();
					}

					// Aktualisiere die crpInfo und den Titels im Dokument und im Header des 
					// Contents (wenn eine der CRP-Komponenten geändert wurde).
					if (typeof (transport.responseJSON.crpInfo) != 'undefined') {
						search.setTitle(transport.responseJSON.title, transport.responseJSON.h1);

						var crpInfo = $('crpInfo');
						if (transport.responseJSON.crpInfo == null) {
							(crpInfo == null) || crpInfo.hide();
						} else {
							if (crpInfo == null) {
								$('mainContent').insert({ 'after' : transport.responseJSON.crpInfo });	
							} else {
								crpInfo.replace(transport.responseJSON.crpInfo);
							}
						}
						
						var topObjects = $('topObjects');
						if (transport.responseJSON.topObjects == null) {
							(topObjects == null) || topObjects.hide();
						} else {
							if (topObjects == null) {
								$('mainContent').insert({ 'after' : transport.responseJSON.topObjects });	
							} else {
								topObjects.replace(transport.responseJSON.topObjects);
							}
						}						
					}						 
					
					(function(){
						hideProcessing();
					}).defer();
					
				}
			}
		);
    },

    // fill the countries from the data-array into the iso2CountryCode-select
    setIso2CountryCodeSelect: function(iso2CountryCode) {
		// Entferne die <select> <option>en, mit Ausnahme der ersten beiden
        var iso2CountryCodeSelect = $('iso2CountryCode');
		while (iso2CountryCodeSelect.options.length > 2) {
			iso2CountryCodeSelect.removeChild(iso2CountryCodeSelect.lastChild);
		}

        $('countryName').update(URLAUB_UND_REISEN);

        // create the option-Elements from the countries-array
        if (search.countries.length == 0) {
            // if no data is available, leave the options empty and select nothing
            iso2CountryCodeSelect.selectedIndex = -1;
        } else {
            // create the option-Elements from the data-array and select the iso2CountryCode
	        var iso2CountryCodeOption;
            for (var i = 0; i < search.countries.length; i++) {
                if (this.countries[i].Released) {
                    iso2CountryCodeOption = document.createElement('option');
                    iso2CountryCodeOption.setAttribute('value', this.countries[i].iso2CountryCode);
                    if (iso2CountryCode == this.countries[i].iso2CountryCode) {
                        iso2CountryCodeOption.setAttribute('selected', 'selected');
                        $('countryName').update(this.countries[i].CountryName + 
												' ' + URLAUB_UND_REISEN);
                    }
                    iso2CountryCodeOption.appendChild(
						document.createTextNode(this.countries[i].CountryName));
                    iso2CountryCodeSelect.appendChild(iso2CountryCodeOption);
                }
            }
        }
    },

    // fill the regions from the data-array into the regionCode-select
    setRegionCodeSelect: function() {
		// Entferne die <select> <option>en, mit Ausnahme der ersten beiden
        var regionCodeSelect = $('regionCode');
		while (regionCodeSelect.options.length > 2) {
			regionCodeSelect.removeChild(regionCodeSelect.lastChild);
		}

        // create the option-Elements from the regions-array
        if (search.regions.length == 0) {
            // if no data is available, leave the options empty and select nothing
            regionCodeSelect.selectedIndex = 0;
        } else {
            // create the option-Elements from tha data-array and select the regionCode
	        var regionCodeOption;
            for (var i = 0; i < search.regions.length; i++) {
                if (search.regions[i].Released) {
                    regionCodeOption = document.createElement('option');
                    regionCodeOption.setAttribute('value', this.regions[i].RegionCode);
                    if (search.regionCode == this.regions[i].RegionCode) {
                        regionCodeOption.setAttribute('selected', 'selected');
                    }
					switch (this.regions[i].Depth) {
						case 0: 
							regionCodeOption.className = 'mainRegion';
							break;
						default:		
							regionCodeOption.className = 'subRegion';
							break;							
					}
					var depth = '';
					for (var l = 0; l < this.regions[i].Depth * 3; l++) {
						depth += '\u00A0';
					}
                    regionCodeOption.appendChild(
						document.createTextNode(depth + search.regions[i].RegionName));
                    regionCodeSelect.appendChild(regionCodeOption);
                }
            }
        }
    },

    // fill the places from the places-array into the placeCode-select
    setPlaceCodeSelect: function() {
		// Entferne die <select> <option>en, mit Ausnahme der ersten beiden
        var placeCodeSelect = $('placeCode');
		while (placeCodeSelect.options.length > 2) {
			placeCodeSelect.removeChild(placeCodeSelect.lastChild);
		}

        // create the option-Elements from the places-array 
        if (search.places.length == 0) {
            // if no data is available, leave the options empty and select nothing
            placeCodeSelect.selectedIndex = 0;
        } else {
            // create the option-Elements from the places-array and select the placeCode
            // in the placeCode-select
	        var placeCodeOption;
            for (var i = 0; i < search.places.length; i++) {
                if ((this.places[i].Released) &&
                    ((this.regionCode < 1) ||
                     (this.places[i].Regions.indexOf(this.regionCode) >= 0))) {
                    placeCodeOption = document.createElement('option');
                    placeCodeOption.setAttribute('value', this.places[i].PlaceCode);
                    if (this.placeCode == this.places[i].PlaceCode) {
                        placeCodeOption.setAttribute('selected', 'selected');
                    }
                    placeCodeOption.appendChild(document.createTextNode(this.places[i].PlaceName));
                    placeCodeSelect.appendChild(placeCodeOption);
                }
            }
        }
    },

	// Wenn ein Select-Eintrag ausgewählt wurde, wird geprüft ob der "Trenner (- - -)"
	// ausgewählt wurde. In diesem Fall wird der erste Eintrag des Selects ausgewählt
	optionSelected: function(event) {
		var element = Event.element(event);
		element.blur();
		window.focus();

        if (element.value.strip() == '') {
            element.selectedIndex = 0;
        }

		switch (element.id) {
			case 'fromDate':
				// Sonderbehandlung von '0'-Werten, da sonst das Zurücksetzen von fromDate nicht
				// funktioniert wenn der value = '' ist.
				// dieser Wert auch übergeben wird.
		        if ((+element.value.strip()) < 1) {
					element.selectedIndex = 0;
        		}				
				break;
			case 'days':
				break;
			case 'placeCode':
		        search.placeCode = (+element.value);
		        search.requestCount(true);
				return;		
				break;
			case 'iso2CountryCode':
		        search.setIso2CountryCode(search.getParam('iso2CountryCode'));
				break;
			case 'objectsPerPage':
				showProcessing();
				$('mainContent').select('form')[0].submit();
				return; 
				break;
			case 'orderBy':
				showProcessing();
				// Setze den 'offset' auf 0, da die Sortierung geändert wurde
				// Params._set('orderBy', $F('orderBy')); // oder redirect
				Params._set('offset', null);
				$('mainContent').select('form')[0].writeAttribute(
					{ 'action': '?' + Params.toQueryString(null, false) + '&redirect' }).submit();
				return; 
				break;
			case 'duration':
				showProcessing();
				$('mainContent').select('form')[0].submit();
				return;
				break;							
		}
		
        search.requestCount();		
	},
	
    // regionCode wurde durch den Benutzer angewählt ('option' selektiert oder Klick auf die 'map')
    regionCodeSelected: function() {
		$('regionCode').blur();
		window.focus();
		
        var regionCodeSelect = $('regionCode');
        if (regionCodeSelect.value.strip() == '') {
            regionCodeSelect.selectedIndex = 0;
        }

		// Setze regionCode, weil setRegionCode(0) nicht funktioniert
        search.regionCode = (+regionCodeSelect.value);
		// Bestücke einige Werte, unter anderem auch die subRegions für das folgende requestCount 
		search.setRegionCode();

		// Neuanwahl der Ergebnismenge und neue Bestückung des placeCode-select's
        search.placeCode = -1;
        search.requestCount(true);

		// Bestücke das placeCode-select (indirekt, indem selectedIndex < 0 ist)
		$('placeCode').selectedIndex = -1;
        search.setPlaceCode();
    }
}



var results = {
    //----------------- properties -------------------
    //
    objects: new Array(),
    offset: -1,
	observed: false,
	
    //----------------- methods ----------------------
    //
	observe: function() {
		results.observed = true;
		(function(){
			Event.observe($('objectsPerPage'), 'change', search.optionSelected);	
			Event.observe($('orderBy'), 'change', search.optionSelected);
		}).defer();		
	},
	
    init: function(show) {
		// Aktiviere die Überwachung der aktiven Formfelder, falls diese bereits geladen sind
		(!results.observed) && ($('resultsSubMenu') != null) && results.observe();

		// Liegen die results-Werte als globale Variablen vor, werden diese übernommen  
		if ((typeof (resultObjects) != 'undefined') && (resultObjects.length > 0)) {
			results.offset = (+search.getParam('offset'));
			for (var i = 0, len = resultObjects.length; i < len; i++) {
				results.objects[results.offset + i] = { 'object': resultObjects[i] };
			}
		} else {
			results.offset = -1;
		}
	}		
}



var details = {
    //----------------- properties -------------------
    //
    objects: new Array(),
    offset: -1,
	observed: false,

    //----------------- methods ----------------------
    //
	observe: function() {
		details.observed = true;
		(function(){
			// Event.observe($('objectsPerPage'), 'change', search.optionSelected);	
			// Event.observe($('orderBy'), 'change', search.optionSelected);
			$('duration') && Event.observe($('duration'), 'change', search.optionSelected);			
		}).defer();		
	},
	
    init: function(show) {
		$$('div.object').each(function(object) {
			details.alignPictures(object);
		});
		
		googleMap.showObjectMap($$('div.objectMap')[0]);
		
		// Aktiviere die Überwachung der aktiven Formfelder, falls diese bereits geladen sind
		(!details.observed) && ($('detailsSubMenu') != null) && details.observe();
	},

	alignPictures: function(element) {
		if (element) {
			var pictures = element.select('.pictures')[0];
			var height = element.select('.details')[0].getHeight();
			var visibleImages = Math.floor(height / 100);
			var heightPx = ((height < 100) ? '100' : (visibleImages * 100)) + 'px';
			pictures.setStyle({ height: heightPx });

			// Bildquellen von (blank.gif) auf Thumbnail umstellen, falls das Bild sichtbar wurde.
			var images = pictures.select('img');
			// Es wird pro sichtbarem Bild nur ein 'img' durchsucht, ab Position 1
			var len = (images.length < visibleImages) ? images.length : visibleImages;
			for (var i = 1; i < len; ++i) {
				var image = images[i];
				if (image.name && (image.name != '')) {
					image.src = image.name;
					image.name = '';
				}
			}
		}
	}	
}




function topOfPage() {
	var scrollOffset = document.viewport.getScrollOffsets();

	if (scrollOffset.top > 0) {
		var options = {
			duration: 1.0,
			transition: Effect.Transitions.sinoidal 
		};

		new Effect.Tween(null, scrollOffset.top, 0, options, function(p){ scrollTo(scrollOffset.left, p); });
	}
}



var googleMap = {
    //----------------- properties -------------------
    //
	gMap: null,			// GMap2-Instanz
	mapDIV: null,		// Zeiger auf das aktuelle DIV-Element
	mapObject: null,	// Zeiger auf das aktuelle object (results- bzw. favorites-Array)

	map: null,
	objectMap: null,
	
    //----------------- methods ----------------------
	loadMaps: function() {
		google.load('maps', '2', { callback: this.showObjectMap.bind(this, this.objectMap) });		
	},
	
	showObjectMap: function(objectMap) {
		if (!googleApiKey || !objectMap || !objectMap.select('.googleMaps')[0]) {
			return;
		}

		var point = objectMap.readAttribute('point').evalJSON();
		var hint = objectMap.select('.googleMapsHint')[0];
		var accuracy = ACCURACY[typeof (point.accuracy) == 'undefined' ? 4 : point.accuracy];

		hint && hint.update(accuracy).show();
		this.mapDIV = objectMap.select('.googleMaps')[0].show();	

		if (typeof (google) == 'undefined') {
			this.objectMap = $(objectMap);
			var script = document.createElement('script');
			script.src = 'http://www.google.com/jsapi?key=' + googleApiKey 
					   + '&callback=googleMap.loadMaps';
			script.type = 'text/javascript';
			document.getElementsByTagName('head')[0].appendChild(script);
			return;			
		}
		
		if (!google.maps.BrowserIsCompatible()) {
			return;
		}

		var googleMaps = $('googleMaps');
				
		if (!this.map) {
			hint && hint.update(accuracy).show();
			this.mapDIV = objectMap.select('.googleMaps')[0].show();
			googleMaps.clonePosition(this.mapDIV).show();

	   		this.map = new google.maps.Map2(googleMaps);
    	   	this.map.addControl(new google.maps.LargeMapControl());
       		this.map.addControl(new google.maps.MapTypeControl());
	       	this.map.addControl(new google.maps.ScaleControl());
			this.map.addControl(new google.maps.OverviewMapControl());

			// GEvent.addListener(map, "click", place.mapClicked);
	    } else {
			if (this.mapDIV != object.googleMaps) {
				$('googleMaps').hide();
				$(this.mapDIV).hide();
						
				this.mapDIV = object.googleMaps;				
			}

			if (!$(this.mapDIV).visible()) {
				$(this.mapDIV).show();
				hint && hint.update(accuracy).show();
				this.alignMaps();
				results.alignPictures(element);
			} 

			if (!$('googleMaps').visible()) {
				$('googleMaps').show();
			}
		}	


	
		point = new google.maps.LatLng(point.latitude, point.longitude);
		this.map.setCenter(point, 10);
		this.map.checkResize();

		// var markerTitle = object.object.gsub(/^.*\//, '');		
		// object.marker = new google.maps.Marker(point, { title: markerTitle });
		var marker = new google.maps.Marker(point, { title: accuracy });
		this.map.addOverlay(marker);
		this.map.setCenter(point, 10); // Nochmal für den IE, damit die Karte auch angezeigt wird

	},


	load: function() {
		google.load('maps', '2', { callback: this.show.bind(this) });		
	},

	alignMaps: function() {
		if ((!this.mapDIV) || (this.mapDIV == null) || (!$(this.mapDIV).visible())) {
			return;
		}	
	
		$('googleMaps').clonePosition(this.mapDIV, { setWidth: false, setHeight: false });
	}
}



function setCookie() {
	search.getRequestParam('cookie');
	var cookieParams = params.clone();
	['request', 'languageCode', 'agency', 'db', 'debug', 'offset', 'foffset', 'tab', 'objects'].each(
		function(key) { cookieParams.unset(key); });
	// alert('setCookie: cookieParams =\n' + cookieParams.toJSON());
	createCookie('params', escape(cookieParams.toJSON()), 7);
}

function createCookie(name, value, days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
		var expires = '; expires=' + date.toGMTString();
	} else {
		var expires = '';
	}
	document.cookie = name + '=' + value + expires + '; path=/';
}

function readCookie(name) {
	var nameEQ = name + '=';
	var ca = document.cookie.split(';');
	for(var i = 0; i < ca.length; i++) {
		var c = ca[i];
		while (c.charAt(0) == ' ') {
			c = c.substring(1, c.length);
		}
		if (c.indexOf(nameEQ) == 0) {
			return c.substring(nameEQ.length, c.length);
		}
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name, '', -1);
}




function isUndefined(object) {
	return typeof (object) == 'undefined';
}

var Params = {
    //----------------- properties -------------------
    //
	urlSequence: [
		'object', 'tab',  
		'iso2CountryCode', 'regionCode', 'placeCode', // 'regionCodes', 
		'fromDate', 'days', 'pax', 'quali', 'maxPricePerWeek', 'pets', 'bedrooms', 'seaLake', 'ski',
		'houseType', 'swimmingPool', 'sauna', 'whirlpool', 'television', 'kidBeds', 'heating',
		'aircondition', 'firePlace', 'washmachine', 'dishwasher', 'wheelChair', 'garage', 
		'internet', 'nonSmoking', 'fishing', 'tennis', 'golf', 'boat', 'panoramaHouse',
		'specialOfferCode',
		'objectsPerPage', 'orderBy', 'offset', 
		'checkinDate', 'duration', 'calendarPage', 
		'locale', 'languageCode', 'agency', 
		'db', 'debug'	
	],
	
	types: new Hash({ 
		'object': { 'type': 'string', 'aliases': ['showObject'], 'keyless': true },
		'tab': { 'type': 'string', 'keyless': true, 'default': 'search', 
					   'values': ['search', 'suche', 'results', 'ergebnis', 
					   			  'details', 'vacancy', 'gallery', 'map', 'favorites', 
								  'booking'] },
		'iso2CountryCode': { 'type': 'string' },
		'regionCode': { 'type': 'string', 'alias': 'region' },
		'placeCode': { 'type': 'string', 'alias': 'place' },
		'fromDate': { 'type': 'date', 'alias': 'fDt' },
		'days': { 'type': 'select', 'default': 7 },
		'pax': { 'type': 'select' },
		'quali': { 'type': 'select' },
		'maxPricePerWeek': { 'type': 'integer', 'default': 0 },
		'pets': { 'type': 'select' },
		'bedrooms': { 'type': 'select' },
		'seaLake': { 'type': 'select' },
		'ski': { 'type': 'select' },
		'houseType': { 'type': 'select' },
		'swimmingPool': { 'type': 'checkbox' },
		'sauna': { 'type': 'checkbox' },
		'whirlpool': { 'type': 'checkbox' },
		'television': { 'type': 'checkbox' },
		'kidBeds': { 'type': 'checkbox' },
		'heating': { 'type': 'checkbox' },
		'aircondition': { 'type': 'checkbox' },
		'firePlace': { 'type': 'checkbox' },
		'washmachine': { 'type': 'checkbox' },
		'dishwasher': { 'type': 'checkbox' },
		'wheelChair': { 'type': 'checkbox' },
		'garage': { 'type': 'checkbox' },
		'internet': { 'type': 'checkbox' },
		'nonSmoking': { 'type': 'checkbox' },
		'fishing': { 'type': 'checkbox' },
		'tennis': { 'type': 'checkbox' },
		'golf': { 'type': 'checkbox' },
		'boat': { 'type': 'checkbox' },
		'panoramaHouse': { 'type': 'checkbox' },
		// 'specialOfferCode': { 'type': 'string' },

		'objectsPerPage': { 'type': 'select', 'alias': 'opp', 'default': 10 },
		'orderBy': { 'type': 'select', 'alias': 'sort' },
		'offset': { 'type': 'integer' },
		
		'checkinDate': { 'type': 'date', 'alias': 'cDt' }, /* integer */
		'duration': { 'type': 'select', 'alias': 'dur', 'default': 7 },
		'calendarPage': { 'type': 'integer', 'alias': 'cPg' },
		
		'locale': { 'type': 'string' },
		'languageCode': { 'type': 'string', 'aliases': ['lCode', 'l'] },

		'agency': { 'type': 'string', aliases: ['agencyCode'], 'default': 'DSITE' },
		'db': { 'type': 'string', 'default': 'DEV' },
		'debug': { 'type': 'integer', 'default': 1 },
		
		'request': { 'type': 'string', 'values': ['resultCount', 'objects'], 'keyless': true },
		'json': { 'type': 'boolean' },		
		'redirect': { 'type': 'boolean' },
		'crpInfo': { 'type': 'boolean' },
		'regionCodes': { 'type': 'string' },
		'objects': { 'type': 'string' },
		'bookingCode': { 'type': 'integer', aliases: ['bookingID'] }
	}),
		   
	params: new Hash(),
			   	
    //----------------- methods ----------------------	
	/**
	 * Ermittle den entsprechenden type-Eintrag zu dem angegebenen Schlüssel, wobei nicht nur
	 * in den Schlüssels, sondern auch in den values-Array sowie den alias(es) gesucht wird.
	 * 
	 * @method _getType
	 * @param {string} key Suche nach diesem Schlüssel
	 * @return {hash} Das gefundene type-Objekt, inklusive eines (neuen) 'key'-Wertes 
	 */
	_getType: function(key) {
		var _type = new Hash(Params.types.get(key)), _key, _value;

		if (_type.get('type') == undefined) {
			Params.types.each(function(type) {
				_type = new Hash(type.value);
				if (((Object.isArray(_type.get('values')) ? _type.get('values') : []).indexOf(key) >= 0) ||
				    ((Object.isArray(_type.get('aliases')) ? _type.get('aliases') : []).indexOf(key) >= 0) ||
				     (Object.isString(_type.get('alias')) && _type.get('alias') == key)) {
					_type.set('key', type.key);
					throw $break;
				}				
			});
			_type.get('key') || (_type = new Hash({ 'key': key }));
		} else {
			_type.set('key', key);
		};
			
		return _type;
	},
	
	/**
	 * Liefere den Wert zum angegebenen Schlüssel abhängig vom übergebenen Wert und den zulässigen
	 * Werten bzw. vom 'default' Wert.
	 * 
	 * @method _get
	 * @param {string|hash} key Schlüsselwert oder types-Hash zu diesem Schlüssel
	 * @param {object} value Optionaler Wert, der auf Gültigkeit geprüft wird
	 * @param {boolean} defaults Optionaler Wert der entscheidet (true) ob ein defaultValue 
	 * 		zurückgeliefert wird, falls kein Wert definiert ist oder (false) der Wert entwertet 
	 * 		wird (undefined), falls der Wert dem defaultValue entspricht. 
	 * 		 
	 * @return {object} 
	 */
	_get: function(key, defaults, params) {
		var _type, _key, _value;

		params = (Object.isHash(params) ? params : Params.params);
		_type = (Object.isHash(key) ? key : Params._getType(key.strip()));
		_key = _type.get('key');
		_value = params.get(_key);
		
		if ((defaults != undefined) && (_type.get('type') != undefined)) {
			_values = _type.get('values');
			_value = (Object.isArray(_values) && _values.indexOf(_value) < 0) ? undefined : _value;
			if ((_type.get('type') == 'boolean') || (_type.get('type') == 'checkbox')) {
				_value = (_value === true || 
						 ((_value == undefined) && (params.keys().indexOf(_key) >= 0)) ||
						 (Object.isString(_value) && 
						  ['Y', 'J', 'TRUE'].indexOf(_value.toUpperCase()) >= 0)) 
					   ? true : _value;
			}
			if (_type.get('type' == 'integer')) {
				_value = (!isNaN(+_value) ? +_value : undefined);
			}
			_default = _type.get('default');
			_value = ((_value == undefined) && (defaults === true)) ? _default 
				   : (((_value != _default || defaults !== false)) ? _value : undefined);
		}
		
		return _value;
	},
	
	setTypeAttribute: function(key, attribute, value, types) {
		var _type = (Object.isHash(key) ? key : Params._getType(key)),
			_key = _type.get('key');
			
		(Object.isHash(types) ? types : Params.types).get(_key)[attribute] = value;
	},
	
	_set: function(key, value, params) {
		var _type = (Object.isHash(key) ? key : Params._getType(key)),
			_key = _type.get('key');
			
		(Object.isHash(params) ? params : Params.params).set(_key, value);
	},
	
	/**
	 * Bilde ein Hash der Parameter aus der übergebenen Zeichenkette.
	 * Falls der Schlüsselwert einem Objektmuster entspricht und kein Wert angegeben ist, wird
	 * ein 'object'-Schlüssel mit dem ursprünglichem Schlüssel als Wert erzeugt.
	 * Bei Checkbox-Schlüsseln (type='checkbox') mit leeren Werten (0, "", false), wird ein 
	 * 'true'-Wert benutzt. 
	 * 
	 * @method toHash
	 * @param {string} queryString Zeichenkette mit Parameterwerten, die im Aufbau einer URL
	 *		([?]key[=value][{&key[=value]}][#[key[=value][{&key=[value]}]) entsprechen.
	 * @param {boolean} beyondHash Wenn true, wird auch der Teil nach dem Hash ('#') betrachtet
	 * @return {hash} Hash mit den aus dem queryString gebildeten Parameter
	 * @public
	 */
	set: function(queryParams, params, beyondHash) {
		var _type, _key, _value;		
		
		params = (Object.isHash(params) ? params : Params.params);

		$H(queryParams.sub('#', beyondHash ? '&' : '#').toQueryParams()).each(function(param) {
			if (param.value == undefined && 
				param.key.match(/^(NOV|CUE|DAN|INT|WOL)[\/\.\-\_](.{3,15})$/)) {
				Params._set('object', param.key, params);					
			} else {
				_type = Params._getType(param.key);
				_key = _type.get('key');
				
				_value = (_type.get('keyless') && (param.value == undefined) &&
						  (_type.get('key') != param.key)) ? param.key : 
						  (Object.isArray(param.value) ? param.value[param.length - 1] : param.value);
				Params._set(_key, _value, params);
			}
		});

		return params;
	},
	// results&iso2CountryCode=DK&region=juetland-nord&days=14&sort=qualiDesc&offset=30
	/**
	 * Liefere alle relevanten Parameter in einem String zurück.
	 * 
	 * @method toQueryString
	 * @param {string|array|null} (Liste) der gewünschten Schlüssel
	 * @param {boolean|null} defaults Optionaler Wert der entscheidet (true) ob ein defaultValue 
	 * 		zurückgeliefert wird, falls kein Wert definiert ist oder (false) der Wert entwertet 
	 * 		wird (undefined), falls der Wert dem defaultValue entspricht. 
	 * 		 
	 * @return {string} 
	 */
	toQueryString: function(sequence, defaults, params, urlNames) {
		var _type, _key, _value, _alias, _param, _params = [];

		params = (Object.isHash(params) ? params : Params.params);
		
		(Object.isArray(sequence) ? sequence 
			: (Object.isString(sequence) ? [sequence] : Params.urlSequence)).each(						 
			function(key) {
				_key = key.strip();
				_type = Params._getType(_key);
				_value = Params._get(_type, defaults, params);
				
				if ((urlNames) && (['placeCode', 'regionCode'].indexOf($_key) >= 0) &&
					(+_value > 0)) {
					switch (_key) {
						case 'placeCode':
							var _place = 'place ermitteln...';
							_value = _place; // UrlName
							break;
						case 'regionCode':
							var _region = 'region ermitteln...';
							_value = _region; // UrlName
							break;							
					}
				}
				
				((_type.get('type') == 'boolean') || (_type.get('type') == 'checkbox')) && 
					(_value !== true) && (_value = undefined); 
				if (_value != undefined) {
					_alias = _type.get('alias');
					_param = (_alias ? _alias : (_type.get('keyless') ? _value : _key))
						   + ((_type.get('type') == 'boolean' || _type.get('type') == 'checkbox' ||
						      _type.get('keyless'))
							  ? '' : '=' + _value);
					(!_param) || _params.push(_param);
				}
			}
		);

		return _params.join('&');
	},
	
	getInputParam: function(id, defaultValue) {
		var param = $(id);
		param = ((!!param) ? param.getValue()
			  : (!isUndefined(params.get(id))) 
			     ? params.get(id)
			  	 : ((isUndefined(defaultValue) ? '' : defaultValue)));
				
		return param;
	},

	getCheckboxParam: function(id, defaultValue) {
		var param = $(id);
		param = ((!!param) ? param.checked
			  : (isUndefined(params.get(id)) 
			     ? (isUndefined(defaultValue) ? false : defaultValue)
			  	 : ((params.get(id) == 'Y') || (params.get(id) == 'true'))));
				
		return param;
	},

	/**
	 * Lese (alle) im types-Hash definierten Formelemente und setze die entsprechenden Werte
	 * in den params-Hash.
	 * 
	 * @method getFormParams
	 */
	getFormParams: function() {
		var _params = new Hash();
				
		Params.types.each(function(type) {
			_type = new Hash(type.value);
			if (['input', 'checkbox', 'select'].indexOf(_type.get('type')) >= 0) {				
				_id = _type.get('id');
				_element = $(id ? id : type.key);
				_value = (!!_element) 
					   ? ((_type.get('type') == 'checkbox') ? _element.checked : _element.getValue())
					   : undefined;
				_params.set(type.key, _value);
			}			 
		});
		
		Params.params.update(_params);
	},
	
	/**
	 * Setze (alle) vorhandenen Formelemente, die im types-Hash definiert sind, anhand
	 * eventuell definierter Werte in params.
	 * 
	 * @method setFormParams
	 */
	setFormParams: function() {
		Params.types.each(function(type) {
			_type = new Hash(type.value);			
			if (['input', 'checkbox', 'select'].indexOf(_type.get('type')) >= 0) {				
				_id = _type.get('id');
				_element = $(id ? id : type.key);
				_value = (!!_element) 
					   ? ((_type.get('type') == 'checkbox') ? _element.checked : _element.getValue())
					   : undefined;
				_params.set(type.key, _value);
			}			 
			
		});		
	}

}



function onKeyDown(event) {
    if (!event) {
        event = window.event;
    }

    var key = (event.which ? event.which : (event.keyCode ? event.keyCode : null));

    if (key == Event.KEY_RETURN && $('searchNref')) {
		if ((Params._get('tab', true) == 'search') && ($F('searchNref').strip() != '')) {
			event.stop();
			search.enter();
			return false;		
		}
    }
}



document.observe('dom:loaded', function() {

	$$('.nojs').invoke('hide');
	$$('.js').each(function(element) { element.removeClassName('js'); });
	$$('a.top').invoke('writeAttribute', 'href', 'javascript:topOfPage()');
	
	Params.set(window.location.href, null, true);
	// Wandele das globale 'params'-Objekt (literal) in einen Hash um
	params = (typeof (params) != 'undefined') ? $H(params) : new Hash();	
	
	search.init();
	results.init();
	details.init();

	// Aktiviere die Überwachung der Tastatur
	Event.observe(document, 'keydown', onKeyDown);
});
