  var myMap = null;
  var myMapType = null;
  var cw_city_zoomLevel = 12;
  var gmarkers = [];
  var gicons = [];
	var crimesAmount = [];
  // The allowed region which the whole map must be within
  var allowedBounds = new GLatLngBounds(new GLatLng(52.37224557,13.12316895), new GLatLng(52.71133933,13.67248535));
	
	crimesAmount['Brand'] = 0;
	crimesAmount['Diebstahl'] = 0;
	crimesAmount['Koerperverletzung'] = 0;
	crimesAmount['Mord'] = 0;
	crimesAmount['Raub'] = 0;
	crimesAmount['Unfall'] = 0;
	crimesAmount['Diverses'] = 0;

  gicons["Brand"] = createIcon("Brand");
	gicons["Diebstahl"] = createIcon("Diebstahl");
	gicons["Koerperverletzung"] = createIcon("Koerperverletzung");
	gicons["Mord"] = createIcon("Mord");
  gicons["Raub"] = createIcon("Raub");
	gicons["Unfall"] = createIcon("Unfall");
	gicons["Diverses"] = createIcon("Diverses");

  var cw_berlin = new GLatLng(52.52389816959583, 13.411474227905273);
  var cw_charlottenburg = new GLatLng(52.511151, 13.301472);
  var cw_friedrichshain = new GLatLng(52.512727, 13.445510);
  var cw_hellersdorf = new GLatLng(52.533024, 13.609286);
  var cw_koepenick = new GLatLng(52.442560, 13.582385);
  var cw_kreuzberg = new GLatLng(52.498402, 13.395996);
  var cw_lichtenberg = new GLatLng(52.514556, 13.498307);
  var cw_marzahn = new GLatLng(52.544741, 13.564412);
  var cw_mitte = new GLatLng(52.522124, 13.397590);
  var cw_neukoelln = new GLatLng(52.480818, 13.424997);
  var cw_pankow = new GLatLng(52.569569, 13.403145);
  var cw_reinickendorf = new GLatLng(52.574264, 13.347776);
  var cw_schoeneberg = new GLatLng(52.486875, 13.357190);
  var cw_spandau = new GLatLng(52.534072, 13.181689);
  var cw_steglitz = new GLatLng(52.452659, 13.330793);
  var cw_tempelhof = new GLatLng(52.478192, 13.385976);
  var cw_treptow = new GLatLng(52.490708, 13.445931);
  var cw_wilmersdorf = new GLatLng(52.483756, 13.320199);
  var cw_zehlendorf = new GLatLng(52.441071, 13.257859);
  
  
  // Create an icon
  function createIcon(color) {
    var icon = new GIcon();
    icon.image = "/img/marker/cw_marker_"+color+".png";
    icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
    icon.iconSize = new GSize(12, 25);
    icon.shadowSize = new GSize(22, 20);
    icon.iconAnchor = new GPoint(6, 25);
    icon.infoWindowAnchor = new GPoint(5, 1); 
    return icon;
  };
  
  // Create a marker and set up the event window
  function createMarker(point,crime,title,date,message,link) {
    var marker = new GMarker(point, gicons[crime]);
    // Store the crime info as a marker properties 
    marker.mycrime = crime;
		
		message = message.replace(/\&lt;br&gt;/g,"<br>");
		message = message.replace(/\&lt;br \/&gt;/g,"<br>");
		message = message.replace(/\&amp;ndash;/g,"-");
		title   = title.replace(/\&amp;#8222;/g,"\"");
		
		if (crime == "Koerperverletzung")
		  crime = "K&ouml;rperverletzung";
	
	  GEvent.addListener(marker, 'click', function() { 
      marker.openExtInfoWindow(
        myMap,
        "custom_info_window_CrimeWatching",
        "<div class='crime'>" + crime + "</div>"+
        "<div class='date'>&curren; " + date + "</div>"+
        "<div class='title'>" + title + "</div>",
        {beakOffset: 3,
	       maxContent: "<div class='crime'>" + crime + "</div>"+
                     "<div class='date'>&curren; " + date + "</div>"+
                     "<div class='title'>" + title + "</div>"+
                     "<div class='message'><div class='message_head'> Meldung: </div>" + message + "</div>"+
                     "<div class='source'>&raquo; <a href='" + link + "' target='_blank'>Quelle</a></div>"}
      ); 
    });
    // Save the marker in the array
    gmarkers.push(marker);
    return marker;
  };

  // Shows all markers of a particular crime, and ensures the checkbox is checked 
   function show(crime) {
    for (var i = 0; i < gmarkers.length; i++) {
      if (gmarkers[i].mycrime == crime) {
        gmarkers[i].show();
      }
    }
    // Check the checkbox 
    document.getElementById(crime+"box").checked = true;
  };

  // Hides all markers of a particular crime, and ensures the checkbox is cleared 
  function hide(crime) {
    for (var i = 0; i < gmarkers.length; i++) {
      if (gmarkers[i].mycrime == crime) {
		    gmarkers[i].hide();
      }
    }
    // Clear the checkbox 
    document.getElementById(crime+"box").checked = false;
    // Close the info window, in case its open on a marker that we just hid
    myMap.closeExtInfoWindow();
  };

  // Checkbox has been clicked 
  function boxclick(box,crime) {
    if (box.checked) {
      show(crime);
    } else {
      hide(crime);
    }
  };

  function myclick(i) {
    GEvent.trigger(gmarkers[i],"click");
  };
	  
  // Get the crime-messages from the db using a AJAX.REQUEST
  function getData() {
    var myAjax = new Ajax.Request(
      "/db/getData.php",
      { method: 'get', onComplete: parseData }
    );
  };

  // Get the responseText (STRING) from the Request
  // and convert it into a JSON-array
  function parseData(originalRequest) {
    // Evaluates the JSON in the string and returns the resulting object (array)
    var json = originalRequest.responseText.evalJSON();
	
	  for (var i = 0; i < json.length; i++) {
	    if (json[i].Crime == "Brand" 
			    || json[i].Crime == "Diebstahl" 
          || json[i].Crime == "Koerperverletzung" 
          || json[i].Crime == "Mord" 
          || json[i].Crime == "Raub" 
          || json[i].Crime == "Unfall" 
          || json[i].Crime == "Diverses" ) {
        var lat = parseFloat(json[i].Latitude);
        var lng = parseFloat(json[i].Longitude);
        var point = new GLatLng(lat,lng);
		    var crime = json[i].Crime;  
        var date = json[i].Date;
        var title = json[i].Title;
		    var message = json[i].Message;
		    var link = json[i].Link;
	
        // Create the marker
        var marker = createMarker(point,crime,title,date,message,link);
		    // Add the marker to the map
        myMap.addOverlay(marker);
				// Amount of the crime
				crimesAmount[crime]++;
	    }
	  }
	  // Show or hide the crimes initially 
	  show("Brand");
		show("Diebstahl");
		show("Koerperverletzung");
		show("Mord");
	  show("Raub");
		show("Unfall");
		show("Diverses");
    
    // Hide "Loading"
    setTimeout('hideLoading()', 1000);
  };
	  
  // Display the map
  function displayMap() {
    // Create the map
    myMap = new GMap2(document.getElementById("content_map"));
    myMap.addMapType(G_PHYSICAL_MAP);
    //myMap.setCenter(cw_berlin, cw_city_zoomLevel, G_PHYSICAL_MAP);
    // G_HYBRID_MAP
		var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(10,40));
    myMap.addControl(new GLargeMapControl(), pos);
    myMap.addControl(new GMapTypeControl());
    myMap.enableContinuousZoom();
    myMap.enableScrollWheelZoom();
    
    // Restricting the range of Zoom Levels
    // Get the list of map types      
    var mt = myMap.getMapTypes();
    // Overwrite the getMinimumResolution() and getMaximumResolution() methods
    for (var i=0; i<mt.length; i++) {
      mt[i].getMinimumResolution = function() {return 10;}
      mt[i].getMaximumResolution = function() {return 17;}
    }


    //myMap.addControl(new GLargeMapControl());
    //myMap.addControl(new GMapTypeControl());
    //myMap.setCenter(new GLatLng(53.3,-1.6), 7);
    myMap.setCenter(cw_berlin, cw_city_zoomLevel, G_PHYSICAL_MAP);
    
    // Show "Loading"
    showLoading();
    
	  // Get the crime-messages from the db
    getData();
    
    // Add a move listener to restrict the bounds range
    GEvent.addListener(myMap, "move", function() {
      checkBounds();
    });
  };
      
  // If the map position is out of range, move it back
  function checkBounds() {
    // Perform the check and return if OK
    if (allowedBounds.contains(myMap.getCenter())) {
      return;
    }
    // It`s not OK, so find the nearest allowed point and move there
    var C = myMap.getCenter();
    var X = C.lng();
    var Y = C.lat();

    var AmaxX = allowedBounds.getNorthEast().lng();
    var AmaxY = allowedBounds.getNorthEast().lat();
    var AminX = allowedBounds.getSouthWest().lng();
    var AminY = allowedBounds.getSouthWest().lat();

    if (X < AminX) {X = AminX;}
    if (X > AmaxX) {X = AmaxX;}
    if (Y < AminY) {Y = AminY;}
    if (Y > AmaxY) {Y = AmaxY;}
    //alert ("Restricting "+Y+" "+X);
    myMap.setCenter(new GLatLng(Y,X));
  };
	
	function hideChart() {
	  var chart = document.getElementById('content_chart');
		chart.style.display = 'none';
	};
	
	// Fade-in and out
	function doFade(targetElement, duration, from, to, toggle) {
	  Spry.Effect.DoFade(targetElement, {duration: duration, from: from, to: to, toggle: toggle});
  };
  
  // Show the "load content" dialog
  function showLoading() {
    $('overlay').setStyle({ display: 'block' });
    new Effect.Opacity('overlay', { from: 0.0, to: 0.8, duration: 0.5 });
    new Effect.Appear('load_content', { duration: 0.5, queue: 'end' });
  };
  
  
  // Hide the "load content" dialog
  function hideLoading() {
	  new Effect.DropOut('load_content');
    //new Effect.Fade('load_content', { duration: 0.5, });
	  new Effect.Opacity('overlay', { from: 0.8, to: 0.0, duration: 0.5, queue: 'end' });
    
    setTimeout('loadingDisplayNone()', 1000);
  };

  function loadingDisplayNone() {
    $('overlay').setStyle({ display: 'none' });
	  $('load_content').setStyle({ display: 'none' });
  };
  
  
