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