// Pavel Janda's mapping system
// (c) 2007 Pavel Janda http://www.jandic.com/
// Email: pavel.janda@jandic.com
// http://www.jandic.com/maps/    


// 31 Cameron Square, Kilmainham, Dublin 8
var originLat = 53.34022644920856;
var originLng = -6.300508975982666;
var originZoom = 10;    
var defaultIconId = "red-pushpin";

var theMap = null; // map object (class MyMap)

// class MyMap
function MyMap() {
  // object with data from database
  this.storage = new Storage();
  // Google Maps object
	this.map;
	// Marker Manager object
	this.mrkMgr;
	
	theMap = this;

  // loads maps API
  if (maps_lang == "en") {
    google.load("maps", "2", {locale: "en_UK"}); //!!! 
  } else {
    google.load("maps", "2"); //!!!
  }
  google.setOnLoadCallback(this.loadIcons); 
};

/**
 * Loads marker icon library.
 */ 
MyMap.method('loadIcons', function () {
  google.maps.DownloadUrl("geticons.php", function (data) {
    theMap.storage.initializeIcons(data);
    theMap.loadMapsData();
  });
});

/** 
 * Loads mapping data from database.
 */ 
MyMap.method('loadMapsData', function () {
  google.maps.DownloadUrl("getdata.php?target=A", function (data) {
    theMap.storage.addMapsData(data);

    theMap.create();
    theMap.addMapsData();
    theMap.initialize();
    theMap.afterInit();
  });
});

/**
 * Creates Google Maps objects and initialises it.
 */ 
MyMap.method('create', function () {
  if (google.maps.BrowserIsCompatible()) {
    this.map = new google.maps.Map2(document.getElementById("map"));

    this.map.addMapType(G_PHYSICAL_MAP); 
    this.map.addControl(new google.maps.LargeMapControl());
    this.map.addControl(new google.maps.ScaleControl(), new google.maps.ControlPosition(G_ANCHOR_BOTTOM_LEFT, new google.maps.Size(0,32)));     
    this.map.addControl(new google.maps.HierarchicalMapTypeControl()); 
    this.map.addControl(new google.maps.OverviewMapControl());
    this.map.setCenter(new google.maps.LatLng(originLat, originLng), originZoom);  // set origin
    this.map.enableScrollWheelZoom();
    this.map.enableDoubleClickZoom();
    this.map.enableContinuousZoom();
    this.map.enableGoogleBar();  

    //!!! google.maps.KeyboardHandler(this.map);    
    
    // register onClick handler 
    google.maps.Event.bind(this.map, 'click', this, this.onClick);
  } else {
    alert("Sorry, the Google Maps API is not compatible with this browser");
  }
});

/**
 * It is called after all initialization has been finished.
 */ 
MyMap.method('afterInit', function () {
  // abstract
});

/**
 * Nofifies the Map object about resizing of its container.
 */ 
MyMap.method('checkResize', function() {
  if (this.map != null)
    this.map.checkResize();
});

/**
 * Shows a popup window with detailed information about marker.
 */     
MyMap.method('onClick', function(overlay, point) {
  if (overlay) {
    // marker
    if (overlay.id_mrk) {
      overlay.openInfoWindowHtml("<div id='popup-win'>" + overlay.description + "</div>");
    }
  } 
});

/**
 * Creates a Google marker.
 */ 
MyMap.method('createMarker', function (marker, useDefaultIcon) {
  var text="<div class='msinfotitle'>" + marker.translatedTitle + "</div>" + 
    "<div class='msfeatureupdater'>" + marker.translatedDate + "</div>" +
    "<div class='msdescription'>" + marker.translatedDescription + "</div>";
    
  var iconId = null;
  if (useDefaultIcon) {
    iconId = defaultIconId;
  } else {
    iconId = marker.id_icn;
  }
  var gicon = this.storage.getGIcon(iconId);
  var gmarker = new google.maps.Marker(new google.maps.LatLng(marker.lat, marker.lng), {title: marker.translatedTitle, draggable: true, icon: gicon });
  gmarker.disableDragging();
  gmarker.id_mrk = marker.id_mrk;
  gmarker.description = text;
  marker.gmarker = gmarker;
  
  return gmarker;
});

/**
 * Creates an array with Google markers.
 */
MyMap.method('createMarkers', function (min_zoom) {
  var markers = [];

  for(var i = 0; i < this.storage.markers.length; i++) {
    if (min_zoom == this.storage.markers[i].min_zoom) {
      if (this.storage.markers[i].type == "M") {
        markers.push(this.createMarker(this.storage.markers[i], false));      
      }
    }
  }
  
  return markers;
});

/**
 * Creates a Google polyline.
 */ 
MyMap.method('createPolyline', function (route) {
  var text="<div class='msinfotitle'>" + route.translatedTitle + "</div>" + 
    "<div class='msfeatureupdater'>" + route.translatedDate + "</div>" +
    "<div class='msdescription'>" + route.translatedDescription + "</div>";
    
  var gpolyline = new google.maps.Polyline.fromEncoded({    
    color: "#" + route.color,    
    weight: route.weight,    
    opacity: route.opacity,
    points: route.points,    
    levels: route.levels,    
    zoomFactor: route.zoom_factor,    
    numLevels: route.num_levels});

  gpolyline.id_rts = route.id_rts;
  gpolyline.description = text;
  // register onClick handler 
  google.maps.Event.addListener(gpolyline, 'click', function(latlng) {
    theMap.map.openInfoWindowHtml(latlng, "<div id='popup-win'>" + text + "</div>");
  });

  route.gpolyline = gpolyline;
  
  return gpolyline;
});

/**
 * Creates an array with Google markers.
 */
MyMap.method('createAndAddPolylines', function () {
  for (var i = 0; i < this.storage.routes.length; i++) {
    this.map.addOverlay(this.createPolyline(this.storage.routes[i]));      
  }
});

/**
 * Adds mapping data from Storage structure to the map.
 */ 
MyMap.method('addMapsData', function () {
  this.mrkMgr = new google.maps.MarkerManager(this.map, {trackMarkers:true});
  for (var zoom = 0; zoom < 16; zoom++) {
    this.mrkMgr.addMarkers(this.createMarkers(zoom), zoom);
  }
  this.mrkMgr.refresh();
  
  // creates all polylines
  this.createAndAddPolylines();  
});

/**
 * Center map to given marker and zooms to default zoom level if specified.
 */ 
MyMap.method('zoomToMarker', function (id_mrk, applyZoom) {
  var marker = this.storage.getMarker(id_mrk);
  if (marker) {
    if (marker.zoom == -1 || !applyZoom) {
      this.map.setCenter(new google.maps.LatLng(marker.lat, marker.lng));
    } else {
      this.map.setCenter(new google.maps.LatLng(marker.lat, marker.lng), Number(marker.zoom));
    }        
  }
});

/**
 * Center map to given polyline and zooms to it if required.
 */ 
MyMap.method('zoomToPolyline', function (id_rts, applyZoom) {
  var route = this.storage.getRoute(id_rts);
  if (route) {
    var bounds = route.gpolyline.getBounds();
    var center = bounds.getCenter(); 
    var newZoom = this.map.getBoundsZoomLevel(bounds); 
    if (applyZoom && this.map.getZoom() != newZoom) { 
      this.map.setCenter(center, newZoom);
    } else {
      this.map.setCenter(center);
    } 
  }
});

/**
 * Returns the default marker Icon object.
 */ 
MyMap.method('getDefaultMarkerIcon', function () {
  return this.storage.getIcon(defaultIconId);
});

