/** GPlotter - Plotter interface for use with Google Maps - offwhite@gmail.com - 2005-07-24        **
 ** Code licensed under Creative Commons Attribution-ShareAlike License      **
 ** http://creativecommons.org/licenses/by-sa/2.0/                           **/
function GPlotter() {

  this.VERSION = "0.70";
  this.initialized = false;
  this.mapDocument = "";
  this.maxIconNumber = 25;
  this.baseIcon = new GIcon();
  this.markers = new Array();
  this.baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
  this.baseIcon.iconSize = new GSize(20, 34);
  this.baseIcon.shadowSize = new GSize(37, 34);
  this.baseIcon.iconAnchor = new GPoint(9, 34);
  this.baseIcon.infoWindowAnchor = new GPoint(9, 2);
  this.baseIcon.infoShadowAnchor = new GPoint(18, 25);
  this.iconUrl = "/maps/icons/";

  this.maps = new Array();

  this.RED = "r";
  this.GREEN = "g";
  this.BLUE = "b";
  this.color = this.GREEN;

  this.DEBUG = false;

  this.runPlotter = function(map, xmlDoc)
  {
    this.mapDocument = xmlDoc;
    var root = xmlDoc.getElementsByTagName("locations")[0];
    version = root.getAttribute("version");
    if (version == "0.9") {
      this.runPlotter09(map, xmlDoc);
    }
    else {
      alert("Locations version not supported");
    }
  }

  this.enableDebug = function()
  {
    this.DEBUG = true;
  }

  this.setIconUrl = function(url)
  {
    this.iconUrl = url;
  }

  this.setColor = function(c)
  {
    if (c == this.RED) {
      this.color = this.RED;
    }
    else if (c == this.GREEN) {
      this.color = this.GREEN;
    }
    else if (c == this.BLUE) {
      this.color = this.BLUE;
    }
    else {
      alert("Color not supported: " + c);
    }
  }

  this.runPlotter09 = function(map, xmlDoc)
  {
    var innerHTML = "";
    var cLat, cLong, zoomLevel;
    var root = xmlDoc.getElementsByTagName("locations")[0];
    cLat = root.getAttribute("latitude");
    cLong = root.getAttribute("longitude");
    zoomLevel = root.getAttribute("zoomlevel");
    var centerPoint = new GPoint(cLong, cLat);
    map.centerAndZoom(centerPoint, 16);

    var locations = xmlDoc.getElementsByTagName("location");
    for (var i=0;i<locations.length;i++) {
      var node = locations[i];
      var label = node.getAttribute("label");
      var latitude = node.getAttribute("latitude");
      var longitude = node.getAttribute("longitude");
      var street = this.getTagNodeValue(node, "street");
      var suite = this.getTagNodeValue(node, "suite");
      var city = this.getTagNodeValue(node, "city");
      var state = this.getTagNodeValue(node, "state");
      var phone = this.getTagNodeValue(node, "phone");
      var zip = this.getTagNodeValue(node, "zip");

      var number = i + 1
      innerHTML = innerHTML + number + ". " + label + "";
      var address = "";
      if (street != "") { address += street; }
      if (suite) { address += "" + suite; }
      if (city) { address += "<br />" + city; }
      if (state) { address += ", " + state; }
      if (zip) { address += " " + zip; }
      address += "";
      innerHTML += address + "<br />";

      var icon = new GIcon(this.baseIcon);
      if (number <= this.maxIconNumber) {
        icon.image = this.iconUrl + "icon" + this.color + number + ".png";
      }
      else {
        icon.image = this.iconUrl + "icon" + this.color + ".png";
      }
      var marker = this.createMarker09(label, longitude, latitude, icon, address);
      map.addOverlay(marker);
    }

    if (this.labels) {
      this.labels.innerHTML = innerHTML;
    }
  }

  this.createMarker09 = function(label, longitude, latitude, icon, address)
  {
    var point = new GPoint(longitude, latitude);
    var marker = new GMarker(point, icon);
    var text = "<b>" + label + "</b>";
    if (address != "") { text += "" + address; }
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml(text);
    });
    this.markers[this.markers.length] = marker;
    return marker;
  }

  this.getTagNodeValue = function(node, tagName)
  {
      var value = "";
      var tag = node.getElementsByTagName(tagName)[0];
      if (tag && tag.firstChild) {
        value = tag.firstChild.nodeValue;
      }
      return value;
  }

  // clear the markers off this map
  this.clear = function(mapDivId, labelsDivId)
  {
    alert("Not supported yet!");
  }

  this.handleResponse = function(p, t) {
    //alert('mapID = ' + p.mapID);
    this.runPlotter(p.map, t.responseXML);
  }

  this.plot = function(mapDivId, labelsDivId, url)
  {
    if (!this.initialized) {
      var plotter = this;
      this.labels = document.getElementById(labelsDivId);
      if (this.DEBUG && ! this.labels) { alert("Labels element not found!"); return; }
      var mapElem = document.getElementById(mapDivId);
      if (this.DEBUG && !mapElem) { alert("Map element not found!"); return; }
      if (mapElem) {
        var map;

        if (this.maps[mapDivId] && this.maps[mapDivId].centerAndZoom) {
          map = this.maps[mapDivId];
        }
        else {
          map = new GMap(mapElem);
          map.addControl(new GLargeMapControl());
          map.addControl(new GMapTypeControl());
          this.maps[mapDivId] = map;
        }

        var params = {
          map : map,
          mapID : mapDivId,
          labelsID : labelsDivId
        }

        this.successHandler = this.handleResponse.bind(this, params);

        var opt = {
          asynchronous:true,
          // Use POST
          method: 'get',
          // Handle successful response
          onSuccess: this.successHandler,
          // Handle 500
          on500: function(t) {
              alert('Error 500: location "' + t.statusText + '" was not found.');
          },
          // Handle 404
          on404: function(t) {
              alert('Error 404: location "' + t.statusText + '" was not found.');
          },
          // Handle other errors
          onFailure: function(t) {
              alert('Error ' + t.status + ' -- ' + t.statusText);
          }
        }

        new Ajax.Request(url, opt);

        this.initialized = true;
      }
    }
  }
}

