
  /*** globals ***/

  var requestGettingData = false; // requesting?

  var map = null;
//  var geocoder = null;
  var bounds = new Array();
  var zoomMax = 12;
  var globalScale = false;
  var globalScaleImportant = false;
  var mapClicked = 0;

  var mapDeactivatedDivContent;

  var mapTableLoaded = false;
  var mapIsStartPage = false;
  var mapCircle = null;

  var flagHelpClosed = false;

  var mapsRoot = '/maps/';
  // limit zoom level
  limitMapZoomLevel(zoomMax);

  var gCountry = null;
  var gRegion = null;

  var persistentOverlay = "...";
  var currentOverlay = null;
  var mapCircleOverlay = null;

  var loadStateMapLoaded = false;
  var zoomChangeStopRequest = false;

  var currentMarkers = new Array();
  var showObjectGroups = false;

  var currentLoading = 0;
  var lastrequest = "+";
  var selectedType = 'housing';
  var mapRadius = 15;

  var mapMoveEndBlock = 0;
  var mapUnloaded = true;

  var globalRegionID = '';

  var adminLocation = '';
  var adminCountry  = '';
  
  var restoreOldPoly = false;

  /*** default icon ***/

  if(typeof GIcon != 'undefined') {

      var defaultIcon = new GIcon();
      defaultIcon.iconSize = new GSize(30, 30);
      defaultIcon.iconAnchor = new GPoint(15, 30);
      defaultIcon.infoWindowAnchor = new GPoint(14, 1);

      var defaultGroupIcon = new GIcon();
      defaultGroupIcon.iconSize = new GSize(60, 30);
      defaultGroupIcon.iconAnchor = new GPoint(0, 30);
      defaultGroupIcon.infoWindowAnchor = new GPoint(30, 1);

      var defaultGroupIcons = new Array();

      var groupIconSizes = new Array ( 22, 30, 38, 46, 54, 62 );
      for (var i = 0; i <= 6; i++) {
          defaultGroupIcons.push(new GIcon());
          defaultGroupIcons[i].iconSize = new GSize(groupIconSizes[i], 21);
          //defaultGroupIcons[i].iconAnchor = new GPoint(groupIconSizes[i] / 2, 21);
          defaultGroupIcons[i].iconAnchor = new GPoint(groupIconSizes[i] / 2, 10);
          defaultGroupIcons[i].infoWindowAnchor = new GPoint(groupIconSizes[i] / 2, 1);
      }

      /*** custom icons ***/

      var customIcons = new Array();
      customIcons["region"] = new GIcon(defaultIcon, mapsRoot+'images/drop_house.png');

      var flagIcon = new GIcon(defaultIcon, mapsRoot+'images/flag.png');
      flagIcon.iconAnchor  = new GPoint(14, 28);
      flagIcon.transparent = mapsRoot+'images/flag_transparent.png';
      flagIcon.imageMap    = [2,0, 2,20, 24,20, 24,0];
      var flagMarker = new GMarker(new GLatLng(120, 0),
                                   { icon: flagIcon, draggable: true, bouncy: true, autoPan: true, zIndexProcess: function() { return 9999 } });
      GEvent.addListener(flagMarker, 'dragend', function(latlng) {
          showRadiusControl();
          // zoom to level 6 at least
          if (map.getZoom() < 6) {
              setMapZoom(latlng, 6);
          }
          //map.panTo(latlng);
          setSearchCoordinates(latlng.lat(), latlng.lng());
          setCircle(latlng.lat(), latlng.lng());
          preLoadSearchResult();
          //highlightSearch('dummy');
      });

      /*** country icons ***/

      var countryDefaultIcon = new GIcon();
      countryDefaultIcon.iconSize = new GSize(16,11);
      countryDefaultIcon.iconAnchor = new GPoint(8, 5);
      countryDefaultIcon.infoWindowAnchor = new GPoint(8,1);

  }
      
  /*** classes ***/

  function myCountry ( id, points, levels, center, title ) {
      this.id = id;
      this.points = points;
      this.levels = levels;
      this.center = center;
      this.title  = title;
  }

  function myMarker ( id, position, name, regions, num, zoom ) {
      if (!groupExists(id)) {
          var nIcon = new GIcon(defaultGroupIcons[numDigits(num)-1], mapsRoot+'cached/images/b-'+num+'.png');

          // stick marker title together
          var o     = (num > 1) ? Translations[languageCode]["mapSearchObjects"] : Translations[languageCode]["mapSearchObject"];
          var iu    = (num > 1) ? Translations[languageCode]["mapSearchAround"] : Translations[languageCode]["mapSearchIn"];
          var nTitle = o +' '+ iu +' '+ name +' ('+ num +' '+ o +')'

          // var p     = position;
          var m     = new GMarker(position, { icon: nIcon, title: nTitle });
          GEvent.addListener(m, 'click', function(latlng) {

              setSearchCoordinates(position.lat(), position.lng());
              setMapCoordinates(position.lat(), position.lng());

              // zoom to level 7 at least
              if (map.getZoom() < 7) {
                  setMapZoom(latlng, 7);
              } else {
                  setMapZoom(latlng, map.getZoom()+1);
              }
              
              mapProcessBubbleWrap(position.lat(), position.lng(), regions.split(";"));

              if (!mapIsStartPage && zoom == zoomMax) {
                  startMapSearch(position.lat(), position.lng()); // start search directly on highest zoom level
              }
              preLoadSearchResult();
          });
          return m;
      }
  }

  var myCachedArray = new Array();

  function myCached ( id, position, name, regions, zoom, count ) {
      if (!groupExists(id)) {
          this.id = id;
          this.position = position;
          this.name = name;
          this.regions = regions;
          this.count = count;
          this.zoom = zoom;
          myCachedArray.push(this);
      }
  }

  var myCountries = new Array();
  var myRegions = new Array();
  var myGroups = new Array();
  function groupExists (id) {
      return (id in myGroups);
  }

  function resetGroups() {
      myGroups = new Array();
      if (groupMgr != null) {
          groupMgr.clearMarkers();
      }
      //alert("reset!");
  }

  var groupMgr = null;

  /*** map initialization ***/

  function loadMap () {

      if (mapTableLoaded && document.getElementById("map")) {

          if (GBrowserIsCompatible()) {

              // save map div content
              mapDeactivatedDivContent = document.getElementById("map").innerHTML;
              //alert('1: '+(mapDeactivatedDivContent.basicTrim() == '') + '\n' + (typeof mapLoadMapImg != 'undefined'));
              if (mapDeactivatedDivContent.basicTrim() == '' && typeof mapLoadMapImg != 'undefined') {
                  mapDeactivatedDivContent = mapLoadMapImg;
              }
              // load map
              map = new GMap2(document.getElementById("map"), { draggingCursor: "move" } );

              mapUnloaded = false;
              
              
              map.addMapType(G_NORMAL_MAP); /*G_PHYSICAL_MAP*/
              map.addControl (new GSmallMapControl());
              map.addControl(new GMenuMapTypeControl());
              
              prev = getPrevMapSettings();
              
              var myRequestType = '';
              if (document.getElementById('requestType')) myRequestType = document.getElementById('requestType').value;              
              
			  if(typeof oldPoly != 'undefined' && oldPoly != '' && typeof oldPolyLevels != 'undefined' && oldPolyLevels != '' && typeof oldPolyLatitude != 'undefined' && typeof oldPolyLongitude != 'undefined') 
			  {				  	
			  	restoreOldPoly = true;  	
			    var polylight = createPolyLight(oldPoly, oldPolyLevels);
			    changeCurrentOverlay(polylight);
			    var globalScale = map.getBoundsZoomLevel(polylight.getBounds());							    
				if(typeof oldPolyLatitude != 'undefined' && typeof oldPolyLongitude != 'undefined') {
					map.setCenter(new GLatLng(oldPolyLatitude, oldPolyLongitude), globalScale);
					flagMarker.setLatLng(new GLatLng(oldPolyLatitude, oldPolyLongitude));					
				}				
			  } else if (prev) {			  	
                  map.setCenter(new GLatLng(prev[0], prev[1]), parseInt(prev[2]));
                  if (myRequestType != 'form') flagMarker.setLatLng(new GLatLng(prev[0], prev[1]));
                  showRadiusControl();                  
              } else {              	
                  map.setCenter (new GLatLng(47.350733, 10.722656), 3 );
              }
			  //alert(oldPoly);
			  // else set prev-selected poly
			  //alert('felix, test: ' + felixLatTest + ' ' + felixLongTest);
			  //map.setCenter (new GLatLng(felixLatTest, felixLongTest), 5 );
			  
			  
              map.setMapType (G_NORMAL_MAP); /* G_PHYSICAL_MAP */

              var mgrOptions = { maxZoom: zoomMax, trackMarkers: false };
              groupMgr = new MarkerManager(map, mgrOptions);

              GEvent.addListener(map, 'moveend', function() {
                  getMarker();
                  setMapCoordinates('', '');
              });

              GEvent.addListener(map, 'dragend', function() {
                  setMapCoordinates();
              });


              GEvent.addListener(map,"click", function(overlay, point) {
                  if (!overlay) {
                      mapClick(point);
                      preLoadSearchResult();
                  }
              });

              // select correct radius
              if (document.getElementById('mapRadius')) {
                   var r = document.getElementById('mapRadius').value;
                   if (r) {
                   	  if (myRequestType != 'form') setMapRadius(r);
                   	  else setMapRadius(r, true);
                   }
              }

              // marker initialization
              if (!mapIsStartPage) {
                  //mapProcessRestoreWrap();
              }
              restoreOldPoly = false;
              
              getSelectedType();
              getMarker();

              showMapSubmit();
              
              map.addOverlay(flagMarker);

              // set session
              // tobi, not needed anymore // GDownloadUrl(mapsRoot+"requestMapSession.php", function() {});

              // show close button
              if (!mapIsStartPage)
                if(document.getElementById('closemap')) document.getElementById('closemap').style.display = 'block';                                
          }
      } else {
          window.setTimeout("loadMap()", 1000);
      }
  }

  function unloadMap() {
      // unset session
      // tobi, not needed anymore // GDownloadUrl(mapsRoot+"requestMapSession.php?disabled="+Math.floor(Math.random()*1000), function() {});
      // restore bgcolor
      document.getElementById('map').style.backgroundColor = '#f0f0f0';
      // hide search now
      hideRadiusControl();
      hideFlagHelp();
      hideMapSubmit();

      mapUnloaded = true;

      // restore image
      if (mapDeactivatedDivContent)
          document.getElementById('map').innerHTML = mapDeactivatedDivContent;
      // hide close button
      if (!mapIsStartPage)
          document.getElementById('closemap').style.display = 'none';
  }

  function restoreMap(zoom, lat, lng) {
      map.setCenter(new GLatLng(lat, lng), zoom);
  }

  function resetMap() {
      hideCircle();
      changeCurrentOverlay(null);
      hideFlag();
      hideRadiusControl();
      hideFlagHelp();
      map.setCenter (new GLatLng(51.161671, 10.414617), 4 );
  }

  function mapClick(arg1, arg2) {
      var lat,lng;
      if (arg2) {
          lat = arg1;
          lng = arg2;
      } else if (arg1) {
          lat = arg1.y;
          lng = arg1.x;
      }
      if (lat && lng) {      	  
      	  setHiddenLocation('');
          setSearchCoordinates(lat, lng);
          setMapCoordinates(lat, lng);
          zoomMap(lat, lng);
          setFlag(lat, lng);
          setCircle(lat, lng);
      }
  }

  /*** draw markers **/

  function getMarker() {
      var point = map.getCenter();
      lng = point.lng();
      lat = point.lat();

      loadGroups();

      var scale = map.getZoom();
      if (scale <= 5) {
          /*** show countries ***/
          // show selected overlay, if exists
          showCurrentOverlay();

          // show countries inside of map bounds
          var bounds = map.getBounds();
          for (var i = 0; i < myCountries.length; i++) {
              if ( bounds.containsLatLng(myCountries[i].center) ) {
                  map.addOverlay( createCountry(myCountries[i]) );
              }
          }
      }
  }

  /*** create country flag ***/

  function createCountry(regionObject) {

      var marker  = new GMarker(regionObject.center, { icon: customIcons[regionObject.id], title: regionObject.title } );

      //var polygon = new GPolygon(regionObject.points, "#99ff33", 1, 1, "#99ff33", 0.4 );
      var polygon = new GPolygon.fromEncoded ({
          polylines: [{
              points: regionObject.points,
              levels: regionObject.levels,
              zoomFactor: 2,
              numLevels: 18,
              color: '#99ff33',
              weight: 1,
              opacity: 1
          }],
          fill: true,
          color: '#99ff33',
          opacity: 0.4,
          outline: true
      });

      var polylight = createPolyLight(regionObject.points, regionObject.levels);

      GEvent.addListener(polygon, 'click', function(latlng) {
          //zoomMap (false, false); // zoom
          mapClick(latlng.lat(), latlng.lng());
          preLoadSearchResult();
      });

      if (regionObject.id != persistentOverlay) {

          GEvent.addListener(marker, 'mouseover', function() {
              map.addOverlay(polygon);
          });

          // hide area
          GEvent.addListener(marker, 'mouseout', function() {
              map.removeOverlay(polygon);
          });
      }

      // marker clicked
      GEvent.addListener(marker, 'click', function() {
      	  setHiddenLocation('');
          var c = regionObject.center;
          globalScale = map.getBoundsZoomLevel(polygon.getBounds());
          if (globalScale == map.getZoom())  globalScale++;
          zoomMap (c.lat(), c.lng()); // zoom
          showObjectGroups = true;

          makeOverlayPersistent(regionObject.id);
          changeCurrentOverlay(polylight);

          // change search form
          mapClicked++;
          
          fillForm (new Array (regionObject.id));
          
          preLoadSearchResult();		  
      });

      return marker;
    }

  /*** fill the search form ***/
  function fillForm ( data ) {

      //alert ('fillForm');

      //if (!mapIsStartPage) {

          // data is an array containing country / region data

          // change country dropdown
          changeDropdownOptionById('sfCountry', data[0]);
          if (document.getElementById('hiddenCountryID')) document.getElementById('hiddenCountryID').value = data[0];

          // catch empty entries
          if (data[0] == '') {
              changeDropdownOptionById('sfLevel1', '');
              changeDropdownOptionById('sfLevel2', '');
              changeDropdownOptionById('sfLevel3', '');
              changeDropdownOptionById('sfLevel4', '');
              refreshLocation(1, '');
              return false;
          }

          if (data.length == 1) { // isCountry
              refreshLocation(1, data[0]);
          } else {
              globalRegionID = data[1];
              refreshLocation(1, data[0]);
          }			
          return true;
      //}
  }



  function mapFillFormLevel1() {
      if (globalRegionID != '') {
          var rID = globalRegionID;
          globalRegionID = '';
          changeDropdownOptionById('sfLevel1', rID);
          refreshLocation(2, rID, true);
      }
  }

  /** drops the flag **/
  function setFlag (lat, lng) {
      if (arguments.length == 0) {
          lat = map.getCenter().lat();
          lng = map.getCenter().lng();
      }
      if(typeof flagMarker != 'undefined')
        flagMarker.setLatLng(new GLatLng(lat, lng));

      showRadiusControl();
      if (mapIsStartPage && !flagHelpClosed && document.getElementById('mapflaghelp')) {
          document.getElementById('mapflaghelp').style.display = 'block';
      }

  }

  function showRadiusControl() {  	
      if (!mapUnloaded && document.getElementById('mapradiuscontrol')) {      	
          document.getElementById('mapradiuscontrol').style.display = 'block';
      }
  }

  function hideRadiusControl() {
      if (document.getElementById('mapradiuscontrol')) {
          document.getElementById('mapradiuscontrol').style.display = 'none';
      }
  }

  function showMapSubmit() {
      if (document.getElementById('mapsubmit')) {
          document.getElementById('mapsubmit').style.display = 'block';
      }
  }

  function hideMapSubmit() {
      if (document.getElementById('mapsubmit')) {
          document.getElementById('mapsubmit').style.display = 'none';
      }
  }

  function hideFlagHelp() {
      if (map) {
          globalScale = map.getZoom();
          globalScaleImportant = true;
      }
      if (document.getElementById('mapflaghelp')) {
          document.getElementById('mapflaghelp').style.display = 'none';
      }
      flagHelpClosed = true;
  }

  function hideFlagHelp2() {
      if (map) {
          globalScale = map.getZoom();
          globalScaleImportant = true;
      }
      if (document.getElementById('mapflaghelp')) {
          Effect.Fade('mapflaghelp');
      }
      flagHelpClosed = true;
  }

  function hideFlag () {
      setFlag(-120, 0);
  }

  function setCircle(lat, lng) {  
  	  changeCurrentOverlay(null);
      if (mapCircleOverlay != null) {      	  
          map.removeOverlay(mapCircleOverlay);
      }
      if (arguments.length == 0 || !lat) {
          lat = map.getCenter().lat();
          lng = map.getCenter().lng();
      }
      mapCircleOverlay = drawCircle(new GLatLng(lat, lng), mapRadius);
  }

  function hideCircle() {
      if (mapCircleOverlay != null) {
          map.removeOverlay(mapCircleOverlay);
      }
  }


  /*** returns a polygon with a lighter background ***/

  function createPolyLight (pPoints, pLevels) {
      var polylight = new GPolygon.fromEncoded ({
          polylines: [{
              points: pPoints,
              levels: pLevels,
              zoomFactor: 2,
              numLevels: 18,
              color: '#99ff33',
              weight: 1,
              opacity: 0.8
          }],
          fill: true,
          color: '#99ff33',
          opacity: 0.2,
          outline: true
      });

      GEvent.addListener(polylight, 'click', function(latlng) {
          mapClick(latlng.lat(), latlng.lng());
      });

      return polylight;
  }

  /*** load object group markers ***/
  function loadGroups() {

      var center = map.getCenter();
      var scale  = map.getZoom();

      myCachedArray = new Array();

      var thisrequest = center.lat()+","+center.lng()+","+scale;

      // prevent double requests
      if (thisrequest != lastrequest) {

          lastrequest = thisrequest;

          if (scale >= 5 ) {
              setLoading();

              GDownloadUrl(mapsRoot+"requestXML.php?groups=true&posLat="+center.lat()+"&posLng="+center.lng()+"&posTyp="+scale, function(data) {
                  var xml = GXml.parse(data);
                  var groups = xml.documentElement.getElementsByTagName("group");
                  var ga = new Array();

                  //updateSelectedTypes();

                  // get data from xml response
                  for (var i = 0; i < groups.length; i++) {
                      var id        = groups[i].getAttribute("id");
                      var name      = groups[i].getAttribute("name");
                      var regions   = groups[i].getAttribute("regions");
                      var count     = new Object();
                      count["all"] = groups[i].getAttribute("countAll");
                      count["housing"] = groups[i].getAttribute("countHousing");
                      count["hotels"] = groups[i].getAttribute("countHotels");

                      var position = new GLatLng(parseFloat(groups[i].getAttribute("lat")),
                                                 parseFloat(groups[i].getAttribute("lng")));

                      // add to cache
                      var cached = new myCached(id, position, name, regions, scale, count);

                      // calculate correct marker num
                      var num = count[selectedType];
                      if (num > 0) {
                          // create group object
                          var group = myMarker(id, position, name, regions, num, scale);

                          // add it to the map
                          if (group)
                              ga.push(group);
                      }
                  }

                  if (ga.length > 0) {
                      groupMgr.addMarkers(ga, scale, scale);
                      groupMgr.refresh();
                  }
                  unsetLoading();
              });
          }
      }
  }

  function getTypeSelectionMarker() {
      setLoading();

      resetGroups();

      var ga = new Array();
      var scale = 0;
      for (var i in myCachedArray) {
          var c = myCachedArray[i];
          var sum = c.count[selectedType];
          if (sum > 0) {
              ga.push (myMarker(c.id, c.position, c.name, c.regions, sum, c.zoom));
              scale = c.zoom;
          }
      }

      if (ga.length > 0) {
          groupMgr.addMarkers(ga, scale, scale);
          groupMgr.refresh();
      }
      unsetLoading();
  }

  function getSelectedType() {
      if (mapIsStartPage) {
          var radio = document.getElementsByName("group");
          for (var i = 0; i < radio.length; i++) {
              if (radio[i].checked == true) {
                  selectedType = (radio[i].value == '') ? 'all' : radio[i].value;
                  break;
              }
          }
      } else {
         if ($('group')) {
             selectedType = ($('group').value) ? $('group').value : 'all';
         }
      }
  }

  /*** sets the hidden fields with coordinate data ***/
  function setMapCoordinates( lat, lng, scale ) {
      if (arguments.length < 2) {
          lat = map.getCenter().lat();
          lng = map.getCenter().lng();
      }
      if (arguments.length < 3) {
          scale = map.getZoom();
      }
      /*
      if (typeof document.getElementById("mapLatitude") != "undefined"
        && document.getElementById("mapLatitude").length > 0
        && typeof document.getElementById("mapLongitude") != "undefined"
        && document.getElementById("mapLongitude").length > 0
        && typeof document.getElementById("mapScale") != "undefined"
        && document.getElementById("mapScale").length > 0) {
          document.getElementById("mapLatitude").value = lat;
          document.getElementById("mapLongitude").value = lng;
          setMapScale(scale);
      }
      */
      if (typeof document.getElementById("mapLatitude") != "undefined"       
        && typeof document.getElementById("mapLongitude") != "undefined"        
        && typeof document.getElementById("mapScale") != "undefined") {
          document.getElementById("mapLatitude").value = lat;
          document.getElementById("mapLongitude").value = lng;
          setMapScale(scale);
      }
  }

  /*** sets the hidden fields with coordinate data ***/
  function setMapScale( scale ) {
      if (arguments.length == 0) {
          scale = map.getZoom();
      }
      if (document.getElementById("mapScale")) {
          document.getElementById("mapScale").value = scale;
      }
  }


  /*** sets the hidden fields for search with coordinate data ***/
  function setSearchCoordinates(lat, lng) {
      if (arguments.length < 2) {
          lat = map.getCenter().lat();
          lng = map.getCenter().lng();
      }
      if (typeof document.getElementById("latitude") != "undefined"
        && typeof document.getElementById("longitude") != "undefined"
        && lat != ''
        && lng != '') {
          document.getElementById("latitude").value = lat;
          document.getElementById("longitude").value = lng;
      }
      setRequestType('map');
  }


  function setIsGroup(status) {
      document.getElementsByName("mapIsGroup")[0].value = status;
  }

  function showConfirmMapSearch() {
      if (!mapIsStartPage)
          document.getElementById("confirmmapsearch").style.display = 'block';
  }

  function hideConfirmMapSearch() {
      if (!mapIsStartPage)
          document.getElementById("confirmmapsearch").style.display = 'none';
  }

  function setMapRadius (r, dontDraw) {  	
      mapRadius = r;
      var oldRadius = 0;
      // set input value      
      if (document.getElementById('mapRadius'))
      {      	  
      	  oldRadius = document.getElementById('mapRadius').value;
          document.getElementById('mapRadius').value = r;
      }
      // set styles
      if (document.getElementById('mapradiuscontrol')) {      	
          radiuslinks = document.getElementById('mapradiuscontrol').getElementsByTagName('a');
          for (var i = 0; i < radiuslinks.length; i++) {
              if (radiuslinks[i].id == 'radius'+r) {
                  radiuslinks[i].style.fontWeight = 'bold';
              } else {
                  radiuslinks[i].style.fontWeight = 'normal';
              }
          }
      }

      if (arguments.length < 2 || !dontDraw) {      	
          // draw Circle
          setCircle(flagMarker.getLatLng().lat(), flagMarker.getLatLng().lng());
          // set request type
          setRequestType('map');
          // zoom          
          setMapZoom(flagMarker.getLatLng(), map.getBoundsZoomLevel(mapCircleOverlay.getBounds()));          
      }      
      if (oldRadius != r && dontPreload != true) preLoadSearchResult();
  }

  function startMapSearch(lat, lng) {
      showSearchLayer();;
      if (arguments.length < 2) {
          lat = map.getCenter().lat();
          lng = map.getCenter().lng();
      }
      setSearchCoordinates(lat, lng);
      setMapCoordinates(lat, lng);
      setIsGroup('true');
      setRequestType('map');
      document.forms.searchfrm.submit();
  }

  function getPrevMapSettings() {
       if (document.getElementById("latitude") && document.getElementById("latitude").value
        && document.getElementById("longitude") && document.getElementById("longitude").value ) {
              var s = (document.getElementById("mapScale") && document.getElementById("mapScale").value) ? document.getElementById("mapScale").value : 4;
              return new Array (document.getElementById("latitude").value, document.getElementById("longitude").value, s);

      } else if (document.getElementById("mapLatitude") && document.getElementById("mapLatitude").value
              && document.getElementById("mapLongitude") && document.getElementById("mapLongitude").value ) {

              var s = (document.getElementById("mapScale") && document.getElementById("mapScale").value) ? document.getElementById("mapScale").value : 4;
              return new Array (document.getElementById("mapLatitude").value, document.getElementById("mapLongitude").value, s);
       }
       return false;
  }

  /*** update map when search form is changed ***/
  function changeFormMapUpdate(fromForm, maxLevel, doSetFlag, country, region) {
      if (mapClicked == 0 && map != null) {

          var lat, lng, scale, flagSet = false;

          // see if custom coordinates and zoom level are set
          if (typeof document.getElementsByName("latitude") != "undefined"
           && document.getElementsByName("latitude").length > 0
           && document.getElementsByName("latitude")[0].value
           && typeof document.getElementsByName("longitude") != "undefined"
           && document.getElementsByName("longitude").length > 0
           && document.getElementsByName("longitude")[0].value ) {

                lat   = document.getElementsByName("latitude")[0].value;
                lng   = document.getElementsByName("longitude")[0].value;

          } else if (typeof document.getElementsByName("mapLatitude") != "undefined"
                 && document.getElementsByName("mapLatitude").length > 0
                 && document.getElementsByName("mapLatitude")[0].value
                 && typeof document.getElementsByName("mapLongitude") != "undefined"
                 && document.getElementsByName("mapLongitude").length > 0
                 && document.getElementsByName("mapLongitude")[0].value ) {

                lat   = document.getElementsByName("mapLatitude")[0].value;
                lng   = document.getElementsByName("mapLongitude")[0].value;

           }

           if (typeof document.getElementsByName("mapScale") != "undefined"
             && document.getElementsByName("mapScale").length > 0
             && document.getElementsByName("mapScale")[0].value) {
              scale = document.getElementsByName("mapScale")[0].value;
           }

          //alert(mapCircle);

          if (mapCircle) {
              setCircle(lat, lng);
              setFlag(lat, lng);
              globalScale = map.getBoundsZoomLevel(circle.getBounds());
              globalScaleImportant = true;
              zoomMap(lat, lng);

              mapCircle = false;
          } else {

              var cbox = document.getElementById("sfCountry");
              if ((country && region) || cbox != null) {
                  var countryid = (country) ? country : cbox.options[cbox.selectedIndex].value;
                  var regionid = (region) ? region : "";
                  if (regionid == '') {
                      for (var i = (maxLevel) ? maxLevel-1 : 4; i >= 1; i--) {
                          var rbox = document.getElementById("sfLevel"+i);
                          if (rbox.options.length > 0) {
                              var regionid = rbox.options[rbox.selectedIndex].value;
                              if (regionid != '') {
                                  regionid = regionid.split("|")[0];
                                  break;
                              }
                          }
                      }
                  }

                  var doNotZoomOut;

                  var doNotZoomOut = (typeof document.getElementsByName("mapIsGroup") != "undefined" &&
                             document.getElementsByName("mapIsGroup").length > 0 &&
                             document.getElementsByName("mapIsGroup")[0].value == "true" );

                  if (regionid == '' && countryid != '')
                      regionid = countryid;

                  if (regionid != '') {
                      makeOverlayPersistent(regionid);

                      flagSet = true;
                      // get matching overlay data

                      GDownloadUrl(mapsRoot+"requestArea.php?location="+regionid+"&country="+countryid,
                            function (response, status, xdoNotZoomOut, isCountry, xfromForm,xxdoSetFlag, xlat, xlng, xscale, xcountryid, xregionid) {
                                handleChangeMapResponse(response, (doNotZoomOut ? true : false), (regionid == countryid),
                                                                  (fromForm ? true : false), (doSetFlag ? true : false),
                                                                   lat, lng, scale, countryid, regionid)
                            }
                      );
                 }
             }
         }

         if (doSetFlag && !flagSet) {
             setCircle(lat, lng);
             setFlag();
         }

      }  else {
          makeOverlayPersistent("...");
          changeCurrentOverlay(null);
      }
      if (fromForm && mapClicked > 0) {
          mapClicked--;
      }
  }

  function handleChangeMapResponse(response, doNotZoomOut, isCountry, fromForm, doSetFlag, lat, lng, scale, country, region) {

      if (response.length > 1) {
          var poly = response.split(",,");
          var polylight = createPolyLight(poly[0], poly[1]);
          changeCurrentOverlay(polylight);
          if (doNotZoomOut && !fromForm) {
              globalScale = (scale) ? scale : 7;
              globalScaleImportant = true;
          } else {
              globalScale = map.getBoundsZoomLevel(polylight.getBounds());
              globalScaleImportant = true;
          }
          var lat = (!fromForm) ? lat : polylight.getBounds().getCenter().lat()
          var lng = (!fromForm) ? lng : polylight.getBounds().getCenter().lng();
          zoomMap(lat, lng);

          if (doSetFlag) {
              setFlag();
              fillForm((isCountry) ? new Array(country) : new Array(country, region));
              setRequestType('form');
          }
      } else if (isCountry) {
          resetMap();
      } else if (doSetFlag) {
          setCircle(lat, lng);
          setFlag();
      }
  }

  //*********************************************************************************//


  /**
    param options: object containing parameters:
      - latitude
      - longitude
      - countryID
      - locationID
  */
  function mapProcessRequest(method, options) {
      // stop request if map is not loaded
      if (mapUnloaded) {
          return false;
      }

      // parameter validation
      if (method == 'form') {
          if (!(options.countryID && options.locationID)) {
              return false;
          }
      } else if (method == 'suggestion') {
          if (!(options.countryID && options.locationID && options.longitude && options.latitude)) {
              return false;
          }
      } else if (method == 'bubble') {
          // would be better if called with locationID && countryID
          if (!(options.longitude && options.latitude)) {
              return false;
          }
      } else if (method == 'restore') {
          if (!(options.longitude && options.latitude)) {
              return false;
          }
      } else {
          // failure
          return false;
      }

      // hide flag, hide circle, hide place filter
      hideFlag();
      hideCircle();

      if (method == 'suggestion' || method == 'bubble' || method == 'restore') {
          // set flag
          setFlag(options.latitude, options.longitude);
      }

      if (method == 'suggestion' || method == 'bubble') {
          if (options.countryID) {
              // fill select boxes
              if (!mapIsStartPage) {
                  // change country dropdown
                  changeDropdownOptionById('sfCountry', options.countryID);
                  if (document.getElementById('hiddenCountryID')) document.getElementById('hiddenCountryID').value = options.countryID;
                  
                  // save locationID globally for asynchronous usage
                  globalRegionID = options.locationID;
                  // refresh select boxes
                  refreshLocation(1, options.countryID, true);
                  change_action(options.locationID);
                  // location box will be changed through a call to mapFillFormLevel1 from asynchronous select box loading script
              } else {
                  change_action((options.locationID) ? new Array(options.countryID, options.locationID) : new Array(options.countryID), true);
              }
          }
      }

      // fetch region area coordinates
      if (method == 'suggestion' || method == 'form') {

          var requestURL = mapsRoot+'requestArea.php?location='+options.locationID+'&country='+options.countryID
                           + ((method == 'form') ? '&getCenter=1' : '');
                           			
          GDownloadUrl(requestURL, function (response, status) {

              if (status == 200 && response.length > 1) {

                  var splitted = response.split(',,');
                  var encPoints, encLevels;

                  if (method == 'suggestion' && splitted.length == 2) {
                      // response expected in format: <encodedPoints>,,<encodedLevels>
                      encPoints = splitted[0];
                      encLevels = splitted[1];
                  } else if (method == 'form' && splitted.length >= 2) {
                      // response expected in format: <center latitude>,,<center longitude>,,<encodedPoints>,,<encodedLevels>
                      options.latitude = splitted[0];
                      options.longitude = splitted[1];
                      encPoints = splitted[2];
                      encLevels = splitted[3];
                  }

                  // setRequestType
                  setRequestType('form');

                  // draw polygon if points available
                  if (encPoints.length > 0 && encLevels.length > 0) {
                      if (method == 'suggestion') {
                          mapMoveEndBlock++;
                          setHiddenLocation(options.locationID);
                          setMapCoordinates('', '');
                          //alert('sug hier');
                      }

                      var polylight = createPolyLight(encPoints, encLevels);
                      changeCurrentOverlay(polylight);
                      options.latitude  = polylight.getBounds().getCenter().lat()
                      options.longitude = polylight.getBounds().getCenter().lng();
                      // zoom out
                      globalScale = map.getBoundsZoomLevel(polylight.getBounds());
                      globalScaleImportant = true;
                      zoomMap(options.latitude, options.longitude);

                  } else if (method == 'form') {
                      // zoom map out
                      if (options.countryID == options.locationID) {
                          globalScale = 5;
                      } else {
                          globalScale = 7;
                      }
                      zoomMap(options.latitude, options.longitude);
                  } else if (method == 'suggestion') {
                      map.panTo(new GLatLng(options.latitude, options.longitude));
                      // show circle
                      mapPostProcessMapSearch(options.latitude, options.longitude, true);
                  }

                  if (method == 'form') {
                      // set flag
                      setFlag(options.latitude, options.longitude);
                  }
              } else if (method == 'suggestion') {
                  map.panTo(new GLatLng(options.latitude, options.longitude));
                  // show circle
                  mapPostProcessMapSearch(options.latitude, options.longitude, true);
              }
              
              // needed for livesearch / suggestion
              if(typeof submitSearchForm != 'undefined' && submitSearchForm == true) {
                searchForm.submit();
                showSearchLayer();;
              }

          });
      }

     // alert ('process '+(i++));

      // pan map
      if (method == 'bubble') {
          map.panTo(new GLatLng(options.latitude, options.longitude));
      } else if (method == 'restore' && mapCircle) {
          zoomMap(options.latitude, options.longitude);
          //alert('zoomy');
      }

     // alert ('process '+(i++));

      // draw circle, set request type
      if (method == 'bubble' || (method == 'restore' && mapCircle)) {
          mapPostProcessMapSearch(options.latitude, options.longitude);
      }
  }

  /**
    @param updateFromForm: boolean - select box update was triggered from form? (opposed to update from js)
    @param maxLevel: int - maximum level to check for locationID
  */
  function mapProcessFormWrap(maxLevel, isRestore) {
      //alert (maxLevel);
      // get IDs from form selects
      var cbox = document.getElementById("sfCountry");
      if (cbox != null && cbox && cbox.options && cbox.options.length > 0) {
          var countryID = cbox.options[cbox.selectedIndex].value;
          var locationID = '';
          for (var i = maxLevel-1; i >= 1; i--) {
              var rbox = document.getElementById("sfLevel"+i);
              if (rbox != null && rbox && rbox.options && rbox.options.length > 0) {
                  locationID = rbox.options[rbox.selectedIndex].value;
                  if (locationID != '') {
                      locationID = locationID.split("|")[0];
                      break;
                  }
              }
          }

          if (locationID == '') {
              var h = getHiddenLocation();
              locationID = (h) ? h : countryID;
          }

          //alert(countryID + ".." + locationID);
          if (!isRestore)
              setHiddenLocation ('');

          // request
          if (restoreOldPoly != true) mapProcessRequest('form', {countryID: countryID, locationID: locationID});
      }
  }

  function mapProcessSuggestionWrap(latitude, longitude, countryID, locationID) {
      hidePlaceBox();
      hideUserinfoBox();

      adminLocation = locationID;
      adminCountry  = countryID;

      // alert(latitude+' '+longitude+' '+countryID+' '+locationID);
      mapProcessRequest('suggestion', {latitude: latitude, longitude: longitude, countryID: countryID, locationID: locationID});
  }

  function mapProcessBubbleWrap(latitude, longitude, locationIDs) {
      hidePlaceBox();
      hideUserinfoBox();
      if (typeof locationIDs != 'undefined' && locationIDs) {
          countryID  = locationIDs[0];
          locationID = (locationIDs.length > 1) ? locationIDs[1] : countryID;
          mapProcessRequest('bubble',  {latitude: latitude, longitude: longitude, countryID: countryID, locationID: locationID});
      } else {
          mapProcessRequest('bubble',  {latitude: latitude, longitude: longitude});
      }
  }

  function mapProcessRestoreWrap() {
      // alert('restore');
      var lat, lng, scale = false;
      // latitude and longitude were used for search
      
      if ($('latitude') && $('longitude') && $('latitude').value && $('longitude').value) {
          lat = $('latitude').value;
          lng = $('longitude').value;
      // mapLatitude and mapLongitude were set
      } else if ($('mapLatitude') && $('mapLongitude') && $('mapLatitude').value && $('mapLongitude').value) {
          lat = $('mapLatitude').value;
          lng = $('mapLongitude').value;
      }

      // get scale
      if ($('mapScale') && $('mapScale').value) {
          scale = parseInt($('mapScale').value);
      }
		
      if (lat && lng) {
          if (scale) {
              globalScale = scale;
              globalScaleImportant = true;
          }          
          mapProcessRequest('restore',  {latitude: lat, longitude: lng});
      } else {      	
          mapProcessFormWrap(5, true);
      }
  }

  function mapPostProcessMapSearch(latitude, longitude, zoomCircle) {
      setCircle(latitude, longitude);
      if (zoomCircle) {
          globalScale = map.getBoundsZoomLevel(circle.getBounds());
          zoomMap(latitude, longitude);
      }
      setRequestType('map');
  }

  function setRequestType (requestType) {
      //alert(requestType);
      if (document.getElementById("requestType"))
          document.getElementById("requestType").value = requestType;
  }

  function setHiddenLocation (locationID) {
      if (document.getElementById("hiddenLocationID"))
          document.getElementById("hiddenLocationID").value = locationID;
  }

  function getHiddenLocation () {
      if (document.getElementById("hiddenLocationID"))
          return document.getElementById("hiddenLocationID").value;
  }

  //********************************************************************************//



  /*** draw a circle ***/
  // see http://maps.forum.nu/gm_sensitive_circle2.html
  function drawCircle (center, circleRadius) {

    	var circlePoints = Array();

    	with (Math) {
    			var d = circleRadius/6378.8;	// radians

      		var lat1 = (PI/180)* center.lat(); // radians
      		var lng1 = (PI/180)* center.lng(); // radians

      		for (var a = 0 ; a < 361 ; a++ ) {
        			var tc = (PI/180)*a;
        			var y = asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc));
        			var dlng = atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(y));
        			var x = ((lng1-dlng+PI) % (2*PI)) - PI ; // MOD function
        			var point = new GLatLng(parseFloat(y*(180/PI)),parseFloat(x*(180/PI)));
        			circlePoints.push(point);
      		}

      		//if (d < 1.5678565720686044) {
      			  circle = new GPolygon(circlePoints, '#99ccff', 1, 0.9, '#99ccff', 0.3, { clickable: false });	//99ccff
      		//} else {
      		//	  circle = new GPolygon(circlePoints, '#99ccff', 1, 0.9);
      		//}
      		map.addOverlay(circle);
    	}

      return circle;
  }

  /*** save location id of selected region ***/
  function makeOverlayPersistent (id) {
      persistentOverlay = id;
  }

  /*** change/show overlay ***/
  function changeCurrentOverlay (polygon) {
      if (currentOverlay != null && map != null) {
          map.removeOverlay(currentOverlay);
      }
      currentOverlay = polygon;
      showCurrentOverlay();
  }

  function showCurrentOverlay () {
      if (currentOverlay != null && map != null) {
          map.addOverlay(currentOverlay);
      }
  }


  /*** zoom map ***/

  function zoomMap (lat, lng) {

      if ( lat && lng ) {
          map.setCenter(new GLatLng(lat, lng));
      }

      var currentScale = map.getZoom();
      var scale = currentScale;
		
      if (globalScale) {
          if (globalScaleImportant) {
              scale = globalScale;
          } else {
              scale = (scale > globalScale) ? scale+1 : globalScale;
              globalScale = false;
          }
      } else {
          scale = (scale+1 < zoomMax) ? scale+1 : zoomMax;
      }

      globalScaleImportant = false;
	  
      if (scale != currentScale) {
          map.setZoom(scale);          
          zoomChangeStopRequest = true;          
          getMarker();          
      }
  }
  
  function setMapZoom (centerLatLng, zoomLevel) {
      map.setCenter(centerLatLng);
      map.setZoom(zoomLevel);
  } 
  

  /*** functions to control loading image behaviour ***/
  function setLoading() {
      if (false && !mapIsStartPage && currentLoading == 0)
          document.getElementById('loadingmap').style.display = 'block';
      currentLoading++;
  }

  function unsetLoading() {
      if (!mapIsStartPage && currentLoading == 1 && document.getElementById('loadingmap'))
          document.getElementById('loadingmap').style.display = 'none';
      currentLoading--;
  }

  function showAdminCoordinateWindow() {
      if (adminLocation != '' && adminCountry != '') {
          adminCoordinateWindow = window.open("http://www.tourist-online.de/admintools/locationCoordinates/?locationID="+adminLocation+"&countryID="+adminCountry, "locationCoordinates", "width=860,height=596,location=0");
          adminCoordinateWindow.focus();
      } else {
          alert(unescape("Es wurde noch nichts %FCber die Vorschl%E4ge der Stichwortsuche gew%E4hlt."));
      }
  }

  /*** set the map control background image. ***/
  // ya, it's dirty, sorry
  function setControlBackground() {

      var e = getElementsByClassName("gmnoprint");
      var breakloop = false;
      for (var i = 0; i < e.length; i++) {
          if (e[i].tagName == "DIV"){
              var c = e[i].childNodes;
              if (typeof(c[0]) != "undefined") {
                  c[0].src = mapsRoot+"images/smc.png";
                  breakloop = true;
              }
          }
      }

      if (!breakloop) {
          window.setTimeout('setControlBackground()', 1000);
          //alert ("again!");
      }
  }

  /*** limits the map's maximum zoom level ***/
  function limitMapZoomLevel(zoomMax) {
      if(typeof G_PHYSICAL_MAP != 'undefined')
        G_PHYSICAL_MAP.getMaximumResolution = function () { return zoomMax };
      if(typeof G_NORMAL_MAP != 'undefined')
        G_NORMAL_MAP.getMaximumResolution = function () { return zoomMax };
      if(typeof G_SATELLITE_MAP != 'undefined')
        G_SATELLITE_MAP.getMaximumResolution = function () { return zoomMax };
      if(typeof G_HYBRID_MAP != 'undefined')
        G_HYBRID_MAP.getMaximumResolution = function () { return zoomMax };
  }

  /*** helpers ***/

  /*** returns the number of digits in an integer, e.g. numDigits(24) = 2, numDigits(123456) = 6 ***/
  function numDigits (n) {
      return Math.floor(Math.log(n)/Math.log(10)) + 1;
  }

  /*** returns the sum of the pArray values at the indexes given in indexArray ***/
/*   function arrayIndexSum ( pArray, indexArray ) {
      var s = 0;
      for (var i in indexArray) {
          s += parseInt(pArray[indexArray[i]]);
      }
      return s;
  } */

  function getElementsByClassName(class_name) {
      var all_obj,ret_obj=new Array(),j=0,teststr;

      if (document.all)
          all_obj = document.all;
      else if (document.getElementsByTagName && !document.all)
          all_obj = document.getElementsByTagName("*");

      for (i=0;i<all_obj.length;i++)  {
          if (typeof(all_obj[i].className) == "string" && all_obj[i].className.indexOf(class_name)!=-1) {
              teststr = ","+all_obj[i].className.split(" ").join(",")+",";
              if (teststr.indexOf(","+class_name+",")!=-1) {
                  ret_obj[j]=all_obj[i];
                  j++;
              }
          }
      }
      return ret_obj;
  }

  function changeDropdownOption(ename, v) {

      var e = document.getElementsByName(ename)[0];
      if (! (e && e.options)) {
          // IE fix
          e = document.searchfrm[ename];
      }

      if (e && e.options) {
          for (var i=0; i < e.options.length; i++) {
              if (e.options[i].value.substr(0,9) == v.substr(0,9)) {
    			        e.options[i].selected = true;
    			    } else {
    				      e.options[i].selected = false;
    		      }
    	    }
      }
  }

  function changeDropdownOptionById(elementid, val) {

      var e = document.getElementById(elementid);
      //var s = "";

      if (e && e.options) {
          // alert("ok "+e.options.length);
          for (var i=0; i < e.options.length; i++) {
              // s += i + " // " + e.options[i].value + "\n";
              //s += "\n '"+e.options[i].value.substr(0,9)+"' == '"+val.substr(0,9)+"'";
              if (e.options[i].value.substr(0,9) == val.substr(0,9)) {
    			        //e.options[i].selected = true;
                  e.selectedIndex = i;
                  return true;
    			    } else {
    				      e.options[i].selected = false;
    		      }
    	    }
      }
      //alert (s);

      return false;
      // alert(s);
  }

  String.prototype.basicTrim = function () {
    return (this.replace(/\s+$/,"").replace(/^\s+/,""));
  };

  if (typeof $ == 'undefined') {
      function $(id) {
          return document.getElementById(id);
      }
  }
  
function zoomPoint(latitude, longitude) 
{
	if (latitude != '' && longitude != '')
	{
	  	var point = new GLatLng(latitude, longitude);
	  	map.addOverlay(new GMarker(point));
		map.setCenter(point);
	}
}
