google.load("maps", "2");

jQuery(document).unload(function() {
  google.maps.Unload();
});

var Map = function(element) {
  var map = new google.maps.Map2(element);
  this.getMap = function() {
    return map;
  };

  this.centre = function(lat,lon) {
    map.setCenter(new google.maps.LatLng(lat,lon), 15);
  };

  this.centreWithZoom = function(lat,lon, zoom) {
    map.setCenter(new google.maps.LatLng(lat,lon), zoom);
  };

  this.mini_centre = function(lat,lon) {
    map.setCenter(new google.maps.LatLng(lat,lon-0.003), 13);
  };
  this.addControls = function() {
    map.addControl(
      new google.maps.LargeMapControl(),
      new google.maps.ControlPosition(
        google.maps.ANCHOR_BOTTOM_RIGHT,
        new google.maps.Size(5, 50)
      )
    );
    map.addControl(
      new google.maps.MapTypeControl(),
      new google.maps.ControlPosition(
        google.maps.ANCHOR_BOTTOM_RIGHT,
        new google.maps.Size(5, 18)
      )
    );
  };
  this.addMarker = function(lat,lon) {
    var baseIcon = new GIcon();
    baseIcon.image = "/images/map/icon.png";
    baseIcon.iconSize = new GSize(65, 85);
    baseIcon.iconAnchor = new GPoint(32, 83);
    baseIcon.shadow = "/images/map/icon-shadow.png";
    baseIcon.shadowSize = new GSize(110, 81);
    var icon = new GIcon(baseIcon);
    var point = new GLatLng(lat,lon);
    var marker = new GMarker(point, icon);
    map.addOverlay(marker);
  };
  this.getBounds = function(){
    return map.getBounds();
  };
  this.addLayer = function(layer){
    map.addOverlay(layer);
  };
  this.removeLayer = function(layer){
    map.removeOverlay(layer);
  };
  this.getBoundsZoomLevel = function( boundary ){
      return map.getBoundsZoomLevel( boundary );
  };
  this.setZoom = function( level ){
     map.setZoom(level);
  };
  this.centrar = function( centro , zoomlevel) {
    //recenter = new google.maps.LatLng( centro.lat(), centro.lng()-(0.008*zoomlevel/10) )
    map.setCenter( centro , zoomlevel);
  };

  this.showcentre = function( point ) {
    var baseIcon = new GIcon();
    baseIcon.image = "/images/pin.png";
    baseIcon.iconSize = new GSize(24, 24);
    baseIcon.iconAnchor = new GPoint(24, 24);
    var icon = new GIcon(baseIcon);
    var marker = new GMarker( point , icon);
    map.addOverlay(marker);
  };

  this.addKml = function( kml_path ){
    var geoXml = new GGeoXml(kml_path);
    map.addOverlay(geoXml);
  };

  this.addOverlay = function( objekt ){
    map.addOverlay( objekt);
  };

  this.addDirections = function(directions_div, searchString) {
    var directions = new GDirections(map);
    var boundaries = new GLatLngBounds( );

    // fetch directions from google
    directions.load(searchString, {getSteps:true,preserveViewport:true});

    GEvent.addListener(directions, "load", function() {
      for (var i = 0; i < directions.getNumRoutes(); i++){
        // map.getPane(G_MAP_MARKER_PANE).style.visibility = "hidden";
        map.getPane(G_MAP_MARKER_SHADOW_PANE).style.visibility = "hidden";
        directions.getMarker(0).getIcon().image = "/images/map/marker-a-active.png";
        directions.getMarker(0).getIcon().iconSize = new google.maps.Size(24,31);
        directions.getMarker(1).getIcon().image = "/images/map/marker-b-active.png";
        directions.getMarker(1).getIcon().iconSize = new google.maps.Size(24,31);


        var route = directions.getRoute(i);

        // start point of the journey is: route.getStartGeocode().address
        // end point of the journey is: route.getEndGeocode().address

        // add distance and journey duration
        $('#info p.distance').html('<strong>'+route.getDistance().html+"</strong> (about <strong>"+route.getDuration().html+'</strong>)');
        // add the print button
        $('#info .content h1:first').after("<a onclick=\"window.print();\" href=\"#\"><img id=\"print_button\" alt=\"Print these directions\" src=\"/images/buttons/print_directions.png\"/></a>");

        // add the ordered list for the direction steps
        $('#map_directions').html('<ol></ol>');

        // interim steps
        for (var j = 0; j < route.getNumSteps(); j++){
          var  step = route.getStep(j);
          var lat_lng = step.getLatLng();
          if (j==0) {
            $('#map_directions ol').append('<li lat="'+lat_lng.lat()+'" lon="'+lat_lng.lng()+'" class="first" id="route_'+i+'_step_'+j+'"><span class="distance">'+step.getDistance().html+'</span><div class="description">'+step.getDescriptionHtml()+'</div></li>');
          }
          else  {
            $('#map_directions ol').append('<li lat="'+lat_lng.lat()+'" lon="'+lat_lng.lng()+'" id="route_'+i+'_step_'+j+'"><span class="distance">'+step.getDistance().html+'</span><div class="description">'+step.getDescriptionHtml()+'</div></li>');
          }
          boundaries.extend( new google.maps.LatLng( lat_lng.lat(),lat_lng.lng() ) );
        };
      };

      // ensure the whole route is shown on the map
      centro = boundaries.getCenter();
      zoomlevel = map.getBoundsZoomLevel( boundaries ) - 1;
      sw = boundaries.getSouthWest();
      ne = boundaries.getNorthEast();
      factor = (ne.lng() - sw.lng()) * (5/zoomlevel);
      recenter = new google.maps.LatLng( centro.lat(), centro.lng()-factor )
      map.setCenter( recenter , zoomlevel);

      // copyright message
      $('#info .content').append('<p>'+directions.getCopyrightsHtml()+'</p>');

      // make the li elements appear like links when users mouseover them
      $('#map_directions ol li').hover(
        function() {
          $(this).addClass('hover');
        },
        function() {
          $(this).removeClass('hover');
        }
      );

      // make the li elements appear like links when users mouseover them
      $('#info .endpoint').hover(
        function() {
          $(this).addClass('hover');
        },
        function() {
          $(this).removeClass('hover');
        }
      );

      // apply behaviour to the directions which shows a blown up bubble on the map
      $('#map_directions ol li').click(function(event) {
        if ($(event.target).attr("lat")) {
          map.showMapBlowup(new GLatLng($(event.target).attr("lat"), $(event.target).attr("lon")));
        }
        else if ($(event.target).parent().attr("lat")) {
          // required as the li can contain <b> <span> and <div> elements, which dont have lat/lon attributes
          map.showMapBlowup(new GLatLng($(event.target).parent().attr("lat"), $(event.target).parent().attr("lon")));
        }
        else if ($(event.target).parent().parent().attr("lat")){
          // required as the li can contain <b> <span> and <div> elements, which dont have lat/lon attributes
          map.showMapBlowup(new GLatLng($(event.target).parent().parent().attr("lat"), $(event.target).parent().parent().attr("lon")));
        }
        else {
          return false;
        }
        return false;
      });

      // apply behaviour to start div
      $('#journey_start').click(function(event) {
        if ($(event.target).html().length > 0 && $(event.target).html() != "your saved location") {
          map.showMapBlowup(route.getStep(0).getLatLng());
          return false;
        };
      });
      // apply behaviour to end div
      $('#journey_end').click(function(event) {
        map.showMapBlowup(route.getEndLatLng());
        return false;
      });

    });
  };

};

var Map_input = function(element) {
  var map = new google.maps.Map2(element);
  this.getMap = function() {
    return map;
  };
  this.centre = function(lat,lon) {
    map.setCenter(new google.maps.LatLng(lat,lon), 15);
  };
  this.addControls = function() {
    map.addControl(
      new google.maps.SmallMapControl(),
      new google.maps.ControlPosition(
        google.maps.ANCHOR_TOP_RIGHT,
        new google.maps.Size(5, 50)
      )
    );
  };

  this.addMarker = function(lat,lon,update_div) {
    var baseIcon = new GIcon();
    baseIcon.image = "/images/map/icon.png";
    baseIcon.iconSize = new GSize(65, 85);
    baseIcon.iconAnchor = new GPoint(32, 83);
    baseIcon.shadow = "/images/map/icon-shadow.png";
    baseIcon.shadowSize = new GSize(110, 81);
    var icon = new GIcon(baseIcon);
    var point = new GLatLng(lat,lon);
    var marker = new GMarker(point, { icon: icon, draggable: true });
    map.addOverlay(marker);

    GEvent.addListener(marker,"dragend",function() {
      if (document.getElementById( update_div )) {
        document.getElementById( update_div ).value = this.getPoint();
      }
    });
  };
  this.setZoom = function( level ){
     map.setZoom(level);
  };

};
