//<![CDATA[

// main.js - renders a google map based on configuration in xml files
// Michael Patch 15-Jan-2009

//EDITABLE VARIABLES:
var xmlConfigFile = "/templates/maps/config.xml"; //Location of the main config.xml

//DO NOT EDIT BELOW THIS LINE
//Logical defaults for these variables are only set here in case they don't exist in xmlConfigFile
var baseiconImage = "/icons/info.png";
var baseiconShadow = "/icons/shadow.png";
var baseiconSize = "18, 28";
var baseiconShadowSize = "22, 20";
var baseiconAnchor = "6, 20";
var baseiconInfoWindowAnchor = "5, 1";
var bSetExtentsDynamic = true;
var mapHeight = 300;
var mapWidth = 400;
var mapCenterX = 45.433944;
var mapCenterY = -75.6774863516;
var mapZoomLevel = 11;
var mapDrivingDirections = false;
//marker directions
var idxMarkers = 0;
var gmarkers = [];
var htmls = [];
var to_htmls = [];
var from_htmls = [];
var dirTitle = "Directions:";
var dirToHere = "To Here";
var dirFromHere = "From here";
var dirStartAddress = "Start Address:";
var dirEndAddress = "End Address:";
var dirSubmit = "Get Directions";
//Language of the map
var lang = "en";

//Render the Map
buildMap();

//MAIN FUNCTION
function buildMap() {
  var request = GXmlHttp.create();
  request.open("GET", xmlConfigFile, true);
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      if (request.status != 200) {
        var httpErr = "Map Error: Configuration file " + xmlConfigFile + " could not be found or HTTP request error.";
        alert(httpErr);
        return;
      } else {
        callbackMainXML(request);
      }
    }
  }
  request.send(null);
  return;
}

//Parse Main XML Config File
function callbackMainXML(request) {
  var xmlDoc = request.responseXML;
  if (xmlDoc.hasChildNodes() == false) {
    var xmlErr = "Map Error: Configuration file " + xmlConfigFile + " is not well formed XML or contains no data.";
    alert(xmlErr);
    return;
  }
  else {
    //NON-REQUIRED FIELDS
    parseNonRequiredFields(xmlDoc);
    //REQUIRED FIELDS
    var callersLocation = window.location.toString();
    var myLocation = "";
    var xmlFile = "";
    //extract current html file path from window.location
    myLocation = parseUri(callersLocation).path; 
    //determine if this a french page from the html file path
    if (isFrench(myLocation)){
      lang = "fr";
      dirTitle = "Itin&eacute;raire :";
      dirToHere = "Vers ce lieu";
      dirFromHere = "&Agrave; partir de ce lieu";
      dirStartAddress = "Lieu de d&eacute;part";
      dirEndAddress = "Lieu d&apos;arriv&eacute;e";
      dirSubmit = "OK";
    } 
    var murls = xmlDoc.documentElement.getElementsByTagName("mapurl");
    //extract the location of the xml file for parent html file
    if (murls.length < 1) {
      var urlsErr = "Map Error: Configuration file " + xmlConfigFile + " does not contain any map locations.";
      alert(urlsErr);     
      return;
    } 
    else {
      for (var j = 0; j < murls.length; j++) {
        if (myLocation == murls[j].getAttribute("html")) {
           xmlFile = murls[j].getAttribute("xml");
        }
      }
    }
    if (xmlFile == "") {
      var nomatchErr = "Map Error: Configuration file " + xmlConfigFile + " does not contain an entry for the location of this map.";
      alert(nomatchErr);     
      return;
    }
    else {
      //Load Local XML file
      var request2 = GXmlHttp.create();
      request2.open("GET", xmlFile, true);
      request2.onreadystatechange = function() {
        if (request2.readyState == 4) {
          if (request2.status != 200) {
             var httpErr = "Map Error: Configuration file " + xmlFile + " could not be found or HTTP request error.";
             alert(httpErr);
             return;
          } else {
             callbackLocalXML(request2,xmlFile);
          }
        }
      }
      request2.send(null);
      return;      
    }
  }
}

//Parse Local XML Config File
function callbackLocalXML(request,xmlFile) {
  var xmlDoc = request.responseXML;
  if (xmlDoc.hasChildNodes() == false) {
    var xmlErr = "Map Error: Local Configuration file " + xmlFile + " is not well formed XML or contains no data.";
    alert(xmlErr);
    return;
  }
  else {
    //NON-REQUIRED FIELDS
    parseNonRequiredFields(xmlDoc);
    //REQUIRED FIELDS
    var markerArray = [];
    var markers = xmlDoc.documentElement.getElementsByTagName("marker");
    if (markers.length > 0) {
      markerArray.length = markers.length;
      for (var i = 0; i < markerArray.length; i++) {
        markerArray[i] = [4];  //Each row has 4 columns: lat, lng, label, html
      }
      for (var j = 0; j < markers.length; j++) {
        markerArray[j][0] = markers[j].getAttribute("lat");
        markerArray[j][1] = markers[j].getAttribute("lng");
        markerArray[j][2] = markers[j].getAttribute("label");
        markerArray[j][3] = markers[j].getAttribute("html");
      }
    } 
    //having collected all the parameters, render the Map
    renderMap(markerArray);
  }
}       

//Parses standard non-required fields from either XML file
function parseNonRequiredFields(xmlDoc) {
  //baseicon
  var bsicn = xmlDoc.documentElement.getElementsByTagName("baseicon");
  if (bsicn.length > 0) {
    if ((bsicn[0].getAttribute("image")) && (bsicn[0].getAttribute("image").trim() != "")) baseiconImage = bsicn[0].getAttribute("image");
    if ((bsicn[0].getAttribute("shadow")) && (bsicn[0].getAttribute("shadow").trim() != "")) baseiconShadow = bsicn[0].getAttribute("shadow");
    if ((bsicn[0].getAttribute("iconsize")) && (bsicn[0].getAttribute("iconsize").trim() != "")) baseiconSize = bsicn[0].getAttribute("iconsize");
    if ((bsicn[0].getAttribute("shadowsize")) && (bsicn[0].getAttribute("shadowsize").trim() != "")) baseiconShadowSize = bsicn[0].getAttribute("shadowsize");
    if ((bsicn[0].getAttribute("iconanchor")) && (bsicn[0].getAttribute("iconanchor").trim() != "")) baseiconAnchor = bsicn[0].getAttribute("iconanchor");
    if ((bsicn[0].getAttribute("infowindowanchor")) && (bsicn[0].getAttribute("infowindowanchor").trim() != "")) baseiconInfoWindowAnchor = bsicn[0].getAttribute("infowindowanchor");
  }
  //bbsetextentsdynamic
  if (xmlDoc.documentElement.getElementsByTagName("bsetextentsdynamic").length > 0) {
    var extents = xmlDoc.documentElement.getElementsByTagName("bsetextentsdynamic");
    var extentsText;
    //Internet Explorer
    if (extents[0].text != undefined) {
      if (extents[0].text.trim() != "") extentsText = extents[0].text.trim().toLowerCase();
    }
    //Standards Compliant Browsers
    else if (extents[0].textContent != undefined) {
      if (extents[0].textContent.trim() != "") extentsText = extents[0].textContent.trim().toLowerCase();
    }
    switch (extentsText) {
      case "true": bSetExtentsDynamic = true;
        break;
      case "false": bSetExtentsDynamic = false;
        break;
    }
  }
  //height
  if (xmlDoc.documentElement.getElementsByTagName("height").length > 0) {
    var ht = xmlDoc.documentElement.getElementsByTagName("height");
    var textHeight = "";
    if (ht[0].text != undefined) {
      if (ht[0].text.trim() != "") textHeight = ht[0].text.trim();
    } 
    else if (ht[0].textContent != undefined) {
      if (ht[0].textContent.trim() != "") textHeight = ht[0].textContent.trim();
    }
    if (textHeight != "") {
      intHeight = parseInt(textHeight);
      //validate conversion to int
      if (intHeight != textHeight) {
        alert('Map Height is not an integer');
      }
      else {
        //validate within range
        if (intHeight < 1) {
            alert('Map Height must be 1 or greater');
        }
        else {
            mapHeight = intHeight;
        }
      }
    }
  }
  //width
  if (xmlDoc.documentElement.getElementsByTagName("width").length > 0) {
    var wth = xmlDoc.documentElement.getElementsByTagName("width");
    var textWidth = "";
    if (wth[0].text != undefined) {
      if (wth[0].text.trim() != "") textWidth = wth[0].text.trim();
    } 
    else if (wth[0].textContent != undefined) {
      if (wth[0].textContent.trim() != "") textWidth = wth[0].textContent.trim();
    }
    if (textWidth != "") {
      intWidth = parseInt(textWidth);
      //validate conversion to int
      if (intWidth != textWidth) {
        alert('Map Width is not an integer');
      }
      else {
        //validate within range
        if (intWidth < 1) {
            alert('Map Width must be 1 or greater');
        }
        else {
            mapWidth = intWidth;
        }
      }
    }
  }
  //xcenter
  if (xmlDoc.documentElement.getElementsByTagName("xcenter").length > 0) {
    var xc = xmlDoc.documentElement.getElementsByTagName("xcenter");
    if (xc[0].text != undefined) {
      if (xc[0].text.trim() != "") mapCenterX = xc[0].text.trim();
    } 
    else if (xc[0].textContent != undefined) {
      if (xc[0].textContent.trim() != "") mapCenterX = xc[0].textContent.trim();
    }
  }
  //ycenter
  if (xmlDoc.documentElement.getElementsByTagName("ycenter").length > 0) {
    var yc = xmlDoc.documentElement.getElementsByTagName("ycenter");
    if (yc[0].text != undefined) {
      if (yc[0].text.trim() != "") mapCenterY = yc[0].text.trim();
    } 
    else if (yc[0].textContent != undefined) {
      if (yc[0].textContent.trim() != "") mapCenterY = yc[0].textContent.trim();
    }
  }
  //zoom
  if (xmlDoc.documentElement.getElementsByTagName("zoom").length > 0) {
    var zm = xmlDoc.documentElement.getElementsByTagName("zoom");
    if (zm[0].text != undefined) {
      if (zm[0].text.trim() != "") textZoomLevel = zm[0].text.trim();
    } 
    else if (zm[0].textContent != undefined) {
      if (zm[0].textContent.trim() != "") textZoomLevel = zm[0].textContent.trim();
    }
    if (textZoomLevel != "") {
      intZoomLevel = parseInt(textZoomLevel);
      //validate conversion to int
      if (intZoomLevel != textZoomLevel) {
        alert('Zoom level in not an integer');
      }
      else {
        //validate within range
        if ((intZoomLevel < 0) || (intZoomLevel > 17)) {
          alert('Valid Zoom Levels are between 0 and 17');
        }
        else {
          mapZoomLevel = intZoomLevel;
        }
      }
    }
  }
  //Directions
  if (xmlDoc.documentElement.getElementsByTagName("directions").length > 0) {
    var dirs = xmlDoc.documentElement.getElementsByTagName("directions");
    var dirsText;
    //Internet Explorer
    if (dirs[0].text != undefined) {
      if (dirs[0].text.trim() != "") dirsText = dirs[0].text.trim().toLowerCase();
    }
    //Standards Compliant Browsers
    else if (dirs[0].textContent != undefined) {
      if (dirs[0].textContent.trim() != "") dirsText = dirs[0].textContent.trim().toLowerCase();
    }
    switch (dirsText) {
      case "true": mapDrivingDirections = true;
        break;
      case "false": mapDrivingDirections = false;
        break;
    }
  }  
}

//Renders the Map based on xml config data
function renderMap(markers) {
  if (GBrowserIsCompatible()) {
    var map = new GMap2(document.getElementById("googlemap"),
                       { size: new GSize(mapWidth, mapHeight) } );
    var centerPoint = new GLatLng(mapCenterX, mapCenterY);
    var bounds = new GLatLngBounds();
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    if ( bSetExtentsDynamic ) map.setCenter(centerPoint, mapZoomLevel);
    //render the points  
    if (markers.length > 0) {
      for (var i = 0; i < markers.length; i++) {
        var lat   = markers[i][0];
        var lng   = markers[i][1];
        var label = markers[i][2];
        var html  = markers[i][3];        
        var point = new GLatLng(lat,lng);
	      bounds.extend(point);
        var marker = createMarker(point, label, html);
        map.addOverlay(marker);
      }  
    }  
  }
}


//Creates a single Marker with onclick pop-up html
function createMarker(point,name,html) {
  var marker = new GMarker(point,{title:name});
  html = "<h4>" + name + "</h4>" + html;

  if (mapDrivingDirections) {        
    to_htmls[idxMarkers] = html + '<br>' + dirTitle + ' <b>' + dirToHere + '</b> - <a href="javascript:fromhere(' + idxMarkers + ')">' + dirFromHere + '</a>' +
        '<form action="http://maps.google.ca/maps" method="get" style="margin:0;padding:0">' + dirStartAddress + '<br>' + 
        '<input type="hidden" name="hl" value="' + lang + '" />' +
        '<input type="text" size="20" maxlength="100" name="saddr" id="saddr" value="" />' +
        '<input value="' + dirSubmit + '" type="submit">' +
        '<input type="hidden" name="daddr" value="' + point.lat() + ',' + point.lng() + "(" + name + ")" + '"/>';
    from_htmls[idxMarkers] = html + '<br>' + dirTitle + ' <a href="javascript:tohere(' + idxMarkers + ')">' + dirToHere + '</a> - <b>' + dirFromHere + '</b>' +
        '<form action="http://maps.google.ca/maps" method="get" style="margin:0;padding:0">' + dirEndAddress + '<br>' +
        '<input type="hidden" name="hl" value="' + lang + '" />' +
        '<input type="text" size="20" maxlength="100" name="daddr" id="daddr" value="" />' +
        '<input value="' + dirSubmit + '" type="submit">' +
        '<input type="hidden" name="saddr" value="' + point.lat() + ',' + point.lng() + "(" + name + ")" + '"/>';
    html = html + '<br>' + dirTitle + ' <a href="javascript:tohere('+idxMarkers+')">' + dirToHere + '</a> - <a href="javascript:fromhere('+idxMarkers+')">' + dirFromHere + '</a>';
  }
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(html);
  });
  if (mapDrivingDirections) {        
    gmarkers[idxMarkers] = marker;
    htmls[idxMarkers] = html;
    idxMarkers++;
  }
  return marker;
}

// functions that open the directions forms
function tohere(idxMarkers) {
  gmarkers[idxMarkers].openInfoWindowHtml(to_htmls[idxMarkers]);
}
  
function fromhere(idxMarkers) {
  gmarkers[idxMarkers].openInfoWindowHtml(from_htmls[idxMarkers]);
}

// Determine if french page request from "_fr." in path
function isFrench(path){
  var frenchMatch = new RegExp("_fr\.","i").test(path);
	return frenchMatch;
}

// parseUri JS v0.1.1, by Steven Levithan <http://stevenlevithan.com>
function parseUri(sourceUri){
	var uriPartNames = ["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"],
		uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri),
		uri = {};
	for(var i = 0; i < 10; i++){
		uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
	}
	/* Always end directoryPath with a trailing backslash if a path was present in the source URI
	Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key */
	if(uri.directoryPath.length > 0){
		uri.directoryPath = uri.directoryPath.replace(/\/?$/, "/");
	}
	return uri;
}

//Trim by Douglas Crockford <http://javascript.crockford.com>
String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, "");
}


//]]>

