/**
  * This script is free, created by Rigas Parathyras @ http://www.rigasp.com
 * You can use the script but please keep the credentials.
 * 
 * This script reads an xml file with the map data and displays them.
 * It uses AJAX to load the xml file with the appropriate information. 
 * More info can be found at the above website 
 */

// Global variables
var map;
var markers = []; // An array of markers with same index as the points
var infoWindows = []; // Array with same index as the markers
var icons = [];
var markerManager;
var file;
var debug = false;

/** EXTERNAL function 
 Used to load the map - This is the main external function of the file
 The filename or url should be the path of the xml file residing on the current server */
function load(fileName) {
  //alert('Loading ' + fileName);
  if (GBrowserIsCompatible()) {
   file = fileName
   if (xmlDocMap.get(file) && xmlDocMap.get(file) != null) {
     xmlDoc = xmlDocMap.get(file);
	 loadMap();
   } else {
     loadXml();
   }
  }
}

/** EXTERNAL function 
  Can be used externally to display a marker for a specific id */
function displayMarker(markerId) {
  markers[markerId].openInfoWindow(infoWindows[markerId]);
}

/**
  * Initializes some components in the page that contains the map */
function initComponents() {
  // Initializes a label under the map so that it displays the GPS coordinates of the place clicked on the map
  var msg;
  var gpsLabel = document.getElementById("gpslabel");
  if (gpsLabel) {
    GEvent.addListener(map, "mouseover", function(overlay, point) {
      if (point) {
        msg = "lat=\"" + point.y + "\" lng=\"" + point.x + "\"";
        gpsLabel.innerHTML = msg;
      }
    });
  }
  var descriptionLabel = document.getElementById("descriptionlabel");
  if (descriptionLabel) {
    msg = getChildValue(getRootElement(), 'description');
    if (msg) {
	  descriptionLabel.style.display = "block";
	  descriptionLabel.innerHTML = msg;
	} else {
	  descriptionLabel.innerHTML = '';
	  descriptionLabel.style.display = "none";
	} 
  }
  var detailsLabel = document.getElementById("detailslabel");
  if (detailsLabel) {
    msg = getChildValue(getRootElement(), 'details');
    if (msg) {
	  detailsLabel.style.display = "block";
	  detailsLabel.innerHTML = msg;
	} else {
	  detailsLabel.innerHTML = '';
	  detailsLabel.style.display = "none";
	} 
  }
}

// ------------------------------------------ Data ----------------------------------------

var xmlDoc;
var xmlDocMap = {
	set : function(xmlUrl,anXmlDoc) {this[xmlUrl] = anXmlDoc;},
	get : function(xmlUrl) {return this[xmlUrl];}
}

/* Does an AJAX call to load the xml document. */
var req;
function loadXml() {
  req = GXmlHttp.create();
  req.onreadystatechange=postLoadXml;
  req.open("GET", file, true);
  req.send("");
}

/* Callback function after the xml has been loaded. */
function postLoadXml() {
  if (req.readyState==4 || req.readyState=="complete") {
    xmlDoc = GXml.parse(req.responseText);
	xmlDocMap.set(file, xmlDoc);
	loadMap();
    return true;
  } else {
    return false;
  }
}

var initialZoom;

function loadMap() {
  map = new GMap2(document.getElementById("map"));
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  var mapCenterLat = parseFloat(getRootElement().getAttribute("lat"));
  var mapCenterLng = parseFloat(getRootElement().getAttribute("lng"));
  initialZoom = parseFloat(getRootElement().getAttribute("zoom"));
  map.setCenter(new GLatLng(mapCenterLat, mapCenterLng), initialZoom);
  markerManager = new GMarkerManager(map)
  loadIcons();
  loadPolyLines();
  loadMarkers();
  initComponents();
  loadKml();
}

function getRootElement() {
  if (xmlDoc == null) { 
    alert('Error initializing data!');	
  } 
  return xmlDoc.getElementsByTagName('map')[0];
}

/** 
  * Finds the first child with the given name under the given element
  * and returns its value 
  */
function getChildValue(element, childElementName) {
  var value = element.getElementsByTagName(childElementName)[0];
  return getNodeValue(value);
}

function getNodeValue(node) {
  if (node) { // if has child
    node = node.childNodes[0];
    if (node) { // if the child is not blank
      return node.nodeValue;
    }
  }
  return null;
}

function loadPolyLines() {
  var lines = getRootElement().getElementsByTagName("line");
  // read each line
  for (var a = 0; a < lines.length; a++) {
    // get any line attributes
    var colour = lines[a].getAttribute("colour");
    var width  = parseFloat(lines[a].getAttribute("width"));	
    // read each point on that line
    var points = lines[a].getElementsByTagName("point");
    var pts = [];
    for (var i = 0; i < points.length; i++) {
      pts[i] = new GLatLng(parseFloat(points[i].getAttribute("lat")),
        parseFloat(points[i].getAttribute("lng")));
    }
    map.addOverlay(new GPolyline(pts,colour,width));
  }
}

function loadKml() {
  var kmlData = getRootElement().getElementsByTagName("kml");
  for (var a = 0; a < kmlData.length; a++) {
    kml = getNodeValue(kmlData[a]);
    map.addOverlay(new GGeoXml(kml));
  }
}

function loadMarker(point) {
  var data = new Object();
  data.description = getChildValue(point, "description");
  data.details = getChildValue(point, "details");
  data.title = getChildValue(point, "title");
  data.icon = icons[getChildValue(point, "icon")];
  data.maxZoom = getChildValue(point, "maxZoom");
  data.minZoom = getChildValue(point, "minZoom");
  data.id = point.getAttribute("id");
  data.lat = point.getAttribute("lat");
  data.lng = point.getAttribute("lng");
  data.displayInfoWindow = point.getAttribute("displayInfoWindow");
  createMarker(data);
}

function loadMarkers() {
  var mapPointsElement = getRootElement().getElementsByTagName('mappoints')[0];
  if (mapPointsElement) {
    var locationsSize = mapPointsElement.getElementsByTagName('point').length;
    for (var i = 0; i < locationsSize ; i++) {
      var point = mapPointsElement.getElementsByTagName('point')[i];
      loadMarker(point);
    }
  }	
}

function createMarker(data) {
	var gMarkerOptions = new Object();
	if (data.title && data.title != null && data.title != undefined) {
	   gMarkerOptions.title = data.title;
	} else if (data.description && data.description != null && data.description != undefined) {
	   gMarkerOptions.title = data.description;
	} 
    if (data.icon && data.icon != null && data.icon != undefined) {
      gMarkerOptions.icon = data.icon
    }
	var marker = new GMarker(new GLatLng(data.lat, data.lng), gMarkerOptions);
    var minZoom;
    if (data.minZoom) {
	  minZoom = data.minZoom;
    } else {
	  minZoom = initialZoom;
	}
    if (data.maxZoom) {
      markerManager.addMarker(marker, parseInt(minZoom), parseInt(data.maxZoom));
    } else {
      markerManager.addMarker(marker, parseInt(minZoom));
    }
	var html = getHtmlInfoWindow(data.title, data.description, data.details);
	if (data.displayInfoWindow == 'true') {
	  marker.openInfoWindowHtml(html);
	}
	if (data.title != null || data.description != null || data.details != null) {
   	  GEvent.addListener(marker, "mouseover", function() {
	    marker.openInfoWindowHtml(html);
      });
    }
	infoWindows[data.id] = html;
	markers[data.id] = marker;
}

function getHtmlInfoWindow(title, description, details) {
  var result = '<p>';
  if (title && title != '') {
    result += "<b>" + title + "</b>";
  } 
  if (description && description != '') {
    if (result != '<p>') {
	  result += '<br>';
	}
    result += description;
  }
  if (details && details != '') {
    if (result != '<p>') {
	  result += '<br>';
	}
    result += "<i>" + details + "</i>"
  }
  result += '</p>';
  return result;
}

function loadIcons() {
  var iconsElement = xmlDoc.getElementsByTagName('icons')[0];
  if (iconsElement) {
   var iconsSize = iconsElement.getElementsByTagName('icon').length;
   for (var i = 0; i < iconsSize ; i++) {
    var iconElement = iconsElement.getElementsByTagName('icon')[i];
    var iconId = iconElement.getAttribute("id");
    icons[iconId] = new GIcon();
    var image = iconElement.getAttribute("image");
    icons[iconId].image = image;
    
    var iconSizeElement = iconElement.getElementsByTagName('iconSize')[0];
    var iconSizeWidth = iconSizeElement.getAttribute("width");
    var iconSizeHeight = iconSizeElement.getAttribute("height");
    icons[iconId].iconSize = new GSize(parseInt(iconSizeWidth), parseInt(iconSizeHeight));
    
    var shadowSizeElement = iconElement.getElementsByTagName('shadowSize')[0];
    var shadowSizeWidth = shadowSizeElement.getAttribute("width");
    var shadowSizeHeight = shadowSizeElement.getAttribute("height");
    icons[iconId].shadowSize = new GSize(parseInt(shadowSizeWidth), parseInt(shadowSizeHeight));
    
    var iconAnchorElement = iconElement.getElementsByTagName('iconAnchor')[0];
    var iconAnchorWidth = iconAnchorElement.getAttribute("width");
    var iconAnchorHeight = iconAnchorElement.getAttribute("height");
    icons[iconId].iconAnchor = new GPoint(parseInt(iconAnchorWidth), parseInt(iconAnchorHeight));
    
    var infoWindowAnchorElement = iconElement.getElementsByTagName('infoWindowAnchor')[0];
    var infoWindowAnchorWidth = infoWindowAnchorElement.getAttribute("width");
    var infoWindowAnchorHeight = infoWindowAnchorElement.getAttribute("height");
    icons[iconId].infoWindowAnchor = new GPoint(parseInt(infoWindowAnchorWidth), parseInt(infoWindowAnchorHeight));
   }
  }
}

