function Edit_Setup() {
	Edit.mapDiv = document.getElementById('gmap_div');
	Edit.elementsTable = document.getElementById("gv_elements_list");
	
	Edit.toolbarButtons = new Array();
	Edit.toolbarButtons['add_marker'] = document.getElementById('gv_button_add_marker');
	Edit.toolbarButtons['add_line'] = document.getElementById('gv_button_add_line');
	Edit.toolbarButtons['add_area'] = document.getElementById('gv_button_add_area');
	Edit.toolbarButtons['pan'] = document.getElementById('gv_button_pan');
	Edit.toolbarButtons['save_gpx'] = document.getElementById('gv_button_save_gpx');
	Edit.toolbarButtons['save_kml'] = document.getElementById('gv_button_save_gpx');
	
	Edit.crosshair = document.getElementById('gv_crosshair');
	
	Edit.addressBox = document.getElementById('address_input');
	Edit.addressBox.onkeypress = function(e) { if (!e) { e = window.event; } if (e.keyCode == 13) { Edit.getGPSLocation(Edit.addressBox.value); return false; } };
	Edit.addressOutput = document.getElementById('address_output');
	
}

Edit = new function() {
	this.map = null;
	this.mapDiv = null;
	this.mapType = null;
	this.ajax = null;
	this.waypoints = [];
	this.numWaypoints = 0;
	this.notes = [];
	this.numNotes = 0;
	this.pictures = [];
	this.numPictures = 0;
	this.tracks = [];
	this.numTracks = 0;
	this.waypointsDiv = null;
	this.drawingTrack = false;
	this.debugBox = null;
	this.currTrackLine = null;
	this.currTrackPoints = [];
	this.tracksTable = null;
	this.currTrackId = 0;
	this.currEditedWaypoint = null;
	this.editDiv = null;
	this.stats = [];
	this.bboxes = [];
	this.tripMarkers = [];
	this.helpText = "";
	this.wasEdited = false;
	this.canGetTrips = false;
	this.tempWaypoints = [];
	this.numTempWaypoints = 0;
	this.tempTracks = [];
	this.numTempTracks = 0;
	this.bool = null;
	
	this.defaultTrackColor = '#FF00FF';
	this.defaultPolygonColor = '#0000FF';
	
	this.markerTooltipID = 'marker_tooltip';
	
	this.stayInWaypointMode = false;
	
	this.load = function() {
		var self = Edit;

		self.ajax = new Ajax();
		self.makeIcons();


		if (gmap) { self.map = gmap; } else { self.map = new GMap2(self.mapDiv); }
		// self.map.enableDoubleClickZoom();
		// self.map.enableScrollWheelZoom();
		// self.map.enableContinuousZoom();
		
		self.mapOffset = self.findPos(self.mapDiv);

		self.setupButtons();

		if (!document.getElementById(Edit.markerTooltipID)) { // initialize it if it hasn't been done yet
			marker_tooltip = Sandbox_Initialize_Marker_Tooltip(Edit.map,Edit.markerTooltipID);
		}
	}
	
	this.addLoadingDiv = function(message) {
		var self = Edit;

		mapContainer = self.mapDiv;

		self.statusDiv = document.createElement('div');
		self.statusDiv.id = 'statusDiv';

		messageWidth = 120;
		messageHeight = 20;

		mapWidth = mapContainer.style.width.replace('px','');
		mapHeight = mapContainer.style.height.replace('px','');

		leftPos = (mapWidth-messageWidth)/2;
		topPos = (mapHeight-messageHeight)/2;

		self.statusDiv.style.position = "absolute";
		self.statusDiv.style.zindex = 100;
		self.statusDiv.style.backgroundColor = "#FFFFFF";
		self.statusDiv.style.border = "2px solid #000000";
		self.statusDiv.style.left = leftPos+'px';
		self.statusDiv.style.top = topPos+'px';
		self.statusDiv.style.width = messageWidth + "px";
		self.statusDiv.style.height = messageHeight + "px";
		self.statusDiv.align = "center";
		self.statusDiv.verticalAlign = "middle";

		self.statusDiv.innerHTML = "<font size=+0>"+message+"</font>";

		mapContainer.appendChild(self.statusDiv);
	}
	
	this.removeLoadingDiv = function() {
		var self = Edit;
		
		self.mapDiv.removeChild(self.statusDiv);
		self.statusDiv = null;
	}
	
	this.findPos = function(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return new GPoint(curleft,curtop)
}

	
	this.getMouseXY = function(e) {
		var self = Edit;

		var tempX = 0;
		var tempY = 0;
		var IE = document.all?true:false;

		if (IE) { // grab the x-y pos.s if browser is IE
		  tempX = event.clientX + document.body.scrollLeft;
		  tempY = event.clientY + document.body.scrollTop;
		  
		  if (document.documentElement) {
			  tempY = event.clientY + document.documentElement.scrollTop;
		  } else { (document.body && document.body.scrollTop); }



		} else { // grab the x-y pos.s if browser is NS
			tempX = e.pageX;
			tempY = e.pageY;
		}

		if (tempX < 0){tempX = 0;}
		if (tempY < 0){tempY = 0;}
		
		mapX = self.mapDiv.offsetLeft;

		self.removeHelpDiv();
		self.addHelpDiv(self.helpText,new GPoint(tempX-self.mapOffset.x+8,tempY-self.mapOffset.y+8));
		
		//self.drawDottedLine(tempX-self.mapOffset.x,tempY-self.mapOffset.y);

		
	}
	
	this.drawDottedLine = function(x,y) {
		var self = Edit;
		
		if(self.currTrackId) {
			track = self.tracks[self.currTrackId];
			
			lastpoint = track['points'][track['points'].length-1];
			if(self.bool == null) {
			// alert(self.currTrackId);
		}
		self.bool = "no";
		}
	}

	this.addMouseEvents = function() {
		var self = Edit;
		
		var IE = document.all?true:false;

		if (!IE) document.captureEvents(Event.MOUSEMOVE)

		self.mapDiv.onmousemove = self.getMouseXY;
		self.mapDiv.onmouseout = self.removeHelpDiv;
	}
	
	this.removeMouseEvents = function() {
		var self = Edit;
		self.mapDiv.onmousemove = null;
		self.removeHelpDiv();
	}
	
	this.setupButtons = function() {
		var self = Edit;
		
		self.toolbarButtons['add_marker'].onclick = function() {
			self.highlightButton('add_marker');
			self.addNewWaypoint();
			return false;
		};
		
		self.toolbarButtons['add_line'].onclick = function() {
			self.highlightButton('add_line');
			self.addWaypointEvent = null;
			self.addNewTrack(false);
			return false;
		};
		
		self.toolbarButtons['add_area'].onclick = function() {
			self.highlightButton('add_area');
			self.addWaypointEvent = null;
			self.addNewTrack(true);
			return false;
		};
		
		self.toolbarButtons['pan'].onclick = function() {
			self.highlightButton('pan');
			if(self.addWaypointEvent) { GEvent.removeListener(self.addWaypointEvent); }
			if(self.addTrackEvent) { GEvent.removeListener(self.addTrackEvent); }
			self.addWaypointEvent = null;
			self.addTrackEvent = null;
			self.removeMouseEvents();
			var track = self.tracks[self.currTrackId];
			if(track) {
				self.removeTrackMarkers(self.currTrackId);
				if(track['points'].length == 0 || track['finished'] != true) {
					self.deleteTrack(self.currTrackId);
				}
			}
			return false;
		};
		
		self.crosshair.onclick = function() {
			if(self.addWaypointEvent) {
				self.placeNewMarker(self.map.getCenter());
			} else {
				// do nothing
			}
			return false;
		};
	}
	this.highlightButton = function(button_id) {
		var self = Edit;
		for (j in self.toolbarButtons) {
			var old_src = self.toolbarButtons[j].src;
			var new_src;
			if (j == button_id) {
				new_src = old_src.replace(/\/(\w+)\.(png|gif|jpg)$/,"/$1-selected.$2");
			} else {
				new_src = old_src.replace(/\/(\w+)-selected\.(png|gif|jpg)$/,"/$1.$2");
			}
			if (new_src != old_src) {
				self.toolbarButtons[j].src = new_src;
			}
		}
		
	}
	
	this.centerOnLoc = function(locPoint) {
		var self = Edit;
		if(locPoint) {
			self.map.setCenter(locPoint,13);
		}
		
	}
	
	this.getGPSLocation = function(address) {
		var self = Edit;
		
		var centered = false;
		var coordinate_pattern = new RegExp('^ *([NSEW])? *((?:[0-9\.\-]+[^0-9A-Z\.\-]*)+) *([NSEW])? *, *([EWNS])? *((?:[0-9\.\-]+[^0-9A-Z\.\-]*)+) *([EWNS])? *,? *$','i');
		if (address.match(coordinate_pattern)) { // the query looks like a pair of numeric coordinates
			var coordinate_match = coordinate_pattern.exec(address.toUpperCase());
			if (coordinate_match && coordinate_match[2] != null && coordinate_match[5] != null) {
				var lat = decimalCoordinate((coordinate_match[1]||'')+coordinate_match[2]+(coordinate_match[3]||''));
				var lon = decimalCoordinate((coordinate_match[4]||'')+coordinate_match[5]+(coordinate_match[6]||''));
				if ((coordinate_match[1] && coordinate_match[1].match(/[EW]/i)) || (coordinate_match[3] && coordinate_match[3].match(/[EW]/i)) || (coordinate_match[4] && coordinate_match[4].match(/[NS]/i)) || (coordinate_match[6] && coordinate_match[6].match(/[NS]/i))) {
					lon = decimalCoordinate((coordinate_match[1]||'')+coordinate_match[2]+(coordinate_match[3]||''));
					lat = decimalCoordinate((coordinate_match[4]||'')+coordinate_match[5]+(coordinate_match[6]||''));
				}
				if (Math.abs(lat) <= 90 && Math.abs(lon) <= 180) {
					self.map.setCenter(new GLatLng(lat,lon)); // don't change the zoom level
					centered = true;
					self.addressOutput.innerHTML = 'Re-centering on '+lat+', '+lon;
					if (self.gv_save_position_after_geocoding && gv_save_position_after_geocoding === true) {
						self.map.savePosition();
					}
				}
			}
		}
		if (!centered) {
			var geocoder = new GClientGeocoder();
			geocoder.getLocations(address, self.processGeocodeInfo);
		}
	}
	
	this.processGeocodeInfo = function(info) {
		var self = Edit;
		var google_precision = ['not found','country','state','county','city','zip','street','intersection','address'];
		if(info && info.Placemark && info.Placemark[0].Point) {
			var coords = new GLatLng(info.Placemark[0].Point.coordinates[1],info.Placemark[0].Point.coordinates[0]);
			var zoom = (self.map.getZoom() >= 5) ? self.map.getZoom() : 5;
			if (info.Placemark[0].AddressDetails) {
				var accuracy = info.Placemark[0].AddressDetails.Accuracy;
				accuracy_as_zoom = [2, 6, 7, 9, 11, 13, 14, 15, 15];
				//                  nf na st co ci  zip str int add
				zoom = accuracy_as_zoom[accuracy];
			}
			self.map.setCenter(coords,zoom);
			if (gv_save_position_after_geocoding == true) {
				self.map.savePosition();
			}
			var found = (info.Placemark[0].address) ? '<b>'+info.Placemark[0].address+'</b> ('+info.Placemark[0].Point.coordinates[1]+','+info.Placemark[0].Point.coordinates[0]+')' : '<b>'+info.Placemark[0].Point.coordinates[1]+','+info.Placemark[0].Point.coordinates[0]+'</b>';
			self.addressOutput.innerHTML = 'Google found: '+found;
			self.addressOutput.innerHTML += ' [precision:'+google_precision[info.Placemark[0].AddressDetails.Accuracy]+']';
		} else if (info && info.name) {
			self.addressOutput.innerHTML = 'Google could not locate "'+info.name+'".';
		}
	}
	
	this.makeIcons = function() {
		var self = Edit;
		
		self.inactiveIcon = new GIcon();
		self.inactiveIcon.image = "images/marker.png";
		self.inactiveIcon.iconSize = new GSize(15, 15);
		self.inactiveIcon.shadowSize = new GSize(15, 15);
		self.inactiveIcon.iconAnchor = new GPoint(8, 8);
		self.inactiveIcon.infoWindowAnchor = new GPoint(8, 8);

		self.activeIcon = new GIcon();
		self.activeIcon.image = "images/marker_red.png";
		self.activeIcon.iconSize = new GSize(15, 15);
		self.activeIcon.shadowSize = new GSize(15, 15);
		self.activeIcon.iconAnchor = new GPoint(8, 8);
		self.activeIcon.infoWindowAnchor = new GPoint(8, 8);
		
		self.trackIcon = new GIcon();
		self.trackIcon.image = "images/track_marker.png";
		self.trackIcon.iconSize = new GSize(10, 10);
		self.trackIcon.shadowSize = new GSize(10, 10);
		self.trackIcon.iconAnchor = new GPoint(5, 5);
		self.trackIcon.infoWindowAnchor = new GPoint(5, 5);
		
		self.articleIcon = new GIcon();
		self.articleIcon.image = "images/trip_marker.png";
		self.articleIcon.iconSize = new GSize(9, 9);
		self.articleIcon.shadowSize = new GSize(9, 9);
		self.articleIcon.iconAnchor = new GPoint(9, 0);
		self.articleIcon.infoWindowAnchor = new GPoint(9, 9);
		
		// self.waypointIcon = new GIcon();
		// self.waypointIcon.image = "images/red_marker_small.png";
		// self.waypointIcon.iconSize = new GSize(11, 19);
		// self.waypointIcon.shadowSize = new GSize(11, 19);
		// self.waypointIcon.iconAnchor = new GPoint(5, 18);
		// self.waypointIcon.infoWindowAnchor = new GPoint(6, 10);
		
		self.waypointIcon = new GIcon();
		self.waypointIcon.image = "images/googlemini-red.png";
		self.waypointIcon.transparent = "images/googlemini-red-t.png"
		self.waypointIcon.shadow = "images/googlemini-shadow.png"
		self.waypointIcon.iconSize = new GSize(12,20);
		self.waypointIcon.iconAnchor = new GPoint(6,20);
		self.waypointIcon.shadowSize = new GSize(22,20);
		self.waypointIcon.infoWindowAnchor = new GPoint(5,1);
		self.waypointIcon.infoShadowAnchor = new GPoint(10,15);
		self.waypointIcon.imageMap = [4,19, 4,14, 0,7, 0,3, 4,0, 7,0, 11,3, 11,7, 7,14, 7,19, 4,19];
	}

	
	this.getEleFromPoint = function(point) {
		var self = Edit;
		
		return 0;
	}
	
	this.metersToMiles = function(meters) {
		return meters * 0.000621371192;
	}
	
	this.metersToFeet = function(meters) {
		return meters * 0.000621371192 * 5280;
	}
	
	this.gpsDist = function(p1,p2) {
		var self = Edit;
		return p1.distanceFrom(p2);
	}
	
	this.changeCursor = function(cursorStyle) {
		var self = Edit;
		
		self.mapDiv.style.cursor = "pointer";

	}


	this.updateStats = function() {
		var self = Edit;
		
		/* vars */
		var distance = 0;
		var up = 0;
		var down = 0;
		var startingPoint = null;
		var startingEle = null;
		var lowestPoint = null;
		var lowestEle = null;
		var highestPoint = null;
		var highestEle = null;

		for(i=0; i<self.tracks.length;i++) {
			var track = self.tracks[i];
			if(track) {
				
		
		

				/* go through all points */
				for(j=0; j<track['points'].length;j++) {
					var currPoint = track['points'][j];
					var nextPoint = track['points'][j+1];
					var currEle = track['eles'][j];

					if(startingPoint == null) {
						startingPoint = currPoint;
						startingEle = currEle;
					}

					if(nextPoint) {
						/* calculate up and down */

						var nextEle = track['eles'][j+1];
						var diff = nextEle - currEle;
						if(diff > 0) {
							up += diff;
						} else {
							if(isNaN(down)) { alert (currEle + "---- " + nextEle + "---" + j); }
							down -= diff;
						}
						
						/* calculate lowest point and highest point */
						if(lowestPoint == null || currEle < lowestEle) {
							lowestPoint = currPoint;
							lowestEle = currEle;
						}
						if(highestPoint == null || currEle > highestEle) {
							highestPoint = currPoint;
							highestEle = currEle;
						}

						/* calculate distance */
						distance += self.gpsDist(currPoint,nextPoint);
					}

				}
			}
		}

		/* update values */
		document.getElementById('distanceSpan').innerHTML = Math.round(distance*10)/10 + " ("+Math.round(self.metersToMiles(distance)*10)/10+" miles)";
		document.getElementById('upSpan').innerHTML = Math.round(up*10)/10 + "m ("+Math.round(self.metersToFeet(up)*10)/10+" ft)";
		document.getElementById('downSpan').innerHTML = Math.round(down*10)/10 + "m ("+Math.round(self.metersToFeet(down)*10)/10+" ft)";;			
		
		if(startingPoint) {
		document.getElementById('startingPointSpan').innerHTML = "(" + Math.round(startingPoint.lat()*1000)/1000 + "," +
																					Math.round(startingPoint.lng()*1000)/1000 + ") " + Math.round(startingEle*10)/10 + 
																					"m ("+Math.round(self.metersToFeet(startingEle)*10)/10+" ft)";
		}
		if(lowestPoint) {
		document.getElementById('lowestPointSpan').innerHTML = "(" + Math.round(lowestPoint.lat()*1000)/1000 + "," +
																				 Math.round(lowestPoint.lng()*1000)/1000 + ") " + Math.round(lowestEle*10)/10 +
																				 "m ("+Math.round(self.metersToFeet(lowestEle)*10)/10+" ft)";
		} 
		if(highestPoint) {
		document.getElementById('highestPointSpan').innerHTML = "(" + Math.round(highestPoint.lat()*1000)/1000 + "," + 
																				  Math.round(highestPoint.lng()*1000)/1000 + ") " + Math.round(highestEle*10)/10 +
																				  "m ("+Math.round(self.metersToFeet(highestEle)*10)/10+" ft)";
		}
		
		/* update vars */
		self.stats['distance'] = distance;
		self.stats['up'] = up;
		self.stats['down'] = down;
		self.stats['startingPoint'] = startingPoint;
		self.stats['startingEle'] = startingEle;
		self.stats['lowestPoint'] = lowestPoint;
		self.stats['lowestEle'] = lowestEle;
		self.stats['highestPoint'] = highestPoint;
		self.stats['highestEle'] = highestEle;

	}


	
	this.createPin = function(type,id) {
		var self = Edit;
		var marker = null;

		if(type == "waypoint") {
			var waypoint = self.waypoints[id];
			var name = waypoint['name'];
			var point = new GLatLng(waypoint['lat'],waypoint['lon']);
			marker = new GMarker(point, {draggable:true,icon:self.waypointIcon});

			GEvent.addListener(marker, "click", function() {
				var waypoint = Edit.waypoints[id];

				var name = waypoint['name'];
				
				var lat = waypoint['lat'].toFixed(5);
				var lon = waypoint['lon'].toFixed(5);
				var ele = waypoint['ele'];
				var desc = waypoint['desc'];

				var html = "<div style=''><b>" + name + "</b> [<a href='javascript:Edit.editWaypoint("+id+");'>edit</a>]<br>("+lat+","+lon+")</div>";

				marker.openInfoWindow(html);
			});

			GEvent.addListener(marker, "dragstart", function() {
				self.map.closeInfoWindow();
			});

			GEvent.addListener(marker, "dragend", function() {
				var point = marker.getPoint();

				self.waypoints[id]['lat'] = point.lat();
				self.waypoints[id]['lon'] = point.lng();
				self.madeEdit();

			});
			
			GEvent.addListener(marker, "mouseover", function() {
				var waypoint = Edit.waypoints[id];
				name = waypoint['name'];
				Sandbox_Create_Marker_Tooltip(Edit.map,marker,name);
			});
			GEvent.addListener(marker,'mouseout', function() {
				marker_tooltip.style.visibility = 'hidden';
			});
			
			/*
			GEvent.addListener(marker, "mouseover", function() {
				self.highlightWaypoint("waypoint"+id);
			});
			GEvent.addListener(marker, "mouseout", function() {
				self.unhighlightWaypoint("waypoint"+id);
			});
			*/
		}
		
		return marker;
	}
	
	this.addWaypointRow = function(waypointId) {
		var self = Edit;

		waypoint = self.waypoints[waypointId];
		waypointName = waypoint['name'];
		
		self.waypointsTable.insertRow(self.waypointsTable.rows.length);
		var row = self.waypointsTable.rows[self.waypointsTable.rows.length-1];

	
		var cell = row.insertCell(0);
		cell.innerHTML = "<input type=button value='edit' onclick='Edit.editWaypoint("+waypointId+");'>";
		var cell = row.insertCell(1);
		cell.innerHTML = "<input type=button value='delete' onclick='Edit.deleteWaypoint("+waypointId+");'>";
		var cell = row.insertCell(2);
		cell.id = 'waypoint'+waypointId+'name';
		cell.innerHTML = waypointName;
	}
	
	this.updateTrackName = function(trackId) {
		var self = Edit;
		self.madeEdit();
		
		trackName = document.getElementById('trackEditedName').value;
		self.tracks[trackId]['name'] = trackName;
		var track = self.tracks[trackId];
		track['finished'] = true;
		var type = "track";
		if(track['isPolygon']) {
			type = "area";
		}

		cell = document.getElementById(type+trackId+'name');
		cell.innerHTML = "<a href='javascript:Edit.showInfo(\""+type+"\","+trackId+");'>"+trackName+"</a>";

		self.map.closeInfoWindow();
		if (self.trackMarker) { self.map.removeOverlay(self.trackMarker); }
		
	}
	
	this.updateWaypointName = function(waypointId) {
		var self = Edit;
		var type = "marker";
		self.madeEdit();

		waypointName = document.getElementById('currWaypointName').value;
		cell = document.getElementById(type+waypointId+'name');
		cell.innerHTML = "<a href='javascript:Edit.showInfo(\""+type+"\","+waypointId+");'>"+waypointName+"</a>";

		self.waypoints[waypointId]['name'] = waypointName;
		self.map.closeInfoWindow();
	}

	this.updateWaypoint = function(waypointId) {
		var self = Edit;
		self.currEditedWaypoint = null;
		
		var nameCellBox = document.getElementById('waypoint'+waypointId+'nameEdit');
		var html = nameCellBox.value;
		
		var nameCell = document.getElementById('waypoint'+waypointId+'name');
		nameCell.innerHTML = html;
		
		self.waypoints[waypointId]['name'] = html;
	}
	
	this.updateTrack = function(trackId) {
		var self = Edit;
		self.currEditedTrack = null;
		self.drawingTrack = false;
		self.stopEditTrack();
		

		// alert("stop");

		var track = self.tracks[trackId];
		
		var nameCellBox = document.getElementById('track'+trackId+'nameEdit');
		var html = nameCellBox.value;
		
		var nameCell = document.getElementById('track'+trackId+'name');
		nameCell.innerHTML = html;
		
		track['name'] = html;
		self.editDiv.innerHTML = "";
		
		
		//self.updateStats();
	}
	


	this.editWaypoint = function(waypointId) {
		var self = Edit;
		
		var waypoint = self.waypoints[waypointId];
		var html = "Marker name:<br><input id='currWaypointName' value='"+waypoint['name']+"' onfocus='this.select();'><input type=button value='ok' onclick='Edit.updateWaypointName("+waypointId+");Edit.map.closeInfoWindow();'><br><a href='javascript:Edit.deleteWaypoint("+waypointId+");'>Delete</a>";
		var marker = waypoint['marker'];
		
		marker.openInfoWindowHtml(html);
		textField = document.getElementById('currWaypointName');
		if(textField) {
			textField.onkeypress = function(e) {
			if (!e) e = window.event;
				if (e.keyCode == 13) {
					Edit.updateWaypointName(waypointId);
					Edit.madeEdit();
					Edit.map.closeInfoWindow();
				}
			};
		}

		var input = document.getElementById('currWaypointName')
		
	}
	
	
	this.addTempWaypoint = function(lat,lon,ele,name,desc) {
		var self = Edit;
		var waypoint = [];
		waypointId = self.numTempWaypoints;

		waypoint['name'] = name;
		waypoint['desc'] = desc;
		waypoint['lat'] = lat;
		waypoint['lon'] = lon;
		waypoint['ele'] = ele;
		waypoint['marker'] = null;
		self.tempWaypoints[waypointId] = waypoint;

		var marker = new GMarker(new GLatLng(lat,lon),{icon:self.waypointIcon});
		self.map.addOverlay(marker);

		waypoint['marker'] = marker;
		self.tempWaypoints[waypointId] = waypoint;

		//self.addWaypointRow(waypointId);
		self.numTempWaypoints++;
	}

	this.addWaypoint = function(lat,lon,ele,name,desc) {
		var self = Edit;
		var waypoint = [];
		waypointId = self.waypoints.length;
		
		waypoint['name'] = name;
		waypoint['desc'] = desc;
		waypoint['lat'] = lat;
		waypoint['lon'] = lon;
		waypoint['ele'] = ele;
		waypoint['marker'] = null;
		self.waypoints[waypointId] = waypoint;

		var marker = self.createPin("waypoint", waypointId);
		self.map.addOverlay(marker);

		waypoint['marker'] = marker;
		self.waypoints[waypointId] = waypoint;

		//self.addWaypointRow(waypointId);
		self.addElementRow("marker",waypointId);
		self.numWaypoints++;
		self.madeEdit();
		
		return (waypointId);
	}
	
	this.addPicture = function(lat,lon,name,desc,thumb,full) {
		var self = Edit;
		var picture = [];
		pictureId = self.numPictures;
		

		picture['name'] = name;
		picture['desc'] = desc;
		picture['lat'] = lat;
		picture['lon'] = lon;
		picture['thumb'] = thumb;
		picture['full'] = full;
		picture['marker'] = null;
		self.pictures[pictureId] = picture;

		var marker = self.createPin("picture", pictureId);
		self.map.addOverlay(marker);

		picture['marker'] = marker;
		self.pictures[pictureId] = picture;

		self.addPictureRow(pictureId);
		self.numPictures++;
	}
	
	this.removeTrackMarkers = function(trackId) {
		var self = Edit;

		var track = self.tracks[trackId];
		if(track) {
			for(i=0; i<track['markers'].length; i++) {
				if (track['markers'][i]) { self.map.removeOverlay(track['markers'][i]); }
			}
		}
	}
	this.makeMarker = function(trackId,num,marker) {
		var self = Edit;
		

		GEvent.addListener(marker,"drag",function(point) {
				self.tracks[trackId]['points'][num] = marker.getPoint();
				if (self.tracks[trackId]['polyline']) { self.map.removeOverlay(self.tracks[trackId]['polyline']); }
				if(self.tracks[trackId]['isPolygon']) {
					color = self.defaultPolygonColor;
				} else {
					color = self.defaultTrackColor;
				}

				self.tracks[trackId]['polyline'] = new GPolyline(self.tracks[trackId]['points'],color,2,1);
				self.map.addOverlay(self.tracks[trackId]['polyline']);
				self.madeEdit();
		});
		
		GEvent.addListener(marker,"click",function(point) {
				if(num == self.tracks[trackId]['points'].length-1 || num == 0) {
					self.stopEditTrack();
				}
		});
		
		
	}
	
	// this.createTrackMarker = function(point)

	this.addTrackMarkers = function(trackId) {
		var self = Edit;

		var track = self.tracks[trackId];
		if(track) {
			var markers = [];
	
			for(var i=0; i<track['points'].length; i++) {
				
				var point = track['points'][i];
				var marker = new GMarker(point,{draggable:true,icon:self.trackIcon,dragCrossMove:false,bouncy:false});
	
				self.makeMarker(trackId,i,marker);
	
				markers.push(marker);
				self.tracks[trackId]['markers'] = markers;
				self.map.addOverlay(marker);
	
			}
		}
	}
	
	this.stopEditTrack = function(deleteBlank,leaveButtonsAsIs) {
		var self = Edit;
		self.removeTrackMarkers(self.currTrackId);
		self.removeMouseEvents();
		var currTrackId = null;
		var track = self.tracks[self.currTrackId];

		
		/* change track to polygon if needed */
		if(track) {
			if(track['isPolygon']) {
				if (track['polyline']) { self.map.removeOverlay(track['polyline']); }
				track['polyline'] = new GPolygon(track['points'],self.defaultPolygonColor,2,0.6,self.defaultPolygonColor,0.25);
				self.map.addOverlay(track['polyline']);
			}
			
			if(track['points'].length == 0 && deleteBlank) {
				self.deleteTrack(self.currTrackId);
			}
		}
		
		if(self.clickListener) {
			GEvent.removeListener(self.clickListener);
			GEvent.removeListener(self.endTrackListener);
			if(!leaveButtonsAsIs) { self.highlightButton('none'); }
		}
		
	}


	this.trimTrack = function(trackId) {
		var self = Edit;
		self.newPoints = [];
		clickMap =  GEvent.addListener(self.map,"click", function(overlay,point) {
			marker = new GMarker(point,{icon: G_DEFAULT_ICON,draggable:true,bouncy:false});
			text = "Drag the marker to draw the delete box";
			self.map.addOverlay(marker);
			marker.openInfoWindow(text);
			
			startLat = point.lat();
			startLon = point.lng();
			startPoint = point;
			
			var polylineTop;
			var polylineRight;
			var polylineLeft;
			var polylineBottom;
			
			GEvent.addListener(marker,"dragstart",function() {
				self.map.closeInfoWindow();
			});

			GEvent.addListener(marker,"dragend",function() {
				
				endLat = lastLat;
				endLon = lastLon;
				endPoint = new GLatLng(endLat,endLon);
				
				var bounds = new GLatLngBounds();
				bounds.extend(startPoint);
				bounds.extend(endPoint);

				/* Balloon */
				content = document.createElement('div');

				typeStr = document.createTextNode('Do you want to delete these track points? ');
				yesStr = document.createTextNode('Yes ');
				noStr = document.createTextNode('No ');

				yesRadio = document.createElement('input');
				yesRadio.type = "radio";
				yesRadio.id = "yesRadio";
				yesRadio.name = "deleteRadio";
				noRadio = document.createElement('input');
				noRadio.type = "radio";
				noRadio.id = "noRadio";
				noRadio.name = "deleteRadio";
				
				if(self.browserName == "Microsoft Internet Explorer") {
					yesRadio = document.createElement('<input type="radio" name="deleteRadio" id="yesRadio" checked>');
					noRadio = document.createElement('<input type="radio" name="deleteRadio" id="noRadio">');
				}

				submit = document.createElement('input');
				submit.type = "button";
				submit.value = "Delete";
				submit.onclick = function() {
					self.map.closeInfoWindow();
					closeTrack = yesRadio.checked;
					if(closeTrack) {
						self.deleteTrackPoints(trackId,bounds);
					}
					// self.updateAjax("track",trackId);
					if (polylineTop) { self.map.removeOverlay(polylineTop); }
					if (polylineRight) { self.map.removeOverlay(polylineRight); }
					if (polylineBottom) { self.map.removeOverlay(polylineBottom); }
					if (polylineLeft) { self.map.removeOverlay(polylineLeft); }
					if (marker) { self.map.removeOverlay(marker); }
				  
				};

				closeDiv = document.createElement('div');
				closeDiv.appendChild(typeStr);
				closeDiv.appendChild(yesRadio);
				closeDiv.appendChild(yesStr);
				closeDiv.appendChild(noRadio);
				closeDiv.appendChild(noStr);

				content.appendChild(closeDiv);
				content.appendChild(submit);
				yesRadio.checked = true;
				marker.openInfoWindow(content);
			});

			GEvent.addListener(marker, "drag", function() {
				point = marker.getPoint();
				lastLat = point.lat();
				lastLon = point.lng();
				
				startPoint = new GLatLng(startLat,startLon);
				rightPoint = new GLatLng(startLat,lastLon);
				leftPoint = new GLatLng(lastLat,startLon);
				endPoint = new GLatLng(lastLat,lastLon);

				if(polylineTop && polylineRight && polylineBottom && polylineLeft) {
					if (polylineTop) { self.map.removeOverlay(polylineTop); }
					if (polylineRight) { self.map.removeOverlay(polylineRight); }
					if (polylineBottom) { self.map.removeOverlay(polylineBottom); }
					if (polylineLeft) { self.map.removeOverlay(polylineLeft); }
				}
				
				polylineTop = new GPolyline([startPoint,rightPoint],self.defaultTrackColor,2,1);
				polylineRight = new GPolyline([rightPoint,endPoint],self.defaultTrackColor,2,1);
				polylineBottom = new GPolyline([endPoint,leftPoint],self.defaultTrackColor,2,1);
				polylineLeft = new GPolyline([leftPoint,startPoint],self.defaultTrackColor,2,1);

				self.map.addOverlay(polylineTop);
				self.map.addOverlay(polylineRight);
				self.map.addOverlay(polylineBottom);
				self.map.addOverlay(polylineLeft);

			});
			GEvent.removeListener(clickMap);
			
		});

	}
	
	
	this.deleteTrackPoints = function(trackId,bounds) {
		var self = Edit;
		
		track = self.tracks[trackId];
		var num = 0;
		var newStartMarker;
		var newEndMarker;

		if(track) {
			var newPoints = [];
			var newEles = [];
			var newTrackPoints = [];
			var newPolyline;

			trackName = track['trackName'];
			trackInfo = track['trackInfo'];
			trackLength = track['trackLength'];

			var totalDistance = 0;

			trackPoints = track['points'];
			eles = track['eles'];
			for(var i = 0; i<trackPoints.length; i++) {
				point = trackPoints[i];
				ele = eles[i];
				if(bounds.contains(point)) {
					num++;
				} else {
					var newTrackPoint = [];
					newPoints.push(point);
					newEles.push(ele);
				}
			}
			

			/*
			for(var i = 0; i<newPoints.length; i++) {
			// get new length
					thisPoint = newPoints[i];

					nextPoint = newPoints[i+1];
					if(nextPoint) {
						lastLat = thisPoint.lat();
						newLat = nextPoint.lat();
						lastLon = thisPoint.lng();
						newLon = nextPoint.lng();

						x = 69.1 * (newLat - lastLat);
						y = 69.1 * (newLon - lastLon) * Math.cos(lastLat/57.3);
						dist = Math.sqrt(x*x + y*y) // distance in miles
						meters = dist/0.000621371192;
						totalDistance += meters;
					}
			}

			if(self.user['lengthUnit'] == "english") {
				// meters to miles
				totalDistance = Math.round(totalDistance * 0.000621371192 * 10)/10;
			} else if(self.user['lengthUnit'] == "metric") {
				totalDistance = Math.round(totalDistance/1000*10)/10;
			}	*/

			newPolyline = self.createTrack(newPoints,self.defaultPolygonColor,2);
			/*
			if(newPoints.length > 0) {
				newStartPoint = newTrackPoints[0]['trackPoint'];
				newEndPoint = newTrackPoints[newTrackPoints.length-1]['trackPoint'];
		

				newStartMarker = self.createPin("track",newStartPoint,trackName,trackInfo,totalDistance,trackStartIcon,"beginning of track");
				newEndMarker = self.createPin("track",newEndPoint,trackName,trackInfo,totalDistance,trackEndIcon,"end of track");

			}
			*/

			/* Remove old overlays */
			/*
			oldStartMarker = track['startMarker'];
			oldEndMarker = track['endMarker'];
			*/
			

			oldPolyline = track['polyline'];
			if (oldPolyline) { self.map.removeOverlay(oldPolyline); }
			
			/*
			if(oldStartMarker) {
				if (oldStartMarker) { self.map.removeOverlay(oldStartMarker); }
			}
			if(oldEndMarker) {
				if (oldEndMarker) { self.map.removeOverlay(oldEndMarker); }
			}
			*/

			/* add new overlays */
			if(newPoints.length > 0) {
				self.map.addOverlay(newPolyline);
				// track['polyline'] = newPolyline;
			}
			/*
			if(newStartMarker) {
				self.map.addOverlay(newStartMarker);
			}
			if(newEndMarker) {
				self.map.addOverlay(newEndMarker);
			}*/

			/* update Array */
			
		 
			
		//	 self.tracks[trackId]['trackLength'] = totalDistance;
			self.tracks[trackId]['points'] = newPoints;
			self.tracks[trackId]['eles'] = newEles;
			self.tracks[trackId]['polyline'] = newPolyline;


			//self.updateTrackRow(trackId,trackName,totalDistance)

		}
	}
	
	this.editTrack = function(trackId) {
		var self = Edit;

		/*
		var nameCell = document.getElementById('track'+trackId+'name');
		var html = nameCell.innerHTML;
		
		//self.mapDiv.style.cursor = 'wait';
		
  

		if(self.currEditedTrack == null) {
			self.currEditedTrack = trackId;
			nameCell.innerHTML = "<input id='track"+trackId+"nameEdit' value='"+html+"'><input type=button onclick='Edit.updateTrack("+trackId+")' value='ok'>";
			

			
		 //  self.editDiv.innerHTML = "<input type=button value='add points' onclick='Edit.editTrackLine("+trackId+");'> <input type=button value='trim points' onclick='Edit.trimTrack("+trackId+");'>";



		}
			*/


	}

	this.editTrackLine = function(trackId) {
		var self = Edit;
		var track = self.tracks[trackId];
		if (!track) { return false; }
		
		self.stopEditTrack();
		var type = "track";
		
		if(track['isPolygon']) {
			type = "area";
		}

		
		self.helpText = "Click to start drawing a " + type;
		self.addMouseEvents();

		self.currTrack = trackId;
		self.currTrackId = trackId;

		/* change to polyline from polygon if needed */
		if(track['isPolygon']) {
			if (track['polyline']) { self.map.removeOverlay(track['polyline']); }
			track['polyline'] = new GPolyline(track['points'],self.defaultPolygonColor,2,1);
			self.map.addOverlay(track['polyline']);
		
		}

		self.addTrackMarkers(trackId);
		self.drawTrack();

	}

	this.addTrackRow = function(trackId) {
		var self = Edit;
		
		track = self.tracks[trackId];
		trackName = track['name'];
		
		self.tracksTable.insertRow(self.tracksTable.rows.length);
		var row = self.tracksTable.rows[self.tracksTable.rows.length-1];

		 /*
		var cell = row.insertCell(0);
		cell.innerHTML = "<input type=button value='add points' onclick='Edit.editTrack("+trackId+");'>";
		var cell = row.insertCell(1);
		cell.innerHTML = "<input type=button value='trim points' onclick='Edit.trimTrack("+trackId+");'>";
		*/

		var cell = row.insertCell(0);
		cell.innerHTML = "<input type=button value='edit' onclick='Edit.editTrack("+trackId+");'>";
		var cell = row.insertCell(1);
		cell.id = 'track'+trackId+'name';
		cell.innerHTML = trackName;

 //  cell.innerHTML = "<img src='"+image+"' width='<?=$img_width?>'>";



	}
	
	this.createTrack = function(points,trackColor,isPolygon,weight) {
		var self = Edit;
		var weight = weight || 2;
		var opacity = 0.9;
		/*
		var trackPoints = [];
		for(var i=0;i<points.length;i++) {
			var point = points[i];
			var trackPoint = point['trackPoint'];
			trackPoints.push(trackPoint);
		}
		*/
		
		var polyline = null;

		if(points.length > 0) {
			if(isPolygon) {
				polyline = new GPolygon(points,self.defaultPolygonColor,2,0.6,self.defaultPolygonColor,0.25);
			} else {
				polyline = new GPolyline(points,self.defaultTrackColor,2,opacity);
			}
			self.map.addOverlay(polyline);
		} else {
			var polyline = null;
		}
		return polyline;
	}
	this.addTempTrack = function(points,trackName,trackInfo,isPolygon,trackColor,trackLength,eles) {
		var self = Edit;

		var trackId = self.numTempTracks;
		var trackLength = trackLength || 0;
		var startMarker;
		var endMarker;

		var track = [];
		track['points'] = points;
		track['name'] = trackName;
		track['info'] = trackInfo;
		track['trackLength'] = trackLength;
		//track['db'] = trackDB;
		track['markers'] = [];
		track['eles'] = eles;
	
		track['isPolygon'] = isPolygon;
		
		self.tempTracks[trackId] = track;
		
		var type = "track";
		if(isPolygon) type = "area";
		//self.addElementRow(type,trackId);
		// self.addTrackRow(trackId);

		polyline = self.createTrack(points,trackColor,isPolygon);
		self.tempTracks[trackId]['polyline'] = polyline;
		//self.addTrackRow(trackId,trackName,trackColor,trackLength,showTrack);
	  
		if(polyline) {
			self.map.addOverlay(polyline);
		}


		self.numTempTracks++;
	}
	
	this.addTrack = function(points,trackName,trackInfo,isPolygon,trackColor,trackLength,eles) {
		var self = Edit;

		

		var trackId = self.numTracks;
		var trackLength = trackLength || 0;
		var startMarker;
		var endMarker;

		var track = [];
		track['points'] = points;
		track['name'] = trackName;
		track['info'] = trackInfo;
		track['trackLength'] = trackLength;
		//track['db'] = trackDB;
		track['markers'] = [];
		track['eles'] = eles;
		track['finished'] = true;
	
		track['isPolygon'] = isPolygon;
		
		self.tracks[self.numTracks] = track;
		
		var type = "track";
		if(isPolygon) type = "area";
		self.addElementRow(type,trackId);
		// self.addTrackRow(trackId);

		polyline = self.createTrack(points,trackColor,isPolygon);
		self.tracks[trackId]['polyline'] = polyline;
		//self.addTrackRow(trackId,trackName,trackColor,trackLength,showTrack);
	  
		if(polyline) {
			self.map.addOverlay(polyline);
		}
		if(startMarker) {
			self.map.addOverlay(startMarker);
		}
		if(endMarker) {
			self.map.addOverlay(endMarker);
		} 

		self.numTracks++;
		self.madeEdit();
		
	}

	this.zoomFit = function() {
		var self = Edit;

		var bounds = self.getBounds();

		zoom = self.map.getBoundsZoomLevel(bounds);
		if(zoom > 17) { zoom = 17; }
		center = bounds.getCenter();
		self.map.setCenter(center,zoom);
	}
	
	
	this.makeSaveQuery = function() {
		var self = Edit;
		
		var query = "";
		
		/* format tracks */
		n = 0;
		for(var i=0; i<self.tracks.length; i++) {
			track = self.tracks[i];

			if(track) {
				trackPoints = track['points'];
				trackName = track['name'];
				// trackName = trackName.replace('&','');
				trackLength = track['trackLength'];
				showTrack = track['showTrack'];
				isPolygon = track['isPolygon'];
				trackType = "track";
				if(isPolygon) { trackType = "area"; }

				query += "&tracks["+n+"][trackName]="+URIEscape(trackName);
				query += "&tracks["+n+"][trackLength]="+trackLength;
				query += "&tracks["+n+"][showTrack]="+showTrack;
				query += "&tracks["+n+"][trackType]="+trackType;

				m = 0;

				for(var j=0; j < trackPoints.length; j++) {
					point = trackPoints[j];
					lat = point.lat();
					lon = point.lng();
					ele = '';

					query += "&tracks["+n+"][points]["+m+"][lat]="+lat;
					query += "&tracks["+n+"][points]["+m+"][lon]="+lon;
					query += (ele != '') ? "&tracks["+n+"][points]["+m+"][ele]="+ele : '';

					m++;
				}
				n++;
			}
		}
		
		/* format waypoints */
		for(var i=0; i<self.waypoints.length; i++) {
			waypoint = self.waypoints[i];

			if(waypoint) {
				lat = waypoint['lat'];
				lon = waypoint['lon'];
				name = waypoint['name'];
				if(name) {
					// name = name.replace('&','%26');
				}
				desc = waypoint['desc'];
				if(desc) {
					// desc = desc.replace('&','%26');
				}

				query += "&waypoints["+i+"][name]="+URIEscape(name);
				query += "&waypoints["+i+"][desc]="+URIEscape(desc);
				query += "&waypoints["+i+"][lat]="+lat;
				query += "&waypoints["+i+"][lon]="+lon;
			}
		}
		
		/* bounds info */
		var bounds = self.getBounds();
		var ne = bounds.getNorthEast();
		var sw = bounds.getSouthWest();
		var center = bounds.getCenter();
		
		query += "&trip_center_lat="+center.lat();
		query += "&trip_center_lon="+center.lng();
		query += "&trip_min_lat="+sw.lat();
		query += "&trip_min_lon="+sw.lng();
		query += "&trip_max_lat="+ne.lat();
		query += "&trip_max_lon="+ne.lng();

		return query;
	}
	
	
	this.debug = function(text) {
		if (Edit.debugBox) { Edit.debugBox.innerHTML = text; }
	}
	
	/*
	this.updateTrack = function() {
		var self = Edit;

		if (self.currTrackLine) { self.map.removeOverlay(self.currTrackLine); }
		self.map.addOverlay(self.currTrackLine);
	}	*/

	this.finishTrack = function(trackId) {
		var self = Edit;
		
		var track = self.tracks[trackId];
		if(track) {
			track['finished'] = true;
		}

	}

	this.checkSaveTrack = function(e) {
		var self = Edit;
		
		alert("s");
	}

	this.addPointToTrack = function(point) {
		var self = Edit;
		var newPoint = [];
		var track = self.tracks[self.currTrackId];
		self.tracks[self.currTrackId]['points'].push(point);
		self.tracks[self.currTrackId]['eles'].push(self.getEleFromPoint(point));

		var marker = new GMarker(point,{draggable:true,icon:self.trackIcon,dragCrossMove:false,bouncy:false});
		self.tracks[self.currTrackId]['markers'].push(marker);

		var num = self.tracks[self.currTrackId]['points'].length-1;
		
		var type = "track";
		if(track['isPolygon']) {
			type = "area";
		}

		if(num == 0) {
			self.helpText = "Click to continue drawing a " + type;
		} else {
			if(type == "track") {
				self.helpText = "click again on the last point to end this " + type;
			} else {
				self.helpText = "click on the first point to end this " + type;
			}
		}

		GEvent.addListener(marker,"drag",function(point) {
			self.tracks[self.currTrackId]['points'][num] = marker.getPoint();
			self.tracks[self.currTrackId]['eles'][num] = self.getEleFromPoint(marker.getPoint());

			if (self.tracks[self.currTrackId]['polyline']) { self.map.removeOverlay(self.tracks[self.currTrackId]['polyline']); }

			if(self.tracks[self.currTrackId]['isPolygon']) {
				color = self.defaultPolygonColor;
			} else {
				color = self.defaultTrackColor;
			}

			self.tracks[self.currTrackId]['polyline'] = new GPolyline(self.tracks[self.currTrackId]['points'],color,2,1);

			self.madeEdit();
			self.map.addOverlay(self.tracks[self.currTrackId]['polyline']);

		//	self.updateTrack();

		
		});

		GEvent.addListener(marker,"click",function(point) {
			if(num == self.tracks[self.currTrackId]['points'].length-1) {
				
				
				/* open info window to name track */
				if(track['points'].length > 0) {
					//self.trackMarker = new GMarker(track['points'][track['points'].length-1]);

					var type = "track";
					if(track['isPolygon']) type = "area";

					var html = type + " name<br><input id='trackEditedName' type='text' value='new "+type+"' onfocus='this.select()'><input type='button' onclick='Edit.updateTrackName("+self.currTrackId+");Edit.madeEdit();' value='ok'>";
					
					textField = document.getElementById('trackEditedName');
								//onfocus='this.select();'

					// self.map.addOverlay(self.trackMarker);
					//self.trackMarker.openInfoWindowHtml(html);
					self.map.openInfoWindowHtml(track['points'][track['points'].length-1],html);
					textField = document.getElementById('trackEditedName');
					if(textField) {
						textField.onkeypress = function(e) {
							if (!e) e = window.event;
							if (e.keyCode == 13) {
								Edit.updateTrackName(self.currTrackId);
								Edit.madeEdit();
							}
						};
					}
					
				 //  GEvent.addListener(self.trackMarker,"click",function() {
					// self.trackMarker.openInfoWindowHtml(html);
					//  self.map.openInfoWindowHtml(track['points'][track['points'].length-1],html);
					// });
				}

				GEvent.removeListener(self.endTrackListener);
				self.stopEditTrack(true);
				return;
			}
			self.addPointToTrack(marker.getPoint());
			
			if(num == 0) {
				
				/* open info window to name track */
				if(track['points'].length > 0) {
					// self.trackMarker = new GMarker(track['points'][track['points'].length-1]);
					
					var type = "track";
					if(track['isPolygon']) type = "area";
					
					var html = type + " name<br><input id='trackEditedName' value='new "+type+"' onfocus='this.select();'><input type=button onclick='Edit.updateTrackName("+self.currTrackId+");Edit.madeEdit();Edit.finishTrack("+self.currTrackId+");' value='ok'>";
					//self.map.addOverlay(self.trackMarker);
					//self.trackMarker.openInfoWindowHtml(html);
					self.map.openInfoWindowHtml(track['points'][track['points'].length-1],html);
					textField = document.getElementById('trackEditedName');
					if(textField) {
						textField.onkeypress = function(e) {
							if (!e) e = window.event;
							if (e.keyCode == 13) {
								Edit.updateTrackName(self.currTrackId);
								Edit.madeEdit();
							}
						};
					}
					
				// GEvent.addListener(self.trackMarker,"click",function() {
						//self.trackMarker.openInfoWindowHtml(html);
					//	self.map.openInfoWindowHtml(track['points'][track['points'].length-1],html);
				 //  });
				}
				
				GEvent.removeListener(self.endTrackListener);
				self.stopEditTrack(true);
			}
		});
		
		self.map.addOverlay(marker);
		var polyline = null;
		
		if(self.tracks[self.currTrackId]['isPolygon']) {
			color = self.defaultPolygonColor;
		} else {
			color = self.defaultTrackColor;
		}
		polyline = new GPolyline(self.tracks[self.currTrackId]['points'],color,2,0.75);
		
		if (self.tracks[self.currTrackId]['polyline']) { self.map.removeOverlay(self.tracks[self.currTrackId]['polyline']); }
		self.tracks[self.currTrackId]['polyline'] = polyline;
		self.map.addOverlay(self.tracks[self.currTrackId]['polyline']);
		//self.debug(self.currTrackPoints.length);
		
	}


	this.addNewWaypoint = function() {
		var self = Edit;
		
		self.stopEditTrack(true,true);
		if (self.trackMarker) { self.map.removeOverlay(self.trackMarker); }

		track = self.tracks[self.currTrackId];
		if(track && (track['points'].length == 0 || track['finished'] != true)) {
			self.removeTrackMarkers(self.currTrackId);
			self.deleteTrack(self.currTrackId);
		}
		
		self.helpText = "click to add a new marker";
		self.addMouseEvents();
		
		if(self.addWaypointEvent) {
			GEvent.removeListener(self.addWaypointEvent);
		}
		
		self.addWaypointEvent = GEvent.addListener(self.map,"click", function(marker,point) {
			self.placeNewMarker(point);
		});
		
	}
	
	this.placeNewMarker = function(pt) {
		var self = Edit;
		if (pt) {
			var id = self.addWaypoint(pt.lat(),pt.lng(),0,"new marker","");
			self.editWaypoint(id);
		}
		if (!self.stayInWaypointMode) {
			GEvent.removeListener(self.addWaypointEvent);
			self.addWaypointEvent = null;
			self.removeMouseEvents();
			self.highlightButton('none');
		}
	}

	this.addNewTrack = function(isPolygon) {
		var self = Edit;
		var points = [];
		var eles = [];

		if (self.trackMarker) { self.map.removeOverlay(self.trackMarker); }
		
		trackName = "new track";
		if(isPolygon) {
			trackName = "new area";
		}
		
		if(self.addWaypointEvent) {
			GEvent.removeListener(self.addWaypointEvent);
		}

		track = self.tracks[self.currTrackId];
		if(track && (track['points'].length == 0 || track['finished'] != true)) {
			self.removeTrackMarkers(self.currTrackId);
			self.deleteTrack(self.currTrackId);
		}

		self.addTrack(points,trackName,"track info",isPolygon,self.defaultPolygonColor,0,eles);
		self.editTrack(self.numTracks-1);

		self.editTrackLine(self.numTracks-1);
	}

	this.drawTrack = function() {
		var self = Edit;
		self.drawingTrack = true;

		self.clickListener = GEvent.addListener(self.map,"click",function(marker,point) {
			if(!marker) {
				self.addPointToTrack(point);
			}

		});

		self.endTrackListener = GEvent.addListener(self.map,"dblclick",function(point,src,overlay) {
			self.drawingTrack = false;
			var track = self.tracks[self.currTrackId];

			/* open info window to name track */
			if(track['points'].length > 0) {
				self.trackMarker = new GMarker(track['points'][track['points'].length-1]);

				var type = "track";
				if(track['isPolygon']) type = "area";

				var html = type + " name<br><input id='trackEditedName' value='new "+type+"' onfocus='this.select()'><input type=button onclick='Edit.updateTrackName("+self.currTrackId+");Edit.madeEdit();' value='ok'>";

				//self.map.addOverlay(self.trackMarker);
				//self.trackMarker.openInfoWindowHtml(html);

				textField = document.getElementById('trackEditedName');
				// self.map.addOverlay(self.trackMarker);
				// self.trackMarker.openInfoWindowHtml(html);
				self.map.openInfoWindowHtml(track['points'][track['points'].length-1],html);
				textField = document.getElementById('trackEditedName');
				if(textField) {
					textField.onkeypress = function(e) {
						if (!e) e = window.event;
						if (e.keyCode == 13) {
							Edit.updateTrackName(self.currTrackId);
							Edit.madeEdit();
						}
					};
				}
				
				GEvent.addListener(self.trackMarker,"click",function() {
					// self.trackMarker.openInfoWindowHtml(html);
					self.map.openInfoWindowHtml(track['points'][track['points'].length-1],html);
				});
			}
			
			GEvent.removeListener(self.endTrackListener);
			self.stopEditTrack();
			
		});
		

	}
	
	this.getBounds = function() {
		var self = Edit;
		var bounds = new GLatLngBounds();

		for(i=0; i<self.tracks.length;i++) {
			var track = self.tracks[i];
			if(track) {

				for(j=0;j<track['points'].length;j++) {
					var point = track['points'][j];
					bounds.extend(point);
				}
			}
		}
		
		for(i=0; i<self.waypoints.length;i++) {
			var waypoint = self.waypoints[i];
			if(waypoint) {
				bounds.extend(new GLatLng(waypoint['lat'],waypoint['lon']));
			}
		}

		return bounds;
	}
	
	
	this.hideMapData = function() {
		var self = Edit;
		
		for(i=0; i<self.numTempTracks;i++) {
			track = self.tempTracks[i];
			if(track) {
				if (track['polyline']) { self.map.removeOverlay(track['polyline']); }
				self.tempTracks[i] = null;
			}
		}
		
		for(i=0; i<self.numTempWaypoints;i++) {
			waypoint = self.tempWaypoints[i];
			if(waypoint) {
				if (waypoint['marker']) { self.map.removeOverlay(waypoint['marker']); }
				self.tempWaypoints[i] = null;
			}
		}
	}
	this.showMapData = function(xml) {
		var self = Edit;
		

		self.hideMapData();

		/* Get Tracks */
		res = [];
		res = XMLParse.xml2ObjArray(xml,'trk');
		trk = xml.getElementsByTagName('trk');
		for(var i = 0; i < res.length; i++) {
			var track = [];

			trackName = res[i].name;
			trackType = res[i].trackType;
			trackInfo = res[i].desc;
			trackLength = res[i].length;
			trackTags = res[i].tags || "";
			trackDB = res[i].track_id;
			res2 = XMLParse.xml2ObjArray(trk[i],'trkpt');
			points = [];
			eles = [];
			for(var j = 0; j < res2.length; j++) {

				lat = res2[j].lat;
				lon = res2[j].lon;
				ele = res2[j].ele;
				time = res2[j].time;
				point = new GLatLng(lat,lon,true);
				/*
				points['trackPoint'] = point;
				points['trackLat'] = lat;
				points['trackLon'] = lon;
				points['trackEle'] = ele; */
				eles.push(ele);
				points.push(point);
				track.push(points);
			} 

			isPolygon = false;
			if(trackType == "area") isPolygon = true;

			self.addTempTrack(points,trackName, trackInfo,isPolygon,self.defaultPolygonColor,trackLength,eles);
		}

		/* Get Waypoints */
		res = [];
		res = XMLParse.xml2ObjArray(xml,'wpt');
		var waypoints = [];
		for(var i = 0; i < res.length; i++) {
			lat = res[i].lat;
			lon = res[i].lon;
			ele = res[i].ele;
			name = res[i].name;
			desc = res[i].desc;
			waypointDB = res[i].waypoint_id
			tags = res[i].tags || "";

			self.addTempWaypoint(lat,lon,ele,name,desc);
		}
		
		
	}	
	
	this.imageDimensions = function(imgSrc) {
		var newImg = new Image();
		newImg.src = imgSrc;
		var height = newImg.height;
		var width = newImg.width;

		var dim = [];
		dim['height'] = height;
		dim['width'] = width;

		return dim;
	}
	
	this.removeHelpDiv = function() {
		var self = Edit;
		
		var div = document.getElementById('helpDiv');
		if(div) {
			self.mapDiv.removeChild(div);
		}

	}
	
	this.addHelpDiv = function(text,point) {
		var self = Edit;
		
		var div = document.createElement('div');
		div.id = 'helpDiv';
		div.innerHTML = text;
		div.style.position = 'absolute';
		div.style.top = point.y + 'px';
		div.style.left = point.x + 'px';
		div.style.zIndex = 110;
		div.style.border = "1px solid #999999";
		div.style.backgroundColor = "#DDDDDD";
		div.style.padding = '2px';
		
		self.mapDiv.appendChild(div);

	}
	
	this.madeEdit = function() {
		var self = Edit;
		
		if(self.waypoints.length + self.numTracks > 0) {
			self.wasEdited = true;
			// document.getElementById('continueButton1').disabled = false;
			// document.getElementById('continueButton2').disabled = false;
		}	
	}
	
	this.hideEditMarker = function() {
		var self = Edit;
		if (self.editMarker) { if(self.editMarker) self.map.removeOverlay(self.editMarker); }
	}
	
	this.deleteWaypoint = function(waypointId) {
		var self = Edit;
		var waypoint = self.waypoints[waypointId];
		self.madeEdit();
		
		var marker = waypoint['marker'];
		
		/* delete row */
		var row = document.getElementById("marker"+waypointId+"row");
		self.elementsTable.deleteRow(row.rowIndex);
		
		if (marker) { self.map.removeOverlay(marker); }
		
		// self.waypoints[waypointId] = null;
//for (w1 in self.waypoints) { alert ('w1 = '+w1); }
//alert ('self.waypoints.length = '+self.waypoints.length);
		self.waypoints.splice(waypointId,1);
//for (w2 in self.waypoints) { alert ('w2 = '+w2); }
//alert ('self.waypoints.length = '+self.waypoints.length);
		self.map.closeInfoWindow();
	}
	
	this.deleteTrack = function(trackId) {
		var self = Edit;
		var track = self.tracks[trackId];
		self.removeTrackMarkers(trackId);
		if (self.clickListener) {
			GEvent.removeListener(self.clickListener);
		}
		self.removeMouseEvents();
		
		var polyline = track['polyline'];
		var type = "track";
		if(track['isPolygon']) {
			type = "area";
		}
		
		/* delete row */
		var row = document.getElementById(type+trackId+"row");
		self.elementsTable.deleteRow(row.rowIndex);
		if (polyline) { self.map.removeOverlay(polyline); }
		
		self.tracks[trackId] = null;
		
		self.map.closeInfoWindow();
	}
	
	this.showInfo = function(type,id) {
		var self = Edit;
		var marker = null;
		self.hideEditMarker();
		var html = "";

		if(type == "marker") {
			marker = self.waypoints[id]['marker'];
			elementName = self.waypoints[id]['name'];
			img = "";
			html = "<input value='"+elementName+"' id='currWaypointName'><input type=button value='ok' onclick='Edit.updateWaypointName("+id+")'><br><a href='javascript:Edit.deleteWaypoint("+id+");'>Delete</a>";
			 marker.openInfoWindow(html);
		} else if(type == "track") {
			marker = new GMarker(self.tracks[id]['points'][0]);
			self.editMarker = marker;
			elementName = self.tracks[id]['name'];
			img = "";
			html = "<input value='"+elementName+"' id='trackEditedName'><input type=button value='ok' onclick='Edit.updateTrackName("+id+");Edit.stopEditTrack();'><br><a href='javascript:Edit.editTrackLine("+id+");'>Edit line</a> | <a href='javascript:Edit.deleteTrack("+id+");'>Delete</a>";
			//self.map.addOverlay(marker);
			self.map.openInfoWindowHtml(self.tracks[id]['points'][0],html);
		} else if(type == "area") {
			marker = new GMarker(self.tracks[id]['points'][0]);
			self.editMarker = marker;
			elementName = self.tracks[id]['name'];
			img = "";
			html = "<input value='"+elementName+"' id='trackEditedName'><input type=button value='ok' onclick='Edit.updateTrackName("+id+");Edit.stopEditTrack();'><br><a href='javascript:Edit.editTrackLine("+id+");'>Edit area</a> | <a href='javascript:Edit.deleteTrack("+id+");'>Delete</a>";
			//self.map.addOverlay(marker);
			
			self.map.openInfoWindowHtml(self.tracks[id]['points'][0],html);
		}



		
		if(type != "marker") {
			GEvent.addListener(marker,"infowindowclose",function() {
				// if (marker) { self.map.removeOverlay(marker); }
			});
		}
		


	}

	this.addElementRow = function(type,id) {
		var self = Edit;
		
		self.elementsTable.insertRow(self.elementsTable.rows.length);
		var row = self.elementsTable.rows[self.elementsTable.rows.length-1];
		row.vAlign = 'top';
		row.id = type+id+"row";

		var elementName = "";
		var img = "";
		var link = "";

		if(type == "marker") {
			elementName = self.waypoints[id]['name'];
			img = "images/add_marker_img.png";
		} else if(type == "track") {
			elementName = self.tracks[id]['name'];
			img = "images/add_line_img.png";
		} else if(type == "area") {
			elementName = self.tracks[id]['name'];
			img = "images/add_area_img.png";
		}


		var cell = row.insertCell(0);
		cell.innerHTML = '<a href="javascript:Edit.showInfo(\''+type+'\','+id+');" style="cursor:pointer;"><img src="'+img+'" border="0"></a>';
		var cell = row.insertCell(1);
		cell.id = type+id+'name';
		cell.innerHTML = '<a href="javascript:Edit.showInfo(\''+type+'\','+id+');" style="cursor:pointer;">'+elementName+'</a>';

	}


	this.saveKML = function() {
		var self = Edit;

		var query = self.makeSaveQuery();
		self.ajax.doPost('saveKML.php',query, self.saveResponse,"text");

	}
	
	this.saveGPX = function() {
		var self = Edit;
		var query = self.makeSaveQuery();
		self.ajax.doPost('saveGPX.php',query, self.saveResponse,"text");
	}
	
	this.saveResponse = function(file) {
		var self = Edit;
		window.open ("download_file.php?file="+file,"downloadFrame","status=0,toolbar=0,location=0,menubar=0,resizable=1,width=200,height=50");
	}


}


function Sandbox_Initialize_Marker_Tooltip(map,id) {
	var tt = document.createElement('div');
	tt.id = id;
	tt.style.visibility = 'hidden';
	tt.style.color = '#000000';
	tt.style.backgroundColor = '#FFFFFF';
	tt.style.border = '1px solid #666666';
	tt.style.font = '10px Verdana,sans-serif';
	tt.style.whiteSpace = 'nowrap';
	tt.style.padding = '2px';
	map.getPane(G_MAP_FLOAT_PANE).appendChild(tt);
	return (tt);
}

function Sandbox_Create_Marker_Tooltip(map,marker,text) {
	// copied almost verbatim from http://www.econym.demon.co.uk/googlemaps/tooltips4.htm
	marker_tooltip.innerHTML = text;
	var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
	var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
	var anchor=marker.getIcon().iconAnchor;
	var width=marker.getIcon().iconSize.width;
	var height=marker_tooltip.clientHeight;
	offset.x += 1; offset.y += 6; // a little adjustment
	height = 18; // makes all tooltips hover near the mouse, even if they're tall and have thumbnails or whatnot (they expand downward instead of upward)
	var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height)); 
	pos.apply(marker_tooltip);
	marker_tooltip.style.visibility = 'visible';
}

function Sandbox_Show_Link() {
	var url = document.location.toString().replace(/\/[\?\#].*$/,'/');
	var type_menu = $('gv_map_selector'); var type = type_menu[type_menu.selectedIndex].value;
	if (type == 'G_NORMAL_MAP') { type = 'm'; }
	else if (type == 'G_HYBRID_MAP') { type = 'h'; }
	else if (type == 'G_SATELLITE_MAP') { type = 's'; }
	else if (type == 'MYTOPO_TILES') { type = 't'; }
	else if (type == 'OPENSTREETMAP_TILES') { type = 'osm'; }
	else if (type == 'OPENCYCLEMAP_TILES') { type = 'ocm'; }
	url += '?type='+type;
	url += '&zoom='+gmap.getZoom();
	url += '&center='+parseFloat(gmap.getCenter().lat().toFixed(6))+','+parseFloat(gmap.getCenter().lng().toFixed(6));
	url += '&note=';
	var window_html = "<div style='width:300px; margin-bottom:8px;'>The following URL will take you back to this viewport; note that any tracks or waypoints you've added will not be included.<br><br>(If you want to add a note in an 'info bubble', you can add <tt>note=YOUR_NOTE_HERE</tt> to the URL.)</div>";
	window_html += '<input id="gv_sandbox_url_box" type="text" size=40 value="'+url.replace(/"/g,"&quot;")+'">';
	gmap.openInfoWindowHtml(gmap.getCenter(),window_html);
	window.setTimeout('$("gv_sandbox_url_box").focus(); $("gv_sandbox_url_box").select();',100);
}

function selectText() {
	if (!arguments) { return false; }
	deselectText();
	if (document.selection) {
		for (j=0; j<arguments.length; j++) {
			var range = document.body.createTextRange();
			range.moveToElementText(document.getElementById(arguments[j]));
			range.select();
		}
	} else if (window.getSelection) {
		for (j=0; j<arguments.length; j++) {
			var range = document.createRange();
			range.selectNode(document.getElementById(arguments[j]));
			window.getSelection().addRange(range);
		}
	}
}
function deselectText() {
	if (document.selection) {
		document.selection.empty();
	} else if (window.getSelection) {
		window.getSelection().removeAllRanges();
	}
}			

function URIEscape(text) {
	text = escape(text);
	text = text.replace(/\//g,"%2F");
	text = text.replace(/\?/g,"%3F");
	text = text.replace(/=/g,"%3D");
	text = text.replace(/&/g,"%26");
	text = text.replace(/@/g,"%40");
	text = text.replace(/\\?"/g,"%22");
	return (text);
}

function decimalCoordinate(coordinate) {
	coordinate = coordinate.toString();
	coordinate = coordinate.replace(/(^\s+|\s+$)/g,''); // remove white space
	var neg = 0; if (coordinate.match(/(^-|[WS])/i)) { neg = 1; }
	coordinate = coordinate.replace(/[NESW\-]/gi,' ');
	if (!coordinate.match(/[0-9]/i)) {
		return '';
	}
	parts = coordinate.match(/([0-9\.\-]+)[^0-9\.]*([0-9\.]+)?[^0-9\.]*([0-9\.]+)?/);
	if (!parts || parts[1] == null) {
		return '';
	} else {
		n = parseFloat(parts[1]);
		if (parts[2]) { n = n + parseFloat(parts[2])/60; }
		if (parts[3]) { n = n + parseFloat(parts[3])/3600; }
		if (neg && n >= 0) { n = 0 - n; }
		n = Math.round(10000000 * n) / 10000000;
		if (n == Math.floor(n)) { n = n + '.0'; }
		return n;
	}
}
