// TODO: - xml file remains until next page load
//       - radius & zoom in/ out unticks checkboxes

// userClicksMode:  user setting home base coords
// userMapMode:     display of home base coords in user profile

var xmlProfileData = null;

function svgon() { // Turn SVG on

 _mSvgEnabled = _mSvgForced = true;

}


function readProfileData() { // Load and read XML file using Ajax
 var request = GXmlHttp.create();
 request.open("GET", script_path + "user.xml", true);
 request.onreadystatechange = function() {

 //alert(request.readyState);
  if (request.readyState == 4) {
    var xml = request.responseXML;

    xmlProfileData = xml.documentElement.getElementsByTagName("dataset");
  }
 }; request.send(null);/*
 GDownloadUrl(script_path + "user.xml", function(data, responseCode) {
  xml = GXml.parse(data);
  xmlProfileData = xml.documentElement.getElementsByTagName("dataset");alert(xmlProfileData[0].getAttribute("title"));
 });*/
}


function readData() { // Load and read XML file using Ajax
 // Rewrite xml files according to radius and refill marker arrays
 if(document.getElementById('id_radius') && document.getElementById('id_radius').options.selectedIndex!=-1) {
   var center = map.getCenter();
   if(document.getElementById('id_radius').options.selectedIndex!=0) {
     var target = 'index.php?id=12&return_xml='+document.getElementById('id_radius').options[document.getElementById('id_radius').options.selectedIndex].value+'&center='+center.lat()+':'+center.lng();
     window.frames['getXml'].location.href = target;
     var radbuild = true;
   } else var radbuild = false;
 }
   
 // Unset global marker arrays 
 r_markers = new Array();
 b_markers = new Array();
 u_markers = new Array();
 r_marker_array = new Array();
 b_marker_array = new Array();
 u_marker_array = new Array();
 points = new Array();
 markers = new Array();

 var request = GXmlHttp.create();
 request.open("GET", script_path + "marker.xml", true);
 request.onreadystatechange = function() {

  if(request.readyState == 4) {
  
    var xml = request.responseXML;
    r_markers = xml.documentElement.getElementsByTagName("ger");
    b_markers = xml.documentElement.getElementsByTagName("eu");
    u_markers = xml.documentElement.getElementsByTagName("user");
    if(userMapMode == 1 || userClicksMode == 1) {
      for(var i = 0; i < u_markers.length; i++) {
        if(curUserId == u_markers[i].getAttribute("userid")) {
          var sel = i;
         }
      }
      if(userMapMode == 1 && userClicksMode == 1) buildProfileMap(sel);
      else {
       if(radbuild == true) {
        window.setTimeout(function(){
         buildMap(document.getElementById('id_radius').options[document.getElementById('id_radius').options.selectedIndex].value,'radius',map.getZoom(),map.getCenter());
        },500);
       } else buildMap(sel, "home");
      }
    } else {
      if(radbuild == true) {
       window.setTimeout(function(){
        buildMap(document.getElementById('id_radius').options[document.getElementById('id_radius').options.selectedIndex].value,'radius',map.getZoom(),map.getCenter());
       },500);
      } else buildMap(0);
    }
  }
 }; request.send(null);
}


function createMarker(point, icon, name, userid) {

 var marker = new GMarker(point, icon);
 if(userid != 0) marker.tooltip = "<div class='toolimg'><img src='" + icon_url_local + "home-logo-marker.png' /><\/div>";
 else marker.tooltip = "<div class='tooltip'><span>" + name + "</span><\/div>";

 var marker_type = icon.image.substring(icon.image.lastIndexOf("_")+1,icon.image.lastIndexOf("."));
 if(marker_type == "red") {
  r_marker_array.push(marker);
 }
 if(marker_type == "blue") {
  b_marker_array.push(marker);
 }
 if(marker_type == "user") {
  u_marker_array.push(marker);
 }

 GEvent.addListener(marker, "mouseover", function() {
  showTooltip(marker);
 });

 GEvent.addListener(marker, "mouseout", function() {
  tooltip.style.display = "none";
 });

 GEvent.addListener(marker, "click", function() {

  var form_html ="<div class='infowindow'>";

  if(userid != 0) {
    if(xmlProfileData == null) readProfileData();
    
    for(i = 0; i < xmlProfileData.length; i++) {
      var user_id = xmlProfileData[i].getAttribute("n");
      if(userid == user_id) {
        var user_title = xmlProfileData[i].getAttribute("title");
        var user_name = xmlProfileData[i].getAttribute("name");
        var user_zip = xmlProfileData[i].getAttribute("zip");
        var user_city = xmlProfileData[i].getAttribute("city");
        var user_address = xmlProfileData[i].getAttribute("address");
        var user_country = xmlProfileData[i].getAttribute("country");
        var user_advert = xmlProfileData[i].getAttribute("advert");
        var user_avatar = xmlProfileData[i].getAttribute("avatar");
      }
    }

    if(curUserId != 0) {
      var tab0_html =form_html+'<img src="'+ user_avatar +'" class="user-mapstack-avatar" align=right />';
      tab0_html +=user_advert +"<br \/>";
      var tab1_html =form_html;
      //tab1_html +="<strong>" + user_title + "</strong><br \/>" + user_name +"<br \/>";
      tab1_html +="<img src='" + icon_url_local + "home-logo-tab.png' /><br \/><div class='address'>" + user_name +"<br \/>";
      tab1_html +=user_address +"<br \/>";
      tab1_html +=user_zip + " " + user_city +"<br \/>";
      tab1_html +=user_country +"</div>";
      /*
      if(userid == curUserId) form_html +="<a href=index.php?id=40>Edit Profile</a><br \/>";
      else {
       tab1_html +="<a href=index.php?id=39&action=getviewprofile&uid="+ user_id +">View Profile</a><br \/>";
       tab1_html +="<a href=index.php?id=42&action=messagenew&recipient_uid="+ user_id +">Send Message</a><\/p>";
      }
      */
      var infoTabs = [
         new GInfoWindowTab("Anschrift", tab1_html),
         new GInfoWindowTab("weitere Infos", tab0_html)
      ];
    } else {
      form_html +="<p><b>Please login to view Profile Data.</b><br \/>";
    }
  } else {
    form_html += "<strong>"+name + "<\/strong><p>Luftlinie in km bis [Zielpunkt]<br \/>";
    form_html += "<form name='input_form'><input name='loc' type='text' size='15' \/> <input type='button' value='Zeig'";
    form_html += " onclick='townDistance(\"" + name + "\", this.form.loc.value)' \/>";
    form_html +="<\/form><\/p>";
  }

  form_html +="<\/div>";

  if(infoTabs) marker.openInfoWindowTabsHtml(infoTabs);
  else marker.openInfoWindowHtml(form_html);
 });

 return marker;
}


function addIcon(icon) { // Add icon attributes

  icon.shadow= icon_url + "mm_20_shadow.png";
  icon.iconSize = new GSize(12, 20);
  icon.shadowSize = new GSize(22, 20);
  icon.iconAnchor = new GPoint(6, 20);
  icon.infoWindowAnchor = new GPoint(5, 1);
}


function showTooltip(marker) { // Display tooltips

  tooltip.innerHTML = marker.tooltip;
  tooltip.style.display = "block";

  // Tooltip transparency specially for IE
  if(typeof(tooltip.style.filter) == "string") {
    tooltip.style.filter = "alpha(opacity:70)";
  }

  var currtype = map.getCurrentMapType().getProjection();
  var point = currtype.fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
  var offset = currtype.fromLatLngToPixel(marker.getPoint(),map.getZoom());
  var anchor = marker.getIcon().iconAnchor;
  var width = marker.getIcon().iconSize.width + 6;
  // var height = tooltip.clientHeight +18;
  var height = 10;
  var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y - height - 30));
  pos.apply(tooltip);
}


function toggleTools(display) {
 var mapdiv = document.getElementById("map");
 if (display) {
   mapdiv.childNodes[3].style.display = mapdiv.childNodes[4].style.display = mapdiv.childNodes[5].style.display = display;
 } else {
  if (mapdiv.childNodes[3].style.display == "block" || mapdiv.childNodes[3].style.display == "") {
   mapdiv.childNodes[3].style.display = mapdiv.childNodes[4].style.display = mapdiv.childNodes[5].style.display = "none";
  } else {
   mapdiv.childNodes[3].style.display = mapdiv.childNodes[4].style.display = mapdiv.childNodes[5].style.display = "block";
  }
 }
}


function buildMap(sel, type, zoomval, center) {

 seltype = type;
 sel = sel;

 map = new GMap2(mapdiv);

 GEvent.addListener(map, "mouseover", function() {
  toggleTools("block");
 });
 GEvent.addListener(map, "mouseout", function() {
  toggleTools("none");
 });

 // Add div element for toolips
 tooltip = document.createElement("div");
 map.getPane(G_MAP_MARKER_PANE).appendChild(tooltip);

 // Echo latitude & longitude of the center of the map
 /*GEvent.addListener(map, "moveend", function() {
  var center = map.getCenter();
  var latLngStr = "Lat: " + center.lat() + "<br \/>Long: " + center.lng();
  document.getElementById("pos").innerHTML = latLngStr;
 });*/
 if (isStyledMap()) overview = new GOverviewMapControl(new GSize(132, 132));
 
 // Filling radius select box on zoom end
 GEvent.addListener(map, "zoomend", function() {
  fillRadiusSelect(type, sel, map.getZoom());
 });

 if((sel) == 0 || type == "radius") {

  // Load initial map
  if(!center) var center = new GLatLng(parseFloat("49.44644918162729"),
   parseFloat("8.678383827209473"));
  if(!zoomval) zoomval = 13;
  map.setCenter(center, zoomval);
  map.addControl(new GLargeMapControl()); // Zoom control
  map.addControl(new GMapTypeControl()); // Toggle between map types
  map.addControl(new GScaleControl()); // Scale bar
  if (isStyledMap()) {
   map.addControl(overview);
   setTimeout("posOverview()", 0);
  } else window.setTimeout("toggleTools('none')", 1200);

  // Add directions feature
  gdir = new GDirections(map, document.getElementById("directions"));
  GEvent.addListener(gdir, "load", onGDirectionsLoad);
  GEvent.addListener(gdir, "error", handleErrors);

  if (!isStyledMap() && directionsFromAddress != null) {
   window.setTimeout("setDirections(directionsFromAddress, 'Heidelberger Strasse 55, Dossenheim, Deutschland')", 800);
  }

  if(type == "radius") {
   function CGOverlay(radius) {
    this.radius_ = radius;
   }
   
   radius = sel;
   CGOverlay.prototype = new GOverlay();
   
   // Creates the DIV representing the radius
   CGOverlay.prototype.initialize = function(map) {
    var div = document.createElement("div");
    div.style.position = "absolute";

    // The circle is flat against the map, so its to the
    // MAP_PANE pane, which is at the same z-index as the map  
    // (i.e.,below the marker shadows)
    map.getPane(G_MAP_MAP_PANE).appendChild(div);

    if(/firefox/i.test(navigator.userAgent)) {
     var svg = document.createElementNS('http://www.w3.org/2000/svg','svg');
     div.appendChild(svg);
    }

    this.map_ = map;
    this.div_ = div;
    if(svg) this.svg_ = svg;
   }
   // Remove the main DIV from the map pane
   CGOverlay.prototype.remove = function() {
    this.div_.parentNode.removeChild(this.div_);
   }

   // Copy our data to a new Rectangle
   CGOverlay.prototype.copy = function() {
    return new CGOverlay(this.radius_, this.backgroundColor_, this.opacity_);
   }

   // Redraw the radius based on the current projection and zoom level
   CGOverlay.prototype.redraw = function(force) {
    // We only need to redraw if the coordinate system has changed
    if (!force) return;
    
    // Remove the circle if svg child appended
    if(this.circle_) this.svg_.removeChild(this.circle_);
    
    var multiplier = 0.083;
    var series = (Math.pow(2,map.getZoom()-1));
    var delta = (series * multiplier);
    var current_radius = this.radius_ * delta;
    
    var center = this.map_.getCenter();
    var center_pixel = this.map_.fromLatLngToDivPixel(center);
    
    if(/firefox/i.test(navigator.userAgent)) {
    //for(i=0;i<4;i++) {
//     var paint_radius = document.getElementById('id_radius').options[i].value * delta;
     var paint_radius = current_radius;
     this.svg_.setAttribute('width', paint_radius);
     this.svg_.setAttribute('height', paint_radius);
     var circle = document.createElementNS('http://www.w3.org/2000/svg','circle');
     circle.setAttribute('cx', paint_radius/4);
     circle.setAttribute('cy', paint_radius/4);
     circle.setAttribute('r', paint_radius/4-1);
     circle.setAttribute('fill', 'red');
//     if(this.radius_ == document.getElementById('id_radius').options[i].value) circle.setAttribute('stroke', 'black');
//     else
     circle.setAttribute('stroke', 'gray');
     circle.setAttribute('fill-opacity', '0.10');
     this.svg_.appendChild(circle);
     this.circle_ = circle;
//    }
    } else this.div_.innerHTML = '<v:oval strokecolor="gray" style="opacity:23%;position:relative;top:0;left:0;width:' + current_radius/2 + ';height:' + current_radius/2 + '"><v:fill opacity="10%" color="red"/></v:oval>';

    this.div_.style.width = current_radius/2 + "px";
    this.div_.style.height = current_radius/2 + "px";
    this.div_.style.left = Math.round(center_pixel.x - current_radius/4) + "px";
    this.div_.style.top = Math.round(center_pixel.y - current_radius/4) + "px";
 
   // Remove checkbox ticks
   if(document.getElementById('user_mapstack_pi1[r_toggle]')) document.getElementById('user_mapstack_pi1[r_toggle]').checked = false;
   if(document.getElementById('user_mapstack_pi1[b_toggle]')) document.getElementById('user_mapstack_pi1[b_toggle]').checked = false;
   if(document.getElementById('user_mapstack_pi1[u_toggle]')) document.getElementById('user_mapstack_pi1[u_toggle]').checked = false;

    // Remove markers
    toggleMarkers(r_marker_array, document.getElementById('user_mapstack_pi1[r_toggle]'));
    toggleMarkers(b_marker_array, document.getElementById('user_mapstack_pi1[b_toggle]'));
    toggleMarkers(u_marker_array, document.getElementById('user_mapstack_pi1[u_toggle]'));

    updateMarkers(center, this.radius_);
   }
   
   var radius_div = new CGOverlay(radius, center)
   map.addOverlay(radius_div);
  }

  updateMarkers(center, sel);
  
  // Set checkbox ticks
  if(document.getElementById('user_mapstack_pi1[r_toggle]')) document.getElementById('user_mapstack_pi1[r_toggle]').checked = true;
  if(document.getElementById('user_mapstack_pi1[b_toggle]')) document.getElementById('user_mapstack_pi1[b_toggle]').checked = true;
  if(document.getElementById('user_mapstack_pi1[u_toggle]')) document.getElementById('user_mapstack_pi1[u_toggle]').checked = true;
  
 } else {

  // Remove checkbox ticks
  if(!radius_div) if(document.getElementById('user_mapstack_pi1[r_toggle]')) document.getElementById('user_mapstack_pi1[r_toggle]').checked = false;
  if(!radius_div) if(document.getElementById('user_mapstack_pi1[b_toggle]')) document.getElementById('user_mapstack_pi1[b_toggle]').checked = false;
  if(!radius_div) if(document.getElementById('user_mapstack_pi1[u_toggle]')) document.getElementById('user_mapstack_pi1[u_toggle]').checked = false;

  // Load user home base
  if(type == "home") {
   map.setCenter(new GLatLng(parseFloat(u_markers[sel].getAttribute("lat")),
    parseFloat(u_markers[sel].getAttribute("lng"))), 15);

   document.getElementById("input_lat").value = u_markers[sel].getAttribute("lat");
   document.getElementById("input_lng").value = u_markers[sel].getAttribute("lng");

  // Load chosen town map
  } else {
   var center = new GLatLng(parseFloat(r_markers[sel].getAttribute("lat")),
    parseFloat(r_markers[sel].getAttribute("lng")));
   map.setCenter(center, 13);
   //updateMarkers(center, sel);
  }
  // User markers
  var icon3 = new GIcon();
  icon3.image = icon_url_local+ "mm_20_user.png";
  addIcon(icon3);

  // User marker for current users' home base
  var icon4 = new GIcon();
  icon4.image = icon_url_local+ "mm_20_home.png";
  addIcon(icon4);

  for(var j = 0; j < u_markers.length; j++) {
  var uname = u_markers[j].getAttribute("name");
  var userid = u_markers[j].getAttribute("userid");
  var cpoint = new GLatLng(parseFloat(u_markers[j].getAttribute("lat")),
    parseFloat(u_markers[j].getAttribute("lng")));
  if(curUserId == userid) {
   if(userClicksMode==1) {
    h_marker = new GMarker(cpoint, {icon:icon4, title:"my home base", draggable:true, bouncy:true});
    map.addOverlay(h_marker);
    h_marker.enableDragging();

    // Add event listener for home marker
    GEvent.addListener(h_marker, "dragend", function() {
     
     curpoint = h_marker.getPoint();

     document.getElementById("input_lat").value = curpoint.lat();
     document.getElementById("input_lng").value = curpoint.lng();

     userClicks(h_marker, curpoint);
    });
   } else map.addOverlay(createMarker(cpoint, icon4, uname, userid));
  } else map.addOverlay(createMarker(cpoint, icon3, uname, userid));

 }
  
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  map.addControl(overview);
  setTimeout("posOverview()", 0);
  
 }

 // Add event listener for white and home markers
 GEvent.bind(map, "click", this, this.userClicks);
  
 geocoder = new GClientGeocoder();
 
}

    
function setDirections(fromAddress, toAddress) {
  gdir.load("from: " + fromAddress + " to: " + toAddress,
    { "locale": document.getElementById("userlang") && document.getElementById("userlang").value == "de" ? "de_DE" : "en_US" });
}


function handleErrors(){
  if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS)
    alert("No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.\nError code: " + gdir.getStatus().code);

  else if (gdir.getStatus().code == G_GEO_SERVER_ERROR)
    alert("A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + gdir.getStatus().code);
	   
  else if (gdir.getStatus().code == G_GEO_MISSING_QUERY)
    alert("The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + gdir.getStatus().code);

//  else if (gdir.getStatus().code == G_UNAVAILABLE_ADDRESS)  <--- Doc bug... this is either not defined, or Doc is wrong
//    alert("The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons.\n Error code: " + gdir.getStatus().code);
	     
  else if (gdir.getStatus().code == G_GEO_BAD_KEY)
    alert("The given key is either invalid or does not match the domain for which it was given. \n Error code: " + gdir.getStatus().code);

  else if (gdir.getStatus().code == G_GEO_BAD_REQUEST)
    alert("A directions request could not be successfully parsed.\n Error code: " + gdir.getStatus().code);
	    
  else alert("An unknown error occurred.");
}


function handleMapErrors(){
  alert(gmap.getStatus().code);
}


function setCenter(){
 map.checkResize() ;

 var poly = gdir.getPolyline();
 var markA = (poly.getVertex(0).toUrlValue(5)).split(",");
 var markB = (poly.getVertex(poly.getVertexCount()-1).toUrlValue(5)).split(",");

 var center = new GLatLng(parseFloat(markA[0] + (markB[0] - markA[0]) / 2), parseFloat(markA[1] + (markB[1] - markA[1]) / 2))
 map.setCenter(center, map.getZoom());
}


function fitOrientation(){
 var orientation = getOrientation();
 setOrientation(orientation);
}


function setOrientation(orientation){
 switch (orientation) {
  case "horizontal": 
   mapdiv.style.width = 800 + "px";
   mapdiv.width = 800 + "px";
   mapdiv.style.height = 565 + "px";
   mapdiv.height = 565 + "px";
  break;
  case "vertical": 
   mapdiv.style.width = 565 + "px";
   mapdiv.width = 565 + "px";
   mapdiv.style.height = 800 + "px";
   mapdiv.height = 800 + "px";
  break;
 }
}


function getOrientation(){
 var poly = gdir.getPolyline();
 var markA = (poly.getVertex(0).toUrlValue(5)).split(",");
 var markB = (poly.getVertex(poly.getVertexCount()-1).toUrlValue(5)).split(",");
 var angle = (Math.abs(Math.atan2((markB[0] - markA[0]), (markB[1] - markA[1]))) / (2 * Math.PI)) * 360;

 if ((angle > 45 && angle < 135) || (angle > 225 && angle < 315)) return "vertical";
 else return "horizontal";
}


function onGDirectionsLoad(){
 if (!isStyledMap()) {
  var size = fitOrientation();
  setCenter();
  return;
 }
alert("still here :o");
/*
 var poly = gdir.getPolyline();
 if (poly.getVertexCount() > 1000) {
  alert("This route has too many vertices");
  return;
 }
 var baseUrl = "http://maps.google.com/staticmap?";

 var params = [];
 var gMarkersArray = [];
 gMarkersArray.push(poly.getVertex(0).toUrlValue(5) + ",greena");
 gMarkersArray.push(poly.getVertex(poly.getVertexCount()-1).toUrlValue(5) + ",greenb");
 params.push("markers=" + gMarkersArray.join("|"));

 var polyParams = "rgba:0x0000FF80,weight:5|";
 var polyLatLngs = [];
 for (var j = 0; j < poly.getVertexCount(); j++) {
  polyLatLngs.push(poly.getVertex(j).lat().toFixed(5) + "," + poly.getVertex(j).lng().toFixed(5));
 }
 params.push("path=" + polyParams + polyLatLngs.join("|"));
 params.push("size=512x800");
 params.push("key=ABQIAAAAWhgwkXromNe-ZhQmOWPuFRRQBM5CPB6tnz1SfKqhm7jum9vdjhRG_dloiMS4AtrmGEBPEkm1uQfgfg");

 baseUrl += params.join("&");

 var extraParams = [];
 extraParams.push("center=" + map.getCenter().lat().toFixed(6) + "," + map.getCenter().lng().toFixed(6));
 extraParams.push("zoom=" + map.getZoom());
 addImg(baseUrl + "&" + extraParams.join("&"), "staticMapOverviewIMG");

 var extraParams = [];
 extraParams.push("center=" + poly.getVertex(0).toUrlValue(5));
 extraParams.push("zoom=" + 15);
 addImg(baseUrl + "&" + extraParams.join("&"), "staticMapStartIMG");

 var extraParams = [];
 extraParams.push("center=" + poly.getVertex(poly.getVertexCount()-1).toUrlValue(5));
 extraParams.push("zoom=" + 15);
 addImg(baseUrl + "&" + extraParams.join("&"), "staticMapEndIMG");
*/
}


function addImg(url, id) {
 var img = document.createElement("img");
 img.src = url;
 document.getElementById(id).innerHTML = "";
 document.getElementById(id).appendChild(img);
}


function buildProfileMap(sel) {
 map = new GMap2(mapdiv);

 if((sel) != 0) {

  // Load initial map of current user and disable controls
  map.setCenter(new GLatLng(parseFloat(u_markers[sel].getAttribute("lat")),
   parseFloat(u_markers[sel].getAttribute("lng"))), 10);

  // Fill input fields
  document.getElementById("input_lat").value = parseFloat(u_markers[sel].getAttribute("lat"));
  document.getElementById("input_lng").value = parseFloat(u_markers[sel].getAttribute("lng"));
 }

 // User marker for current users' home base
 var icon4 = new GIcon();
 icon4.image = icon_url_local+ "mm_20_home.png";
 addIcon(icon4);

 // Markers for users
 var icon3 = new GIcon();
 icon3.image = icon_url_local+ "mm_20_user.png";
 addIcon(icon3);

 // Load all user markers
 for(var j = 0; j < u_markers.length; j++) {
  var uname = u_markers[j].getAttribute("name");
  var userid = u_markers[j].getAttribute("userid");
  if(curUserId==userid) {
   var cpoint = new GLatLng(parseFloat(u_markers[j].getAttribute("lat")),
    parseFloat(u_markers[j].getAttribute("lng")));
   map.addOverlay(createMarker(cpoint, icon4, uname, userid));
  } else {
   var upoint = new GLatLng(parseFloat(u_markers[j].getAttribute("lat")),
    parseFloat(u_markers[j].getAttribute("lng")));
   map.addOverlay(createMarker(upoint, icon3, uname, userid));
  }
 }
}


function posOverview() {
  if(!isStyledMap()) return;

  map.checkResize();

  window.setTimeout(function() {
    if (document.getElementById("map_overview")) document.getElementById("map_overview").style.display='none';
  }, 55);

  window.setTimeout(function() {
    var omap = document.getElementById("map_overview");
    var spomap = document.getElementById("map_overview_spacer");

    if (spomap.hasChildNodes()) omap.removeChild(omap.childNodes[0]);

    omap.removeChild(omap.childNodes[1]);
    omap.childNodes[0].style.position = 'relative';
    omap.childNodes[0].style.border = '0';
    omap.childNodes[0].childNodes[0].style.border = '0';
    omap.childNodes[0].childNodes[0].style.position = 'relative';
    omap.childNodes[0].childNodes[0].style.left = '0';
    omap.childNodes[0].childNodes[0].style.top = '0';
    omap.childNodes[0].childNodes[0].style.width = '134px';
    omap.childNodes[0].childNodes[0].style.height = '134px';
    omap.style.position = 'relative';

    spomap.appendChild(omap.childNodes[0]);
  document.getElementById("map").style.visibility = "visible";
  }, 2000);
}


function userClicks(overlay, point) {
 if(point) {
   switch(userClicksMode) {
     case 1:
      userClicksPosMode(overlay, point);
     break;
     default:
      userClicksDistMode(overlay, point);
     break;
  } //END: switch(userClicksMode)
 } //END: if(point)
} //END: function userClicks



function userClicksPosMode(overlay, point) {

  // remove currently set home base marker
  map.removeOverlay(h_marker);
  map.removeOverlay(overlay);

  // Home marker icon
  var icon = new GIcon();
  icon.image = icon_url_local +"mm_20_home.png";
  addIcon(icon);

  map.removeOverlay(markers[0]);
  // Shorten array of markers and points and reset counter
  markers.splice(0, 1);
  points.splice(0, 1);

  // Make marker draggable
  var u_marker = new GMarker(point, {icon:icon, draggable: true});
  map.addOverlay(u_marker);
  u_marker.enableDragging();
  u_marker.content = count;

  markers[0] = u_marker;
  points[0] = point;

  u_marker.tooltip = "<div class='tooltip'>Position " + point + "<\/div>";


  document.getElementById("input_lat").value = point.lat();
  document.getElementById("input_lng").value = point.lng();


  GEvent.addListener(u_marker, "mouseover", function() {
   showTooltip(u_marker);
  });

  GEvent.addListener(u_marker, "mouseout", function() {
   tooltip.style.display = "none";
  });


  GEvent.addListener(u_marker, "dragend", function() {
    
    // Find out dragged marker and replace points while dragging
    for(var v = 0; v < markers.length; v++) {

      if(markers[v] == u_marker) {
        map.removeOverlay(points[v]);
        points.splice(v, 1, u_marker.getPoint());
      }
      
      document.getElementById("input_lat").value = points[v].lat();
      document.getElementById("input_lng").value = points[v].lng();
      
    }
    
    update();

  });


  GEvent.addListener(u_marker, "click", function() {

  // Find out removed marker
  for(var n = 0; n < markers.length; n++) {

   if(markers[n] == u_marker) {
    map.removeOverlay(markers[n]);
    break;
   }
  }
  // Shorten array of markers and points and reset counter
  markers.splice(n, 1); points.splice(n, 1);
  if(markers.length == 0) { count = 0; }
  
  document.getElementById("input_lat").value = "";
  document.getElementById("input_lng").value = "";

  update();

  });

} //END: function


function userClicksDistMode(overlay, point) {

  // White marker icons
  var icon = new GIcon();
  icon.image = icon_url +"mm_20_white.png";
  addIcon(icon);

  count++;
  // Make marker draggable
  var w_marker = new GMarker(point, {icon:icon, draggable: true});
  map.addOverlay(w_marker);
  w_marker.enableDragging();
  w_marker.content = count;
  markers.push(w_marker);
  points.push(point);

  w_marker.tooltip = "<div class='tooltip'>Punkt "+ count+ "<\/div>";

  GEvent.addListener(w_marker, "mouseover", function() {
   showTooltip(w_marker);
  });

  GEvent.addListener(w_marker, "mouseout", function() {
   tooltip.style.display = "none";
  });

  GEvent.addListener(w_marker, "drag", function() {

    // Remove black polylines before replacing them
    for(var u= 0; u < route_lines.length; u++) {
     map.removeOverlay(route_lines[u]);
    }

    // Find out dragged marker and replace points while dragging
    for(var v = 0; v < markers.length; v++) {

      if(markers[v] == w_marker) {
        map.removeOverlay(points[v]);
        points.splice(v, 1, w_marker.getPoint());
      }
    }

    update();
  });

  if(markers.length > 1) {

    // Black polyline
    var poly = new GPolyline([points[points.length-2], point], "#000000", 2, 0.7);
    map.addOverlay(poly);
    route_lines.push(poly);

    // Calculate distance of white points
    routeDistance();
  }

  GEvent.addListener(w_marker, "click", function() {

  // Remove all black polylines before drawing the shorter route
  for(var m= 0; m < route_lines.length; m++) {
   map.removeOverlay(route_lines[m]);
  }
  // Reset array of black polylines
  route_lines.length = 0;

  // Find out removed marker
  for(var n = 0; n < markers.length; n++) {

   if(markers[n] == w_marker) {
    map.removeOverlay(markers[n]);
    break;
   }
  }
  // Shorten array of markers and points and reset counter
  markers.splice(n, 1); points.splice(n, 1);
  if(markers.length == 0) { count = 0; }

  update();
  });

} //END: function



function update() {

 tooltip.style.display= "none";

 // Update side bar info
 routeDistance();
 if(markers.length <= 1) { sidebar.innerHTML = "&nbsp;"; }

 // Draw new route
 var newpoly = new GPolyline(points, "#000000", 2, 0.7);
 map.addOverlay(newpoly);
 route_lines.push(newpoly);
}


function routeDistance() { // Show entire distance of clicked points in side bar
/*
 var dist = 0;
 for(var i = 1; i < points.length; i++) {
  dist += calc(points[i-1].lat(), points[i-1].lng(), points[i].lat(), points[i].lng());
 }

 if(dist > 10) { dist= Math.round(dist)+ " km"; }
 else { dist= Math.round(dist*1000) + " m"; }

 var info_html= "<strong>Punkt "+ markers[0].content + " - ";
 info_html += "Punkt " + markers[markers.length-1].content;
 info_html += "<\/strong><br \/>Luftlinie: " + dist;

 sidebar.innerHTML = info_html;*/
}


function checkRadius(radius, center, point) { // Check if point is in selected radius

 var dist = 0;
 dist = calc(center.lat(), center.lng(), point.lat(), point.lng());

 if(dist < radius) return true;
 else return false;
 
}


function townDistance(townname, destination) {

 var goal_lat, goal_lng, home_lat, home_lng;

 if( destination.match(/(\d+)/)) {
  var nr = RegExp.$1;

  // Loop through tooltips to find white points
  for(var i = 0; i < points.length; i++) {
   if (markers[i].content == nr) {
    goal_lat = points[i].lat();
    goal_lng = points[i].lng();
    break;
   }
  }
 }

 var labels = new Array(r_markers, b_markers);

 for(var j = 0; j < labels.length; j++) {
  var label = labels[j];

  // Loop through all labels of xml file
 LOOP:
   for (var k = 0; k < label.length; k++) {
    var town = label[k].getAttribute("name");

    // Make input case insensitive
    if(destination.toLowerCase() == town.toLowerCase()) {
     goal_lat = label[k].getAttribute("lat");
     goal_lng = label[k].getAttribute("lng");
    }

    if(townname == town) {
      home_lat = label[k].getAttribute("lat");
      home_lng = label[k].getAttribute("lng");
    }

   if( home_lat && goal_lat) { break LOOP; }
  }
 }

 if(goal_lat) {

  // Blue polyline
  var poly = new GPolyline([ new GLatLng( home_lat, home_lng),
   new GLatLng(goal_lat, goal_lng) ], "#0000af", 2, 0.8);
  map.addOverlay(poly); blue_lines.push(poly);

  var dist = Math.round(calc(home_lat, home_lng, goal_lat, goal_lng) );

  // Show distance to given town or point in infowindow
  if(nr) { destination = "Punkt " + nr; }
  else { destination= destination.replace(/^./, destination.charAt(0).toUpperCase()); }
  var info_html ="<div class='infowindow'>";
  info_html += "<p><strong>"+ townname + " - " + destination;
  info_html += "<\/strong><br \/>Luftlinie: "+ dist + " km<\/p><\/div>";

  var size = new GSize(5, -20);
  var point = new GLatLng(home_lat, home_lng);
  map.openInfoWindowHtml(point, info_html, size);
 }
  else { alert(destination + " ist nicht auf der Karte."); }
}


function calc(lat1, lng1, lat2, lng2) { // Calculate distance in km

 var r = 6371.3 ; // Mean radius of earth in km
 var x = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2));
 var y = Math.cos(deg2rad(lat1))* Math.cos(deg2rad(lat2));
 var s = r * Math.acos(x + y * Math.cos(deg2rad(lng1-lng2)));

 return s;
}

function deg2rad(deg) { // Convert decimal degrees to radians

 return deg/(180/Math.PI);
}


function clearItems() { // Remove all polylines and white markers

 var lines = blue_lines.concat(route_lines);
  for(var i= 0; i < lines.length; i++) {
   map.removeOverlay(lines[i]);
  }
  blue_lines.length = route_lines.length = 0;
  sidebar.innerHTML = "&nbsp;";

  for(var j = 0; j < markers.length; j++) {
   map.removeOverlay(markers[j]);
  }
  markers.length = points.length = count = 0;
  map.closeInfoWindow();
}


function clearMap() { // Clear map container

 clearItems();
 mapdiv.innerHTML = "";
 map.removeControl(overview);

}

function toggleMarkers(removed_markers, cb, radius, center) {

 if(cb.checked == false) {
  for(i = 0; i < removed_markers.length; i++) {
    map.removeOverlay(removed_markers[i]);
  }
 } else {
  for(i = 0; i < removed_markers.length; i++) {
   map.addOverlay(removed_markers[i]);
  }
 }

}

function addAddressToMap(response) {
 map.clearOverlays();
 if (!response || response.Status.code != 200) {
  alert("Sorry, we were unable to geocode that address");
 } else {
  place = response.Placemark[0];
  point = new GLatLng(place.Point.coordinates[1],
   place.Point.coordinates[0]);
  map.setCenter(point, 10);
  marker = new GMarker(point);
  map.addOverlay(marker);
  marker.openInfoWindowHtml(place.address + '<br>' +
  '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
 }
}

function getGeoCodeAddress(address, location) {

 if(location!="") address = address + ", " + location;

 geocoder.getLocations(address, addAddressToMap);
 /*geocoder.getLatLng(
  address,
  function(point) {
   if(!point) {
    alert(address + " not found");
   } else {
    var marker = new GMarker(point);
    map.addOverlay(marker);
    marker.openInfoWindowHtml(place.address + '<br>' +
  '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
   }
  }
 );*/
 
 // Remove checkbox ticks
 if(document.getElementById('user_mapstack_pi1[r_toggle]')) document.getElementById('user_mapstack_pi1[r_toggle]').checked = false;
 if(document.getElementById('user_mapstack_pi1[b_toggle]')) document.getElementById('user_mapstack_pi1[b_toggle]').checked = false;
 if(document.getElementById('user_mapstack_pi1[u_toggle]')) document.getElementById('user_mapstack_pi1[u_toggle]').checked = false;
 
 // Remove markers
 toggleMarkers(r_marker_array, document.getElementById('user_mapstack_pi1[r_toggle]'));
 toggleMarkers(b_marker_array, document.getElementById('user_mapstack_pi1[b_toggle]'));
 toggleMarkers(u_marker_array, document.getElementById('user_mapstack_pi1[u_toggle]'));
 
}

function updateMarkers(center, radius) {
 
 // Red marker icons for German cities
 var icon = new GIcon();
 icon.image = icon_url +"mm_20_red.png";
 addIcon(icon);

 // Blue markers for EU-capitals
 var icon2 = new GIcon();
 icon2.image = icon_url+ "mm_20_blue.png";
 addIcon(icon2);

 // Load all red and blue markers
 for(var i = 1; i < r_markers.length; i++) {
  var point = new GLatLng(parseFloat(r_markers[i].getAttribute("lat")),
   parseFloat(r_markers[i].getAttribute("lng")));
  var townname = r_markers[i].getAttribute("name");
  if(radius == 0) map.addOverlay(createMarker(point, icon, townname, 0));
  else {
   if(checkRadius(radius, center, point) == true) map.addOverlay(createMarker(point, icon, townname, 0));
  }
 }

 for(var j = 0; j < b_markers.length; j++) {
  var bpoint = new GLatLng(parseFloat(b_markers[j].getAttribute("lat")),
   parseFloat(b_markers[j].getAttribute("lng")));
  var bname = b_markers[j].getAttribute("name");
  if(radius == 0) map.addOverlay(createMarker(bpoint, icon2, bname, 0));
  else if(checkRadius(radius, center, bpoint) == true) map.addOverlay(createMarker(bpoint, icon2, bname, 0));
 }

 // User markers for other users
 var icon3 = new GIcon();
 icon3.image = icon_url_local+ "mm_20_user.png";
 addIcon(icon3);

 // User marker for current user's home base
 var icon4 = new GIcon();
 icon4.image = icon_url_local+ "mm_20_home.png";
 addIcon(icon4);

 curUserId = 1;
 for(var j = 0; j < u_markers.length; j++) {
  var uname = u_markers[j].getAttribute("name");
  var userid = u_markers[j].getAttribute("userid");
  if(curUserId==userid) {
   var cpoint = new GLatLng(parseFloat(u_markers[j].getAttribute("lat")),
    parseFloat(u_markers[j].getAttribute("lng")));
   map.addOverlay(createMarker(cpoint, icon4, uname, userid));
  } else {
   var upoint = new GLatLng(parseFloat(u_markers[j].getAttribute("lat")),
    parseFloat(u_markers[j].getAttribute("lng")));
   if(radius == 0) map.addOverlay(createMarker(upoint, icon3, uname, userid));
   else if(checkRadius(radius, center, upoint) == true) map.addOverlay(createMarker(upoint, icon3, uname, userid));
  }
 }

}

function fillRadiusSelect(type, sel, curZoom) {
/*
 // Fill radii select box
 if(sel == 0 && curZoom==5) var zoomval = 5;
 else if(type=="town") var zoomval = 13;
 if(!zoomval) var checkZoom = curZoom;
 else var checkZoom = zoomval;
 radius_list = new Array(0.125,0.25,0.5,1,5,10,20,50,100,150,200,400,800);
 var radius = document.getElementById('id_radius');
 if(checkZoom < 8) {
  var initval = 9;
  var endval = radius_list.length;
 }
 if(checkZoom >= 8 && checkZoom <= 10) {
  var initval = 7;
  var endval = 11;
 }
 if(checkZoom > 10 && checkZoom <= 13) {
  var initval = 3;
  var endval = 7;
 }
 if(checkZoom > 13) {
  var initval = 0;
  var endval = 4;
 }
 radius[0] = new Option("**kein Umkreis**");
 counter = 1;
 for(var i = initval; i < endval; i++) {
  if(!isInt(radius_list[i])) var text = radius_list[i] * 1000 + " m";
  else var text = radius_list[i] + "km";
  radius[counter] = new Option(text, radius_list[i]);
  if(type == "radius" && radius_list[i] == sel) radius[counter].selected = true;
  counter++;
 }
*/
}

function isInt(myNum) {
 // get the modulus: if it's 0, then it's an integer
 var myMod = myNum % 1;

 if(myMod == 0) {
  return true;
 } else {
  return false;
 }
}


// Directions step map related stuff
var turnCounter = 0;
function transform(points, radians, translate) {
 // Calculate center of triangle
 var center = [((points[0][0] + points[1][0] + points[2][0]) / 3), ((points[0][1] + points[1][1] + points[2][1]) / 3)];

 // Translate center to 0,0
 points[0] = [(points[0][0] - center[0]), (points[0][1] - center[1])];
 points[1] = [(points[1][0] - center[0]), (points[1][1] - center[1])];
 points[2] = [(points[2][0] - center[0]), (points[2][1] - center[1])];

 if (radians * 180 / Math.PI != 0) {
 // Rotate points by rotation (angle)
  points[0] = [(Math.cos(radians) * points[0][0] - Math.sin(radians) * points[0][1]), (Math.sin(radians) * points[0][0] + Math.cos(radians) * points[0][1])];
  points[1] = [(Math.cos(radians) * points[1][0] - Math.sin(radians) * points[1][1]), (Math.sin(radians) * points[1][0] + Math.cos(radians) * points[1][1])];
  points[2] = [(Math.cos(radians) * points[2][0] - Math.sin(radians) * points[2][1]), (Math.sin(radians) * points[2][0] + Math.cos(radians) * points[2][1])];
 }

 // Translate center to position
 points[0] = [(points[0][0] + translate[0]), (points[0][1] + translate[1])];
 points[1] = [(points[1][0] + translate[0]), (points[1][1] + translate[1])];
 points[2] = [(points[2][0] + translate[0]), (points[2][1] + translate[1])];

 points = [[Math.round(points[0][0]), Math.round(points[0][1])], [Math.round(points[1][0]), Math.round(points[1][1])], [Math.round(points[2][0]), Math.round(points[2][1])]];

 return points;
}


function addDirectionsArrow(map, position, rotation) {
  var div = document.createElement("div");
  map.getPane(G_MAP_MARKER_SHADOW_PANE).appendChild(div);

  this.map_ = map;
  this.div_ = div;
  
  //set up arrow invariants
  if(navigator.userAgent.indexOf("MSIE") != -1){

	var s = document.createElement("v:stroke");
	s.opacity = 0.5;
	if(rotation >= 0)
		s.startarrow="classic";// or "block", "open" etc see VML spec
	l.appendChild(s);
	this.div_.appendChild(l);
	this.vmlLine_ = l;
  }
  else{

	var svgNS = "http://www.w3.org/2000/svg";
	var svgRoot = document.createElementNS(svgNS, "svg");
	svgRoot.setAttribute("width", 256);
	svgRoot.setAttribute("height", 256);
	svgRoot.setAttribute("stroke", "#000088");
	svgRoot.setAttribute("fill", "#000088");
	svgRoot.setAttribute("stroke-opacity", 0.5);
	svgRoot.setAttribute("fill-opacity", 0.5);
	this.div_.appendChild(svgRoot);

      	var arrow = document.createElementNS(svgNS, "polygon");
      	arrow.setAttributeNS(null, "points", transform([[7,7], [-7,7], [0,-8]], ((Math.PI * rotation) / 180), position));
        arrow.setAttributeNS(null, "stroke", "none");
        arrow.setAttributeNS(null, "fill", "#000088");

	svgRoot.appendChild(arrow);

      	var circle = document.createElementNS(svgNS, "circle");
        circle.setAttribute('cx', position[0]);
        circle.setAttribute('cy', position[1]);
        circle.setAttribute('r', 2);
        circle.setAttribute('fill', 'red');

	svgRoot.appendChild(circle);

	this.svgRoot_ = svgRoot;

  }
}

function getDistance(pointX, pointY) {
 return Math.sqrt((pointY.x - pointX.x) * (pointY.x - pointX.x) + (pointY.y - pointX.y) * (pointY.y - pointX.y));
}

function getClosestOnPoly(latlng) {
 var poly = gdir.getPolyline();
 var pointZ = new GPoint(0,0);
 var index;

 for (i = 0; i < poly.getVertexCount(); i++) {
  pointX = poly.getVertex(i);
  pointY = latlng;

  if (getDistance(pointX, pointY) < getDistance(pointY, pointZ)) {
   pointZ = pointX;
   index = i;
  }
 }

 return getNextOnPoly(pointZ, index);
}

function getNextOnPoly(point, index)  {
 var poly = gdir.getPolyline();
 return bearing(point, poly.getVertex(index + 1)) == 0 ? getNextOnPoly(point, index + 1) : [point, poly.getVertex(index + 1)];
}

function processTurnByTurn()  {
  var stepNode;
  var stepTextNode;
  var stepMarker;
  var stepMap;
  var stepMapNode;
  var stepPoly;
  turnCounter++;

  if (turnCounter <= gdir.getRoute(0).getNumSteps()) {
    stepNode = document.createElement("div");
    document.getElementById("options").appendChild(stepNode);

    stepMapNode = document.createElement("div");
    stepNode.appendChild(stepMapNode);

    stepTextNode = document.createElement("div");
    stepNode.appendChild(stepTextNode);

    stepMap = new GMap2(stepMapNode, {size: new GSize(256, 256)});
    GEvent.addListener(stepMap, "error", handleMapErrors);
    stepMap.setCenter(gdir.getRoute(0).getStep(turnCounter-1).getLatLng());

var points = getClosestOnPoly(gdir.getRoute(0).getStep(turnCounter-1).getLatLng());
var rotation = Math.round(bearing(points[0], points[1]));

    stepMap.setZoom(15);
    stepMap.addOverlay(gdir.getPolyline().copy());

    stepTextNode.innerHTML = gdir.getRoute(0).getStep(turnCounter-1).getDescriptionHtml();

    var currtype = stepMap.getCurrentMapType().getProjection();

    addDirectionsArrow(stepMap, [128, 128], rotation);
  } else {
    document.getElementById("getTurnByTurnDirections").enabled = false;
  }  
}
/*
function onMapReady(event) {
  map.setCenter(new LatLng(41.651505,-72.094455), 8, MapType.NORMAL_MAP_TYPE);
  dir = new Directions();
  dir.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, onDirLoad);
  dir.addEventListener(DirectionsEvent.DIRECTIONS_FAILURE, onDirFail);
}

function onDirFail(event) {
  Alert.show("Status: " + event.directions.status);
  step.htmlText = "";
}

function onDirLoad(event) {
  var dir = event.directions;       
  var startMarker;
  var endMarker;
        
  map.clearOverlays();
  map.addOverlay(dir.createPolyline());
  map.setZoom(map.getBoundsZoomLevel(dir.bounds));
  map.setCenter(dir.bounds.getCenter());
  
  startMarker = new Marker(dir.getRoute(0).startGeocode.point, new MarkerOptions({fillStyle: {color:Color.GREEN}}));
  endMarker = new Marker(dir.getRoute(0).endGeocode.point, new MarkerOptions({fillStyle: {color:Color.BLUE}}));
  map.addOverlay(startMarker);
  map.addOverlay(endMarker);
}

*/

     // Returns the bearing in degrees between two points.
     // North = 0, East = 90, South = 180, West = 270.
     function bearing( from, to ) {
       // See T. Vincenty, Survey Review, 23, No 176, p 88-93,1975.
       // Convert to radians.
       var lat1 = from.latRadians();
       var lon1 = from.lngRadians();
       var lat2 = to.latRadians();
       var lon2 = to.lngRadians();

       // Compute the angle.
       var angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) );
       if ( angle < 0.0 )
	       angle  += Math.PI * 2.0;

       // And convert result to degrees.
       angle = angle * 180.0 / Math.PI;

       return angle;
       
     }