/** 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'); }
});


