
// Global variables
var map;
var blue_lines = new Array();
var route_lines = new Array();
var count = 0;
var points = new Array();
var markers = new Array();
var r_markers, b_markers, tooltip, overview;

if(navigator.userAgent.match(/Firefox\/([.0-9]+)/i)) {

 if(parseFloat(RegExp.$1) >= 1.5) svgon();
}

function svgon() { // Turn SVG on

 _mSvgEnabled = _mSvgForced = true;
}
function readData() { // Load and read XML file using Ajax

 var request = GXmlHttp.create();
 request.open("GET", "fileadmin/lageplan/db.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");
   buildMap(0);

  // Create options list
  var choose = document.getElementById('gmap_list');
  for(var i = 0; i < r_markers.length; i++) {
   choose[i] = new Option(r_markers[i].getAttribute("name"));
  }
  // Select first entry of list
  choose[0].selected = 1;

  }
 }; request.send(null);
}


function createMarker(point, icon, name) {

 var marker = new GMarker(point, icon );
 marker.tooltip = '<div class="tooltip">'+ name+ '</div>';

 var form_html ='<div class="infowindow">';
 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="suchen"';
 form_html += ' onclick="townDistance(\'' + name + '\', this.form.loc.value)" />';
 form_html +='</form></p></div>';

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

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

 GEvent.addListener(marker, "click", function() {
  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)); 
 pos.apply(tooltip);
}


function buildMap(sel) {
 map = new GMap2(mapdiv);
 // Add event listener for white markers
 GEvent.bind(map, "click", this, this.userClicks);
 // 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;
 });
 overview = new GOverviewMapControl(new GSize(165,165));
 if((sel) == 0) {
  // Load initial map of Germany and a bunch of controls
  map.setCenter(new GLatLng(parseFloat(r_markers[0].getAttribute("lat")),
   parseFloat(r_markers[0].getAttribute("lng"))), 11);
  map.addControl(new GLargeMapControl()); // Zoom control
  map.addControl(new GMapTypeControl()); // Toggle between map types
  map.addControl(new GScaleControl()); // Scale bar
  map.addControl(overview);
  setOverviewPos();
  // 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 town 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");
   map.addOverlay(createMarker(point, icon, townname));
  }
  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");
   map.addOverlay(createMarker(bpoint, icon2, bname));
  }
 }
 else { // Load chosen town map
  map.setCenter(new GLatLng(parseFloat(r_markers[sel].getAttribute("lat")),
   parseFloat(r_markers[sel].getAttribute("lng"))), 14);
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  map.addControl(overview);
  setOverviewPos();
 }
}

function posOverview() {
 /*map.checkResize();
 var omap = document.getElementById("map_overview");
 document.getElementById("gmap_overview").appendChild(omap);
 if(omap) {
  omap.style.left = "0";
  omap.style.top = "300px";
 }*/
}

function setOverviewPos() {
 setTimeout("posOverview()", 500);
}


function userClicks(overlay, point) {

 if(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();
  });
 }
}


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 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);
}