/** 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/                           **/

// Usage:
// var plotter = new GPlotter();
// plotter.setColor(plotter.BLUE);
// plotter.setIconUrl("http://gplotter.offwhite.net/maps/icons/");
// plotter.plot("map", "labels", "milwaukee.xml");

var GPlotter = Class.create();

Object.extend(GPlotter.prototype, {
  initialize: function() {
    // Variables
    this.VERSION = '0.9.0';
    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.RED = "r";
    this.GREEN = "g";
    this.BLUE = "b";
    this.color = this.GREEN;
    this.maps = new Array();
  },
  // Functions
  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);
    }
  },
  setIconUrl: function(url) {
    this.iconUrl = url;
  },
  plot: function(mapId, labelsId, feedName) {
    if (!this.initialized) {
      var plotter = this;
      this.labels = $(labelsId);
      var mapElem = $(mapId);
      if (mapElem) {
        var map;

        if (this.maps[mapId] && this.maps[mapId].setCenter) {
          map = this.maps[mapId];
        }
        else {
          map = new GMap2(mapElem);
          map.addControl(new GSmallMapControl());
          map.addControl(new GMapTypeControl());
          this.maps[mapId] = map;
        }

        var params = {
          map : map,
          mapID : mapId,
          labelsID : labelsId
        }

        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(feedName, opt);

        this.initialized = true;
      }
    }
  },
  handleResponse: function(p, t) {
    this.runPlotter(p.map, t.responseXML);
  },
  runPlotter: function(map, xmlDoc)
  {
    this.mapDocument = xmlDoc;
    var root = xmlDoc.getElementsByTagName("locations")[0];
    var version = root.getAttribute("version");
    if (version == "0.9") {
      this.runPlotter09(map, xmlDoc);
    }
    else {
      alert("Locations version not supported");
    }
  },
  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 = parseInt(root.getAttribute("zoomlevel"));
    var centerPoint = new GLatLng(cLat, cLong);
    map.setCenter(centerPoint, zoomLevel);

    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 + "<br />";
      var address = "";
      if (street != "") { address += street; }
      if (suite) { address += "<br />" + suite; }
      if (city) { address += "<br />" + city; }
      if (state) { address += ", " + state; }
      if (zip) { address += " " + zip; }
      address += "<br />";
      if (phone) { address += phone + "<br />"; }
      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;
    }
  },
  createMarker09: function(label, longitude, latitude, icon, address)
  {
    var point = new GLatLng(latitude, longitude);
    var marker = new GMarker(point, icon);
    var text = "<b>" + label + "</b>";
    if (address != "") { text += "<br />" + address; }
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml(text);
    });
    this.markers[this.markers.length] = marker;
    return marker;
  },
  getTagNodeValue: function(node, tagName)
  {
      var value = "";
      var tag = node.getElementsByTagName(tagName)[0];
      if (tag && tag.firstChild) {
        value = tag.firstChild.nodeValue;
      }
      return value;
  },
  enableDebug: function() { alert('Function not supported: enableDebug'); }
});

