LHS.MapESRI = Class.create();
LHS.MapESRI.prototype = Object.extend(new LHS.Map(), {
	initialize: function (id, options) {
		this.id = id;
		this.scrollStart = null;
		// used to extend this.options, but didnt work properly
		this.options = Object.extend({}, options);
		this.holder = $('map-' + id.substringAfter('-')) || document.body;
		this.maps = $H({});
		this.layers = [];
		this.userShapes = [];
		this.zoomLevel = null;
		dojo.require("esri.map");
		dojo.require("esri.tasks.query");
		dojo.require("esri.toolbars.draw");
		this.createMap();
		this.setupFeatureCreation();
		this.setupAreaSearch();
		this.setupLayerToggles();
		this.type = 'ESRI';
	},
	/**
	 * Function to turn the object tag into a map using the options that have
	 * been set
	 */
	createMap: function () {
		this.map = null;
		this.map = new esri.Map(this.id);

		if ($T.isString(this.options.mapURL)) {
			this.options.mapURL = [this.options.mapURL];
		}

		// loop around map URLs
		var getVisibleLayers = function (layer) {
			layer.visibleLayers = [];
			if (this.options.layer) {
				layer.visibleLayers = this.options.layer.split(',');
				this.maps[layer.url].setVisibleLayers(layer.visibleLayers);
			} else {
				for ( var y = 0, len = layer.layerInfos.length; y < len; y++) {
					layer.visibleLayers.push(layer.layerInfos[y].id);
				}
			}
		}.bind(this);

		for ( var i = 0, len = this.options.mapURL.length; i < len; i++) {
			var url = this.options.mapURL[i];
			this.maps[url] = new esri.layers.ArcGISDynamicMapServiceLayer(url);
			if (i === 0) {
				this.defaultLayer = this.maps[url];
			} else {
				this.maps[url].setOpacity(0.5);
			}
			this.map.addLayer(this.maps[url]);
			dojo.connect(this.maps[url], "onLoad", getVisibleLayers);
		}

		this.options.extent = this.map.extent;

		function initMap () {
			// load the KML and RSS feeds
			this.options.zoomToLayer = this.options.zoomToLayer ? true : false;
			if (this.options.geoKML) {
				this.options.geoKML.each(function (kml) {
					this.loadKML(kml, null, this.options.zoomToLayer);
				}.bind(this));
			}
			if (this.options.geoRSS) {
				this.options.geoRSS.each(function (rss) {
					this.loadRSS(rss, null, this.options.zoomToLayer);
				}.bind(this));
			}
			if (this.options.xmin && this.options.ymin && this.options.xmax && this.options.ymax) {
				this.changeExtent();
			}

			this.addMapForm();

			var urls = [];
			this.maps.each(function (pair) {
				var url = pair.key;
				pair.value.layerInfos.each(function (layer) {
					urls.push(url + '/' + layer.id);
				});
			});
			$(this.id).style.backgroundImage = '';

			if (this.controls.btnGroup) {
				this.controls.btnGroup.hide();
				this.togglePopup(true, 'startMsg');
			}
			this.options.extent = this.map.extent;
			var breadcrumb = $$('div.breadcrumb')[0];
			if (breadcrumb) {
				breadcrumb.scrollTo();
			}
		}
		// map onload function
		dojo.connect(this.map, "onLoad", initMap.bind(this));
	},
	changeExtent: function () {
		this.options.extent = new esri.geometry.Extent(Number(this.options.xmin), Number(this.options.ymin), Number(this.options.xmax), Number(this.options.ymax), this.map.spatialReference);
		this.map.setExtent(this.options.extent);
	},
	querySearch: function (event, url, sValue) {
		var queryTask = new esri.tasks.QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0");
		var query = new esri.tasks.Query();
		sValue = sValue.value;
		query.returnGeometry = true;
		query.outFields = ["CITY_NAME"];
		query.where = "CITY_NAME like '" + sValue + "'";
		queryTask.execute(query, function (fset) {
			fset.features.each(function (f, i) {
				this.map.centerAt(f.geometry);
			}.bind(this));
		}.bind(this));

		Event.element(event).blur();
		Event.stop(event);
	},
	deleteLastLayer: function () {

	},
	setLayers: function (mapURL, layers) {
		this.maps[mapURL].setVisibleLayers(layers);
	},
	/**
	 * Function to position the popup over the map
	 * 
	 * @param {String}
	 *            type - The type of popup to position
	 */
	positionPopup: function (type) {
		// check popup exists
		if (this.controls.pointPopup) {
			var leftPosition = $(this.id).getWidth() / 2;
			var topPosition = $(this.id).getHeight() / 2;

			// according to type position it in middle of map
			if (type === 'startMsg') {
				leftPosition = (leftPosition + 242) - 333;
				topPosition = (topPosition + $$('div.header')[0].getHeight()) - 155;
				this.controls.pointPopup.setStyle({
					position: 'absolute',
					top: topPosition + 'px',
					left: leftPosition + 'px',
					width: '666px'
				});
			} else {
				leftPosition = (leftPosition + 242) - 170;
				topPosition = (topPosition + $$('div.header')[0].getHeight()) - this.controls.pointPopup.getHeight() / 2;
				this.controls.pointPopup.setStyle({
					position: 'absolute',
					top: topPosition + 'px',
					left: leftPosition + 'px',
					width: '340px'
				});
			}
		}
	},
	/**
	 * Function to add a form to the map that will be populated on the
	 * panning/zooming of map.
	 */
	addMapForm: function () {
		// check map exists
		if (this.options.form && $(this.options.form)) {
			this.options.form = $(this.options.form);

			var change = function (event) {

				// populate form width data
				this.options.form.populate({
					'param:xmin': this.map.extent.xmin,
					'param:xmax': this.map.extent.xmax,
					'param:ymin': this.map.extent.ymin,
					'param:ymax': this.map.extent.ymax,
					'param:spatialReference': this.map.spatialReference.wkid,
					'map:xmin': this.map.extent.xmin,
					'map:xmax': this.map.extent.xmax,
					'map:ymin': this.map.extent.ymin,
					'map:ymax': this.map.extent.ymax,
					'map:spatialReference': this.map.spatialReference.wkid
				});
			}.bind(this);
			change();
			dojo.connect(this.map, 'onExtentChange', change);
		}
	},
	addMap: function () {

	},
	findAddress: function (event, where) {
		var findObj = where.innerHTML.evalJSON();
		if (findObj.candidates[0]) {
			if (findObj.candidates[0].location) {
				var minY, minX, maxY, maxX, x, y, ext;
				x = parseFloat(findObj.candidates[0].location.x);
				y = parseFloat(findObj.candidates[0].location.y);
				minX = x - 500;
				minY = y - 500;
				maxX = x + 500;
				maxY = y + 500;
				ext = new esri.geometry.Extent(minX, minY, maxX, maxY, this.map.spatialReference);
				// this.map.centerAt(new esri.geometry.Point(,
				// findObj.candidates[0].location.y));
				this.map.setExtent(ext);
			}
		} else {
			this.togglePopup(true, 'findMsg');
			this.positionPopup('findMsg');
		}
	},
	/**
	 * Resets the map to its original view
	 */
	resetView: function (event, element) {
		this.map.setExtent(this.options.extent);
	},
	mapResize: function (width, height) {

	},
	/**
	 * @param {String}
	 *            url - The url of the KML feed
	 * @param {Function}
	 *            callback - A function to be run when the KML is loaded
	 * @param {Boolean|Integer}
	 *            zoomTo - If true then the Map should move to the best view for
	 *            the new Layer - If an Integer then zoom to that idexed shape
	 * @return {VEShapeLayer} - the new layer
	 */
	loadKML: function (url, callback, zoomTo, options) {

	},
	loadJSON: function (url) {
		var map = this;
		var layer = [];
		// /AJAX request to get geoJSON object
		var kml2json = new Ajax.Request(url, {
			method: 'get',
			onSuccess: function (transport) {
				var jsonStr = transport.responseText.gsub('\n', '').gsub('\t', '');
				var obj = jsonStr.evalJSON();

				obj.features.each(function (feature) {
					// call shape drawer
					if (feature.type === 'Point') {
						map.drawJSONPoint(layer, feature);
					} else if (feature.type === 'Polygon' || feature.type === 'LineString') {
						map.drawJSONPoly(layer, feature);
					}
				});

				// check for bounding box
				if (obj.bbox) {
					// remove '0' from bounding box
					obj.bbox = obj.bbox.without(0);
					var bestFit = new esri.geometry.Extent(obj.bbox[3], obj.bbox[0], obj.bbox[1], obj.bbox[2], map.map.extent.spatialReference.wkid);
					// timeout prevents IE error
					if (bestFit) {
						setTimeout(function () {
						// map.map.setExtent(bestFit);
						}.bind(this), 1000);
					}
				}
			}

		});
		return layer;
	},
	/**
	 * Removes all shapes from drawing layers
	 */
	removeAllShapes: function () {
		this.layers.each(function (layer) {
			if (typeof layer != 'undefined') {
				layer.each(function (shape) {
					this.map.graphics.remove(shape);
				}.bind(this));
			}
		}.bind(this));
		this.layers = [];
	},
	drawJSONPoint: function (layer, feature) {
		// set map symbol for marker
		var symbol;
		var iconHref;
		if (feature.style.iconStyle) {
			iconHref = feature.style.iconStyle.iconHref;
			if (Prototype.Browser.IE && Prototype.Browser.version < 7) {
				iconHref = iconHref.substringBefore('.') + '.gif';
			}
			symbol = new esri.symbol.PictureMarkerSymbol(iconHref, 57, 53);
			symbol.yoffset = 18;
			symbol.xoffset = 9;
		} else {
			if (feature.styleUrl) {
				if (feature.styleUrl.indexOf('-') !== -1) {
					iconHref = $rootUrl + '/layer/' + feature.styleUrl.substringAfter('-') + '/marker.png';
				} else {
					iconHref = $rootUrl + '/' + feature.styleUrl;
				}
				if (Prototype.Browser.IE && Prototype.Browser.version < 7) {
					iconHref = iconHref.substringBefore('.') + '.gif';
				}
				symbol = new esri.symbol.PictureMarkerSymbol(iconHref, 57, 53);
				symbol.yoffset = 18;
				symbol.xoffset = 9;
			} else {
				symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0,
						255, 0, 0.25]));
			}
		}
		// set shape and add graphic to layer array
		var geometry = new esri.geometry.Point(feature.coordinates[0], feature.coordinates[1], this.map.spatialReference);
		var graphic = new esri.Graphic(geometry, symbol);
		graphic.visible = true;
		this.map.graphics.add(graphic);
		layer.push(graphic);
	},
	drawJSONPoly: function (layer, feature) {
		feature.type = (feature.type === 'Polygon') ? feature.type : 'Polyline';
		var polygon = (feature.type === 'Polygon') ? true : false;
		var symbol, fColour, width, fillColour, lineSymbol, polySymbol;
		var geometry = new esri.geometry[feature.type]();
		var points = feature.coordinates.collect(function (coord) {
			return new esri.geometry.Point(coord[0], coord[1]);
		});

		if (polygon) {
			geometry.addRing(points);
		} else {
			geometry.addPath(points);
		}
		geometry.spatialReference = this.map.spatialReference;

		fColour = (feature.style.lineStyle) ? feature.style.lineStyle.color : null;

		colour = (fColour) ? new dojo.Color('#' + fColour.substr(6, 2) + fColour.substr(4, 2) + fColour.substr(2, 2)) : new dojo.Color('#FF0000');

		width = (feature.style.lineStyle) ? feature.style.lineStyle.width : 2;
		fillColour = (fColour) ? new dojo.Color('#' + fColour.substr(6, 2) + fColour.substr(4, 2) + fColour.substr(2, 2)) : new dojo.Color('#FF0000');
		fillColour.a = 0.4;
		lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, colour, width);
		polySymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, colour, width), fillColour);

		symbol = (feature.type === 'Polyline') ? lineSymbol : polySymbol;

		var graphic = new esri.Graphic(geometry, symbol);
		graphic.visible = true;
		this.map.graphics.add(graphic);
		layer.push(graphic);
	},
	/**
	 * @param {VEShapeLayer}
	 *            layer - The layer to be removed
	 */
	unloadLayer: function (layer) {
		layer.each(function (graphic) {
			this.map.graphics.remove(graphic);
		}.bind(this));
	},
	toggleMap: function (map) {
		var visible = map.visible ? false : true;
		map._setVisibility(visible);
		if (visible) {
			map.setVisibleLayers(map.layerInfos.collect(function (l) {
				return l.id;
			}));
		}
		var form = $(this.id).up('form');
		if (form) {
			form.getElementsBySelector('input[name="param:mapURL"]').each(function (mapURL) {
				if (mapURL.value === map.url) {
					mapURL.disabled = visible ? false : true;
				}
			});
		}
		return visible;
	},
	/**
	 * @param {VEShapeLayer}
	 *            layer - The layer to show
	 * @param {Boolean|Integer}
	 *            zoomTo - If true then the Map should move to the best view for
	 *            the new Layer - If an Integer then zoom to that idexed shape
	 */
	showLayer: function (url, layerId, json) {
		if (json) {
			var layer = url;
			layer.each(function (graphic) {
				graphic.show();
				graphic.visible = true;
			}.bind(this));
		} else {
			if (this.maps[url].visibleLayers.indexOf(layerId) === -1) {
				this.maps[url].visibleLayers.push(Number(layerId));
			}
			this.maps[url].setVisibleLayers(this.maps[url].visibleLayers);
		}
	},
	/**
	 * @param {VEShapeLayer}
	 *            layer - The layer to hide
	 */
	hideLayer: function (url, layerId, json) {
		if (json) {
			var layer = url;
			layer.each(function (graphic) {
				graphic.hide();
				graphic.visible = false;
			}.bind(this));
		} else {
			this.maps[url].visibleLayers = this.maps[url].visibleLayers.without(layerId);
			this.maps[url].setVisibleLayers(this.maps[url].visibleLayers);
		}
	},
	/**
	 * Hide all layers
	 */
	hideAllLayer: function () {

	},
	zoomTo: function (event, element) {
		var ext, maxX, maxY, minY, minX;
		maxX = maxY = minY = minX = null;
		this.map.graphics.graphics.each(function (g, i) {
			if (g.visible) {
				if (minX === null) {
					if (g.geometry.type === 'point') {
						minX = g.geometry.x - 0.5;
						minY = g.geometry.y - 0.5;
						maxX = g.geometry.x + 0.5;
						maxY = g.geometry.y + 0.5;
					} else {
						ext = g.geometry.getExtent();
						minX = ext.xmin;
						minY = ext.ymin;
						maxX = ext.xmax;
						maxY = ext.ymax;
					}
				}
				if (g.geometry.type === 'point') {
					minX = (g.geometry.x - 0.5 < minX) ? g.geometry.x - 0.5 : minX;
					minY = (g.geometry.y - 0.5 < minY) ? g.geometry.y - 0.5 : minY;
					maxX = (g.geometry.x + 0.5 > maxX) ? g.geometry.x + 0.5 : maxX;
					maxY = (g.geometry.y + 0.5 > maxY) ? g.geometry.y + 0.5 : maxY;
				} else {
					ext = g.geometry.getExtent();
					minX = (ext.xmin < minX) ? ext.xmin : minX;
					minY = (ext.ymin < minY) ? ext.ymin : minY;
					maxX = (ext.xmax > maxX) ? ext.xmax : maxX;
					maxY = (ext.ymax > maxY) ? ext.ymax : maxY;
				}
			}
		}.bind(this));
		if (minX !== null) {
			ext = new esri.geometry.Extent(minX, minY, maxX, maxY, this.map.SpatialReference);
			this.map.setExtent(ext);
		}
		if (element) {
			element.blur();
			Event.stop(event);
		}
	},
	/**
	 * @param {String}
	 *            url - The url of the RSS feed
	 * @param {Function}
	 *            callback - A function to be run when the RSS is loaded
	 * @param {Boolean}
	 *            zoomTo - If true then the Map should move to the best view for
	 *            the new Layer
	 */
	loadRSS: function (url, callback, zoomTo, options) {

	},
	styleLayerFeatures: function (layer, options) {

	},
	selectGeometry: function () {

	},
	removePointsFromFeature: function () {

	},
	/**
	 * Adds points onto all the vertices and side of a Polygon/Line so that it
	 * can be modified
	 * 
	 * @param {VEShape}
	 *            geometry - The shape we are going to edit
	 * @param {Boolean}
	 *            end - If true then the points will be removed
	 */
	pointsToFeature: function (geometry, end) {

	},
	mapDrag: function (mapDiv, event) {

	},
	mapScroll: function (mapDiv, event) {

	}
});
/**
 * The Line Drawer extends the Base Drawer
 */
LHS.MapESRI.PointDrawer = Class.create();
LHS.MapESRI.PointDrawer.prototype = Object.extend(new LHS.Map.Drawer(), {
	shape: null,
	shapeType: esri.toolbars.Draw.POINT,
	layer: null,
	/**
	 * @constructor
	 * @param {LHS.MapImpl}
	 *            Map - the map implementation
	 * @param {String}
	 *            icon - the url to the icon used on the start point
	 * @param {String}
	 *            colour - the colour to be used to the stroke and fill
	 * @param {Integer}
	 *            width - the width of the stroke
	 * @param {String}
	 *            title - the title of the layer of the stroke
	 */
	initialize: function (Map, options) {

		if (Map) {
			this.mapObj = Map;
			this.markers = [];
			this.options = Object.extend(Map.drawOptions, options);
			this.drawToolbar = new esri.toolbars.Draw(Map.map);
			dojo.connect(this.drawToolbar, 'onDrawEnd', this.makePoint.bind(this));
			this.drawToolbar.activate(this.shapeType);
			// this.mapObj.map.hideZoomSlider();
			this.layer = [];
		}
	},
	/**
	 * Create a point for the shape here
	 * 
	 * @param {VEEvent}
	 *            event
	 */
	makePoint: function (geometry) {
		var symbol;
		if (this.options.marker && this.options.marker.endsWith('.png')) {
			var iconHref = this.options.marker;
			if (Prototype.Browser.IE && Prototype.Browser.version < 7) {
				iconHref = iconHref.substringBefore('.') + '.gif';
			}
			symbol = new esri.symbol.PictureMarkerSymbol(iconHref, 57, 53);
			symbol.yoffset = 18;
			symbol.xoffset = 9;
		} else {
			symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0,
					0.25]));
		}

		if (this.markers.length < 1) {
			var graphic = new esri.Graphic(geometry, symbol);
			this.mapObj.map.graphics.add(graphic);
			this.markers.push({
				x: geometry.x,
				y: geometry.y,
				spatialReference: this.mapObj.map.spatialReference
			});
			this.shape = graphic;
		}
	},
	/**
	 * Remove the last drawn marker
	 */
	stepBack: function () {
		if (this.markers.length !== 0) {
			if (this.shape) {
				this.mapObj.map.graphics.remove(this.shape);
			}
			if (this.markers.length === 1 && this.startPoint) {
				this.mapObj.map.graphics.remove(this.startPoint);
			}
			this.markers.pop();
		}
	},
	/**
	 * Cancel the current shape completely
	 */
	clear: function () {
		this.mapObj.map.graphics.remove(this.shape);
		if (this.startPoint) {
			this.mapObj.map.graphics.remove(this.startPoint);
		}
		if (this.endPoint) {
			this.mapObj.map.graphics.remove(this.endPoint);
		}
		this.drawToolbar.deactivate();
	},
	/**
	 * Remove the endpoint marker, click event and return the KML
	 * 
	 * @param {VEShapeLayer}
	 *            outputLayer - the layer to add to new shape too
	 */
	finish: function () {
		this.drawToolbar.deactivate();
		var kml = this.serialize();
		if (this.mapObj.layers[this.options.layerId]) {
			this.mapObj.layers[this.options.layerId].push(this.shape);
		} else {
			this.mapObj.layers[this.options.layerId] = [];
			this.mapObj.layers[this.options.layerId].push(this.shape);
		}

		if (this.startPoint) {
			this.mapObj.map.graphics.remove(this.startPoint);
		}
		if (this.endPoint) {
			this.mapObj.map.graphics.remove(this.endPoint);
		}
		return kml;
	},
	/**
	 * Uses the collection of markers that have been created to produce the KML
	 * for the points
	 * 
	 * @return {String|null} return the KML String or null if there are not
	 *         sufficient markers
	 */
	serialize: function () {
		if (this.markers.length === 0) {
			return null;
		}
		var kml = this.markers.collect(function (marker) {
			return '<Point xmlns="http://earth.google.com/kml/2.2"><coordinates>' + marker.x + ',' + marker.y + '</coordinates></Point>';
		});
		return kml.join('');
	}
});

/**
 * The Line Drawer extends the Point Drawer
 */
LHS.MapESRI.LineDrawer = Class.create();
LHS.MapESRI.LineDrawer.prototype = Object.extend(new LHS.MapESRI.PointDrawer(), {
	pointCount: 0,
	startPoint: null,
	editPoint: null,
	type: 'Polyline',
	makePoint: function (geometry) {
		var point = {
			x: geometry.x,
			y: geometry.y,
			spatialReference: this.mapObj.map.spatialReference
		};
		this.markers.push(point);
		if (this.markers.length > 1) {
			this.redraw();
		} else {
			if (this.options.marker && this.options.marker.endsWith('.png')) {
				var iconHref = this.options.marker;
				if (Prototype.Browser.IE && Prototype.Browser.version < 7) {
					iconHref = iconHref.substringBefore('.') + '.gif';
				}
				symbol = new esri.symbol.PictureMarkerSymbol(iconHref, 57, 53);
				symbol.yoffset = 18;
				symbol.xoffset = 9;
			} else {
				symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0,
						255, 0, 0.25]));
			}
			this.startPoint = new esri.Graphic(new esri.geometry.Point(point), symbol);
			this.mapObj.map.graphics.add(this.startPoint);
		}
	},
	redraw: function () {
		if (this.shape) {
			this.mapObj.map.graphics.remove(this.shape);
		}
		var iconHref = (Prototype.Browser.IE && Prototype.Browser.version < 7) ? $context + '/images/mapping/pencil.gif' : $context + '/images/mapping/pencil.png';
		var editSymbol, editPoint;
		var colour = (this.options.colour) ? new dojo.Color('#' + this.options.colour) : new dojo.Color('#FF0000');
		var width = (this.options.width) ? this.options.width : 2;
		var fillColour = (this.options.colour) ? new dojo.Color('#' + this.options.colour) : new dojo.Color('#FF0000');
		fillColour.a = 0.4;

		var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, colour, width);
		var polySymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, colour, width), fillColour);

		var symbol = (this.type === 'Polyline') ? lineSymbol : polySymbol;
		var geometry = new esri.geometry[this.type]();
		var points = this.markers.collect(function (marker) {
			return new esri.geometry.Point(marker.x, marker.y);
		});
		if (this.type === 'Polyline') {
			geometry.addPath(points);
		} else {
			geometry.addRing(points);
		}

		if (this.endPoint) {
			this.mapObj.map.graphics.remove(this.endPoint);
		}
		editSymbol = new esri.symbol.PictureMarkerSymbol(iconHref, 40, 40);
		editSymbol.yoffset = 12;
		editSymbol.xoffset = 14;
		editPoint = this.markers.last();
		this.endPoint = new esri.Graphic(new esri.geometry.Point(editPoint), editSymbol);
		this.mapObj.map.graphics.add(this.endPoint);

		geometry.spatialReference = this.mapObj.map.spatialReference;
		this.shape = new esri.Graphic(geometry, symbol);
		this.mapObj.map.graphics.add(this.shape);
	},
	serialize: function () {
		if (this.markers.length <= 1) {
			return null;
		}

		var kml = this.markers.collect(function (marker) {
			return marker.x + ',' + marker.y + ',0.000000';
		});

		return '<LineString xmlns="http://earth.google.com/kml/2.2"><tessellate>1</tessellate><coordinates>' + kml.join(' ') + '</coordinates></LineString>';
	}
});

/**
 * The Polygon Drawer extends the Line Drawer
 */
LHS.MapESRI.PolygonDrawer = Class.create();
LHS.MapESRI.PolygonDrawer.prototype = Object.extend(new LHS.MapESRI.LineDrawer(), {
	type: 'Polygon',
	serialize: function () {
		if (this.markers.length <= 2) {
			return null;
		}

		var kml = this.markers.collect(function (marker) {
			return marker.x + ',' + marker.y + ',0.000000';
		});

		return '<Polygon xmlns="http://earth.google.com/kml/2.2"><outerBoundaryIs><LinearRing><tessellate>1</tessellate><coordinates>' + kml.join(' ') + '</coordinates></LinearRing></outerBoundaryIs></Polygon>';
	}
});

