﻿function getPolylineCenter(pts){
	var mid;
	var lat=0,lng=0;
	var lat2, lng2;
	if(pts.length > 1){
		if(pts.length == 2){
			lat = (pts[0].lat() / 2) + (pts[1].lat() / 2);
			lng = (pts[0].lng() / 2) + (pts[1].lng() / 2);
		}else if(pts.length > 2){
			// mid point of first and last points
			lat2 = (pts[0].lat() / 2) + (pts[pts.length-1].lat() / 2);
			lng2 = (pts[0].lng() / 2) + (pts[pts.length-1].lng() / 2);
			
			mid = Math.floor(pts.length / 2);
			
			lat = (lat2 / 2) + (pts[mid].lat() / 2);
			lng = (lng2 / 2) + (pts[mid].lng() / 2);
		}
	}
	return (new google.maps.LatLng(lat, lng));
}

function PSStreet(id, name, active, photo, polyline, userid, clickable){
	this.id = id;
	this.name = name;
	this.active = active;
	this.photo = photo;
	this.polyline = polyline;
	this.userid = userid;
	this.clickable = clickable;
	this.isowner = false;
	this.added = false;
}

// container: map div id, mode:'viwer' or 'editor'
function PSMap(container, mode)
{
//	var LINECOLOR_ACTIVE = {color:"#1432EB",opacity:0.4};
//	var LINECOLOR_INACTIVE = {color:"#323232",opacity:0.4};
//	var LINECOLOR_HOT = {color:"#FF0000",opacity:0.4};
	var LINECOLOR_ACTIVE = {color:"#0033CC", opacity:0.6, weight:4};
	var LINECOLOR_INACTIVE = {color:"#0099FF", opacity:0.6, weight:4};
	var LINECOLOR_INACTIVE_NOPHOTO = {color:"#303030", opacity:0.6, weight:4};
	var LINECOLOR_ON = {color:"#FF3300", opacity:0.7};
	var LINECOLOR_HOT = {color:"#FF9933", opacity:0.7};
	var LINECOLOR_REDRAWING = {color:"#333333", opacity:0.2, weight:4};

	this.container = container;
	this.map = new google.maps.Map2(document.getElementById(container));
	this.streets = [];
	this._markerGroups = ['editing','hot','search'];
	this.markers = [];
	this._clusterMarkers = [];
	this.mode = (mode && mode != undefined) ? mode : "viewer";
	this.isDrawing = false;
	this._drawingPts = null;
	this._drawingLine = null;
	this._editingStreet = -1;
	this._editingBusinessMarker = null;
	this._redrawingLine = -1;
	this.popupMenu = null;
	this.lastOverLine = null;
	this.activeStreet = -1;
	this.refreshTimer = null;
	this._draggingMarker = {marker:null,latlng:null};
	this._lastRequestId = 0;
	this._streetPosMarker = null;
	this._startPointMarker = null;
	this._mapControl = null;
	this._polylineOver = null;
	this._polylineTip = null;
	this._labels = [];
	this._clustered = false;
	this._spots = [];	
	this._videos = [];
	this.options = {navLabelControl:true};
	
	this.onPolylineCreated=function(street,distance){};
	this.onCancelDrawLine=function(){};
	this.onBeginDrawLine=function(){};
	this.onEditStreetLine=function(){};
	this.onCancelEditStreetLine=function(){};
	this.onMarkerPosChanged=function(id,latlng){};
	this.onMapMoved=function(){};
	this.onMapLabelClick=function(id){};
	this.onMapMarkerClick=function(type,id){};
	
	if(mode=="editor"){
		this.popupMenu = new PSEditorPopupMenu("pmstreet");
		this._drawingPts = new Array();
	}else{
		this.popupMenu = new PSPopupMenu("pmstreet");
	}
	var owner = this;
	var map = this.map;
	var request = null;

	var overStoreName = "";
	var overStoreAddress = "";
	
	this.indexOfPolyline = function(pobj){
		var result = -1;
		for(i = 0; i < this.streets.length; i++){
			if(this.streets[i].polyline == pobj){				
				result = i;
				break;
			}
		}
		return result;
	}
	this.indexOfId = function(id){
		var result = -1;
		for(var i = 0; i < this.streets.length; i++){
			if(this.streets[i].id == id){
				result = i;
				break;
			}
		}	
		return result;
	}
	// opts
	// navLabelControl:true/false
	this.init=function(lat, lng, zoom, opts){
		if(!zoom || zoom==undefined)
			zoom = 18;
			
		if(opts != undefined){
			for(var i in opts){
				this.options[i] = opts[i];
			}
		}
		this.initMarkers();

		this._mapControl = new google.maps.LargeMapControl3D();
		this.map.enableScrollWheelZoom();
		this.map.setMapType(G_NORMAL_MAP);
		this.map.addControl(this._mapControl);
		this.map.addControl(new google.maps.MapTypeControl());
		//this.map.addControl(new google.maps.SmallZoomControl3D());
		this.map.addControl(new google.maps.OverviewMapControl());
		if(this.options.navLabelControl)
			this.map.addControl(new google.maps.NavLabelControl(), new google.maps.ControlPosition(G_ANCHOR_TOP_LEFT, new google.maps.Size(70, 6)));
	//	gmap.setCenter(new google.maps.LatLng(37.520210226215575, 126.97474479675293),15);
		this.map.setCenter(new google.maps.LatLng(lat, lng), parseInt(zoom));

		mapLoaded();
		
		// events
		google.maps.Event.addListener(this.map, "click", mapOnClick);
		google.maps.Event.addListener(this.map, "singlerightclick", mapOnRightClick);
		google.maps.Event.addListener(this.map, "moveend", mapOnMoveEnd);
		google.maps.Event.addListener(this.map, "zoomend", mapOnZoomEnd);
		google.maps.Event.addListener(this.map, "dragstart", mapOnDragStart);
		//google.maps.Event.addListener(this.map, "mousemove", mapOnMouseMove);
		
		$("#"+this.container).mousemove(function(evt){
			if(owner.mode == "viewer"){
				if(owner._polylineOver && $('#'+owner.container+' .lineToolTip').length == 0){
					var idx = owner.indexOfPolyline(owner._polylineOver);
					var tooltip;
					if(idx != -1)
						tooltip = '<div class="lineToolTip">'+owner.streets[idx].name + ' &nbsp;<span class="distance">(' + parseInt(owner._polylineOver.getLength())+'m) &nbsp;</span><br /><span class="tip">Click to see the street photo &nbsp;</span></div>';
					else
						tooltip = '<div class="lineToolTip">Click here to see the street</div>';
					$('#'+owner.container).append(tooltip);
					var x = evt.pageX - parseInt($("#"+owner.container).offset().left);
					var y = evt.pageY - parseInt($("#"+owner.container).offset().top);					
					if(x > $('#'+owner.container).width() - $('#'+owner.container+' .lineToolTip').width() - 8)
						x = $('#'+owner.container).width() - $('#'+owner.container+' .lineToolTip').width() - 8;
					else x+=16;
					$('#'+owner.container+' .lineToolTip').css({left:x,top:y+16});
				}else if(!owner._polylineOver && $('#'+owner.container+' .lineToolTip').length > 0){				
					$('#'+owner.container+' .lineToolTip').remove();
				}
			}
		});
	}
	this.useLargeMapControl = function(){
		if(this._mapControl)
			this.map.removeControl(this._mapControl);
		this._mapControl = new google.maps.LargeMapControl3D();
		this.map.addControl(this._mapControl);
	}
	this.useSmallMapControl = function(){
		if(this._mapControl)
			this.map.removeControl(this._mapControl);
		this._mapControl = new google.maps.SmallZoomControl3D();
		this.map.addControl(this._mapControl);		
	}
	function mapOnDragStart(){
		if(owner.popupMenu) owner.popupMenu.hide();
	}
	function mapOnMouseMove(latlng){
		/*
		var pl,col;
		if(owner.isDrawing == true){
			map.getDragObject().setDraggableCursor("crosshair");
		}else{
			map.getDragObject().setDraggableCursor("url(http://maps.google.com/intl/en_us/mapfiles/openhand.cur),default");			
		}
		*/
	}
	function mapOnClick(overlay, latlng, overlaylatlng){
		// viewer
		if(owner.mode == "viewer"){
		// editor
		}else{
			if(owner.isDrawing == true && owner._editingStreet == -1){
				if(owner._drawingLine == null){ // begin drawing street line
					owner._drawingLine = new google.maps.Polyline(new Array(latlng), "#0000FF", 4, 0.5);
					map.addOverlay(owner._drawingLine);
					google.maps.Event.addListener(owner._drawingLine, "endline", owner.endDrawLine);
					google.maps.Event.addListener(owner._drawingLine, "cancelline", owner.cancelDrawLine);
					owner._drawingLine.enableDrawing({maxVertices:100,fromStart:true});
				}
			}else if(overlay){
			}
		} // editor
	}
	function polylineOnClick(latlng){
		// viewer
		if(owner.mode == "viewer"){
			var idx = owner.indexOfPolyline(this);
			if(idx != -1){
				owner.onStreetClick(owner.streets[idx].id, latlng.lat(), latlng.lng());
			}
			owner._polylineOver = null;
		// editor
		}else{
			if(owner.isDrawing == true || owner._editingStreet != -1 || owner._redrawingLine != -1)
				return;

			var idx = owner.indexOfPolyline(this);
			if(idx != -1){
				if(owner.streets[idx].photo==1)
					owner.onStreetClick(owner.streets[idx].id, latlng.lat(), latlng.lng());
				else
					alert("There is no photo for this street. Upload the photo first.");
			}
		}
	}
	function polylineOnMouseOver(){
		if(owner.mode == "viewer"){
			map.getDragObject().setDraggableCursor("pointer");
			this.setStrokeStyle({opacity:0.9});
			owner._polylineOver = this;
		}else{//editor
			if(owner.isDrawing == false){
				map.getDragObject().setDraggableCursor("pointer");
				this.setStrokeStyle({opacity:0.9});
				
				//var idx = owner.indexOfPolyline(this);
				//if(idx != -1){
					var icon = new google.maps.Icon();
					icon.image = "images/smalldot.png";
					icon.iconSize = new google.maps.Size(12, 12);
					icon.iconAnchor = new google.maps.Point(6, 6);
					owner._startPointMarker = new google.maps.Marker(this.getVertex(0), {icon:icon,draggable:false,title:""});
					map.addOverlay(owner._startPointMarker);
				//}
			}
		}
	}
	function polylineOnMouseOut(){
		if(owner.mode == "viewer"){
			this.setStrokeStyle({opacity:0.6});
			map.getDragObject().setDraggableCursor("url(http://maps.google.com/intl/en_us/mapfiles/openhand.cur),default");
			owner._polylineOver = null;

		}else{//editor
			if(owner.isDrawing == false){
				this.setStrokeStyle({opacity:0.6});
				map.getDragObject().setDraggableCursor("url(http://maps.google.com/intl/en_us/mapfiles/openhand.cur),default");
				if (owner._startPointMarker) {
					map.removeOverlay(owner._startPointMarker);
					owner._startPointMarker = null;
				}
			}
		}
	}
	function mapOnRightClick(point, src, overlay){
		var offset = getElementPos(document.getElementById(owner.container));
		if (owner.mode == "viewer") {
			owner.popupMenu.popupForMap(offset[0] + point.x, offset[1] + point.y, map.fromContainerPixelToLatLng(point));
		}else {
			if (overlay) {
				var idx = owner.indexOfPolyline(overlay);
				if (idx != -1) {
					owner.popupMenu.popup(owner.streets[idx], offset[0] + point.x, offset[1] + point.y);
				}
			} else {
				owner.popupMenu.popupForMap(offset[0] + point.x, offset[1] + point.y, map.fromContainerPixelToLatLng(point));
			}
		}
	}
	function mapOnMoveEnd(){
		if(owner.popupMenu) owner.popupMenu.hide();
		owner.refreshStreets();
		owner.onMapMoved(owner);
//		var g = new google.maps.ClientGeocoder();
//		g.getLocations(map.getCenter(), updateMapAddress); 
	}
/*	
	function updateMapAddress(response){
		var p = response.Placemark[0];
		//if(p) updateMapLocation(p.address);
	}
*/	
	function mapOnZoomEnd(oldLevel, newLevel){
		if(newLevel < 9) owner.clearStreets();//streets.length = 0;
		else owner.refreshStreets();
		owner.onMapMoved(owner);
	}
	function mapLoaded(){
		owner.refreshStreets();
		owner.onMapLoaded();
	}
	this.onMapLoaded=function(){}
	this.unload=function(){
		google.maps.Unload();
		this.streets.length = 0;
	}
	this.clearStreets=function(keepList){		
		for(var i = 0; i < this.streets.length; i++){
			if(this.streets[i].added){
				this.map.removeOverlay(this.streets[i].polyline);
				this.streets[i].added=false;
			}
		}
		if(keepList == undefined || keepList == false)
			this.streets.length = 0;
	}
	function getCookie(cookieName){
		var startIndex,endIndex;
		var cookie = document.cookie;
		if(cookie.length > 0){
			startIndex = cookie.indexOf(cookieName);
			if(startIndex != -1){
				startIndex += cookieName.length;
				endIndex = cookie.indexOf(";",startIndex);
				if(endIndex == -1) endIndex = cookie.length;
				return unescape(cookie.substring(startIndex+1,endIndex));
			}
		}
		return false;
	}
	
	this.refreshStreets=function(){
		if(this.map.getZoom() < 5){
			this.clearClusterMarkers(); 
			return;
		}
		if(this.refreshTimer != null){
			clearTimeout(this.refreshTimer);
		}
		this.refreshTimer = setTimeout("ps.refreshStreetsInternal()", 20);
	}
	
	this.refreshStreetsInternal=function(){

		if (this.mode == 'editor') {
			var src = "./services/get_streetlines.php?";
			var bounds = this.map.getBounds();
			
			src += "s=" + bounds.getSouthWest().lat() + "&w=" + bounds.getSouthWest().lng() + "&n=" + bounds.getNorthEast().lat() + "&e=" + bounds.getNorthEast().lng();
			if(this.mode=="editor") src += "&e=1";
			this._lastRequestId = (new Date()).getTime();
			src += "&rid="+this._lastRequestId;

			request = GetRequestObject();
			request.onreadystatechange = refreshStreetsHandler;
			request.open("GET", src, true);
			request.setRequestHeader("Content-Type", "application-www-form-urlencoded");
			request.setRequestHeader("If-Modified-Since", "0");
			request.send(null);
		} else {
			var src = "/services/get_mapdata.php?";
			var bounds = this.map.getBounds();

			src += "s=" + bounds.getSouthWest().lat() + "&w=" + bounds.getSouthWest().lng() + "&n=" + bounds.getNorthEast().lat() + "&e=" + bounds.getNorthEast().lng();
			this._lastRequestId = (new Date()).getTime();
			src += "&rid="+this._lastRequestId;
			src += "&l="+this.map.getZoom();

			$.ajax({
				type: "GET",
				dataType: "json",
				url: src,
				success: function(data){
					owner.updateStreetLines(data[0]);
					owner.updateMapLabels(data[1]);
					owner.updateSpots(data[2]);
					owner.updateVideos(data[3]);
				},error:function(a,b){
					//alert(b);
				}
			});
		}
	}
	this.indexOfMapLabel=function(id){
		var result = -1;
		for(var i=0; i < this._labels.length; i++){
			if (this._labels[i].id == id) {
				result = i;
				break;
			}	
		}
		return result;
	}
	this.clearMapLabels = function(){
		for(var i=0; i < this._labels.lenght; i++){
			map.removeOverlay(this._labels[i].overlay);	
		}
		this._labels.length = 0;
	}
	function indexOf(list, id){
		var result = -1;
		for(var i=0; i < list.length; i++){
			if(list[i].id == id){
				result = i;
				break;
			}
		}
		return result;
	}
	this.updateMapLabels = function(data){
		var label;
		for(var i=0;i<data.length;i++){
			if(this.indexOfMapLabel(data[i].id) != -1) // already exists
				continue;

			var icon = new google.maps.Icon();
			icon.image = '';
			icon.iconSize = new google.maps.Size(0, 0);
			icon.iconAnchor = new google.maps.Point(0, 0);
			var className = (this.map.getCurrentMapType() != G_NORMAL_MAP) ? "markerLabelWhite" : "markerLabel";
			var labelText = '<div onclick="popupBusiness('+data[i].id+')">'+data[i].name+"</div>";
			label = new LabeledMarker(new google.maps.LatLng(data[i].lat,data[i].lng), {labelText:labelText,icon:icon,labelOffset:new google.maps.Size(data[i].offsetx,data[i].offsety),labelClass:className,clickable:true});
			this._labels.push({id:data[i].id,overlay:label});
			this.map.addOverlay(label);
		}
		// remove unnecessary labels
		for(var i=0; i < this._labels.length; i++){
			if(indexOf(data, this._labels[i].id) == -1){
				this.map.removeOverlay(this._labels[i].overlay);
				this._labels.splice(i,1);
				i--;
			}
		}
	}
	this.clearSpots=function(){
		for(var i=0; i < this._spots.lenght; i++){
			map.removeOverlay(this._spots[i].overlay);	
		}
		this._spots.length = 0;
	}
	this.updateSpots = function(data){
		var m;
		for(var i=0;i<data.length;i++){
			if(indexOf(this._spots, data[i].id) != -1) // already exists
				continue;

			var icon = new google.maps.Icon();
			icon.image = 'images/camera2.png';
			icon.iconSize = new google.maps.Size(32, 25);
			icon.iconAnchor = new google.maps.Point(15, 12);
			var className = (this.map.getCurrentMapType() != G_NORMAL_MAP) ? "markerLabelWhite" : "markerLabel";
			var labelText = '<div onclick="popupSpot('+data[i].id+')">'+data[i].name+"</div>";
			m = new google.maps.Marker(new google.maps.LatLng(parseFloat(data[i].lat),parseFloat(data[i].lng)), {icon:icon,clickable:true,title:data[i].title});
			m.id = data[i].id;
			google.maps.Event.addListener(m, "click", this.spotClick);
			this._spots.push({id:data[i].id,overlay:m});
			this.map.addOverlay(m);
		}
		// remove unnecessary labels
		for(var i=0; i < this._spots.length; i++){
			if(indexOf(data, this._spots[i].id) == -1){
				this.map.removeOverlay(this._spots[i].overlay);
				this._spots.splice(i,1);
				i--;
			}
		}
	}
	this.spotClick=function(latlng){
		popupSpot(this.id);
	}
	this.clearVideos = function() {
		for(var i=0; i < this._videos.lenght; i++){
			map.removeOverlay(this._videos[i].overlay);	
		}
		this._videos.length = 0;
	}
	this.updateVideos = function(data){
		var m;
		for(var i=0;i<data.length;i++){
			if(indexOf(this._videos, data[i].id) != -1) // already exists
				continue;

			var icon = new google.maps.Icon();
			icon.image = 'images/camera.png';
			icon.iconSize = new google.maps.Size(32, 25);
			icon.iconAnchor = new google.maps.Point(15, 12);
			var className = (this.map.getCurrentMapType() != G_NORMAL_MAP) ? "markerLabelWhite" : "markerLabel";
			var labelText = '<div onclick="popupVideo('+data[i].id+')">'+data[i].name+"</div>";
			m = new google.maps.Marker(new google.maps.LatLng(parseFloat(data[i].lat),parseFloat(data[i].lng)), {icon:icon,clickable:true,title:data[i].title});
			m.id = data[i].id;
			google.maps.Event.addListener(m, "click", this.videoClick);
			this._videos.push({id:data[i].id,overlay:m});
			this.map.addOverlay(m);
		}
		// remove unnecessary labels
		for(var i=0; i < this._videos.length; i++){
			if(indexOf(data, this._videos[i].id) == -1){
				this.map.removeOverlay(this._videos[i].overlay);
				this._videos.splice(i,1);
				i--;
			}
		}
	}
	this.videoClick=function(latlng){
		popupVideo(this.id);
	}
	this.updateStreetLines = function(data){
		if(data.requestId != this._lastRequestId) return;
		var nodeList, node;
		var c, coords;
		var zlevel = map.getZoom();
		var pline;
		var plines = new Array();
		var id, idx;
		var ids = new Array();
		var s, f;
		var weight,color;
		var removed = 0;
		var added = 0;
		var redrawed = 0;
	
		// remove invisible lines
		if(data.lines.length == 0){
			this.clearStreets();
			this.clearClusterMarkers();
			return;
		}else{
			for(var i = 0; i < data.lines.length; i++) {// loop coordinates
				ids.push(data.lines[i].id);
			}
			for(var i = 0; i < this.streets.length; i++){
				f = false;
				for(var j = 0; j < ids.length; j++){
					if(ids[j] == this.streets[i].id){
						f = true;
						break;
					}
				}
				if(f == false){
					if(this.streets[i].added)
						this.map.removeOverlay(this.streets[i].polyline);
					this.streets.splice(i, 1);
					i--;
					
					removed++;
				}
			}
		}
		//alert(removed);
		// update
		var idx;
		var redraw;
		var line;
		for(var i = 0; i < data.lines.length; i++){
			line = data.lines[i];
			idx = this.indexOfId(line.id);
			if(idx != -1){// already exists
				redraw = false;
				if (this.streets[idx].active != line.active) {
					this.streets[idx].active = line.active;
					redraw = true;
				}
				if (this.streets[idx].photo != line.photo) {
					this.streets[idx].photo = line.photo;
					redraw = true;
				}				
				if(redraw == true){
					this.setLineStyle(this.streets[idx]);
					redrawed++;
				}
				continue; 
			}
			coords = new Array();
			for(var j = 0; j < line.points.length; j++){ // loop c
				coords.push(new google.maps.LatLng(parseFloat(line.points[j].lat), parseFloat(line.points[j].lng)));
			}
			if(coords.length > 1){
				s = new PSStreet(line.id);
				s.name = line.name;
				s.active = line.active; 
				s.photo = line.photo;
				s.userid = line.userid;
				s.isowner = line.isowner;
				s.clickable = true;

				// create a polyline
				weight = 4;
				if(zlevel < 12)	weight = 1;
				else if(zlevel < 16) weight = 2;
				else if(zlevel < 18) weight = 3;
				
				pline = new google.maps.Polyline(coords, "#0000FF", weight, 0.4, {mouseOutTolerance:1});
				s.polyline = pline;
				this.setLineStyle(s);

				s.added = false;
				this.streets.push(s);				
			}
		} // for

		if(map.getZoom() < 14){
			this.clearClusterMarkers();
			this.clearStreets(true);
			this.clusterStreetLines();
			this._clustered = true;
			
			// workaround for unknown errors: error occurred when polylines are not added to the map
			for(var i = 0; i < this.streets.length; i++){
				if(this.streets[i].added==false){
					map.addOverlay(this.streets[i].polyline);
					this.streets[i].polyline.hide();
					this.streets[i].added=true;
				}
			}
		}else{
			if(this._clustered == true){
				this.clearClusterMarkers();
				for(var i=0; i < this.streets.length; i++){
					this.streets[i].polyline.show();
					var pline = this.streets[i].polyline; 
					map.addOverlay(pline);
					google.maps.Event.addListener(pline, "mouseover", polylineOnMouseOver);
					google.maps.Event.addListener(pline, "mouseout", polylineOnMouseOut);
					google.maps.Event.addListener(pline, "click", polylineOnClick);
					this.streets[i].added=true;
				}
			}else{
				for(var i = 0; i < this.streets.length; i++){
					this.streets[i].polyline.show();
					if(this.streets[i].added==false){
						map.addOverlay(this.streets[i].polyline);
						this.streets[i].added=true;
						
						var pline = this.streets[i].polyline;
						google.maps.Event.addListener(pline, "mouseover", polylineOnMouseOver);
						google.maps.Event.addListener(pline, "mouseout", polylineOnMouseOut);
						google.maps.Event.addListener(pline, "click", polylineOnClick);
						
						added++;
					}
				}
			}
			this._clustered = false;
		}
//		alert("queried: "+nodeList.length+", added: "+added+", removed: " + removed + ", redrawed: " + redrawed);
	}
	function refreshStreetsHandler(){
		if (owner.mode == "editor") {
			if (getCookie('auto_refresh') == 'checked' && window.frames.panelcontents && window.frames.panelcontents.setSubPage) {
				window.frames.panelcontents.setSubPage('currmap');
			}
		}		
		if(request.readyState == 4)	{
			if(request.status == 200){
				var xmlDoc = request.responseXML;
				var root = xmlDoc.getElementsByTagName("streets");
				owner.updateLines(root[0]);
			}
		}
	}
	this.updateLines=function(root){
		if(root.getAttribute("requestId") != this._lastRequestId)
			return;
		
		var nodeList, node;
		var c, coords;
		var zlevel = map.getZoom();
		var pline;
		var plines = new Array();
		var id, idx;
		var ids = new Array();
	
		var s, f;
		var weight,color;
		
		var removed = 0;
		var added = 0;
		var redrawed = 0;
	
		// remove invisible lines
		nodeList = root.getElementsByTagName("street");
		if(nodeList.length == 0){
			for(var i = 0; i < this.streets.length; i++)
				map.removeOverlay(this.streets[i].polyline);
			this.streets.length = 0;
		}else{
			for(var i = 0; i < nodeList.length; i++) {// loop coordinates
				ids.push(nodeList[i].getAttribute('id'));
			}
			for(var i = 0; i < this.streets.length; i++){
				f = false;
				for(var j = 0; j < ids.length; j++){
					if(ids[j] == this.streets[i].id){
						f = true;
						break;
					}
				}
				if(f == false){
					this.map.removeOverlay(this.streets[i].polyline);
					this.streets.splice(i, 1);
					i--;
					
					removed++;
				}
			}
		}
		//alert(removed);
		// update
		var idx;
		var redraw;
		nodeList = root.getElementsByTagName("street");
		for(var i = 0; i < nodeList.length; i++){
			id = nodeList[i].getAttribute('id');
			idx = this.indexOfId(id);
			if(idx != -1){// already exists
				redraw = false;
				if (this.streets[idx].active != nodeList[i].getAttribute('active')) {
					this.streets[idx].active = nodeList[i].getAttribute('active');
					redraw = true;
				}
				if (this.streets[idx].photo != nodeList[i].getAttribute('photo')) {
					this.streets[idx].photo = nodeList[i].getAttribute('photo');
					redraw = true;
				}				
				if(redraw == true){
					this.setLineStyle(this.streets[idx]);
					redrawed++;
				}
				continue; 
			}
			node = nodeList[i].getElementsByTagName("c");
			coords = new Array();
			for(var j = 0; j < node.length; j++){ // loop c
				c = node[j];
				coords.push(new google.maps.LatLng(parseFloat(c.getAttribute("lat")), parseFloat(c.getAttribute("lng"))));
			}
			if(coords.length > 1){
				s = new PSStreet(id);
				s.name = nodeList[i].getAttribute('name');
				s.active = nodeList[i].getAttribute('active'); 
				s.photo = nodeList[i].getAttribute('photo');
				s.userid = nodeList[i].getAttribute('userid');
				s.isowner = nodeList[i].getAttribute('isowner');
				s.clickable = true;

				// create a polyline
				weight = 4;
				if(zlevel < 12)	weight = 1;
				else if(zlevel < 16) weight = 2;
				else if(zlevel < 18) weight = 3;
				
				pline = new google.maps.Polyline(coords, "#0000FF", weight, 0.4, {mouseOutTolerance:1});
				s.polyline = pline;
				this.setLineStyle(s);

				google.maps.Event.addListener(pline, "mouseover", polylineOnMouseOver);
				google.maps.Event.addListener(pline, "mouseout", polylineOnMouseOut);
				google.maps.Event.addListener(pline, "click", polylineOnClick);
				plines.push(pline);
				
				this.streets.push(s);
			}
		} // for

		for(var i = 0; i < plines.length; i++){
			map.addOverlay(plines[i]);
			added++;
		}
		plines.length=0;
//		alert("queried: "+nodeList.length+", added: "+added+", removed: " + removed + ", redrawed: " + redrawed);
	}

	this.panToStreet = function(street){
		var src = "/services/get_streetcoord.php?s=" + street;

		request = GetRequestObject();
		request.onreadystatechange = panToStreetHandler;
		request.open("GET", src, true);
		request.setRequestHeader("Content-Type", "application-www-form-urlencoded");
		request.setRequestHeader("If-Modified-Since", "0");
		request.send(null);	
	}
	function panToStreetHandler()
	{
		if(request.readyState == 4){
			if(request.status == 200){
				var xmlDoc = request.responseXML;
				var root = xmlDoc.getElementsByTagName("coordinates");
				var nodeList;
				var latlng;
				var coords = new Array();
				var c;
				var pt;
				var street;
				
				street = root[0].getAttribute("street");
				nodeList = root[0].getElementsByTagName("c");
				if(nodeList.length > 0){
					for(var i = 0; i < nodeList.length; i++){ // loop coordinates
						c = nodeList[i];
						coords.push(new google.maps.LatLng(c.getAttribute("lat"), c.getAttribute("lng")));
					}
				}
				latlng = coords[0];
				if(latlng.lat != 0 && latlng.lng != 0){
					if(map.getZoom() < 15)
						map.setCenter(new google.maps.LatLng(latlng.lat(), latlng.lng()), 15);
					else
						map.panTo(new google.maps.LatLng(latlng.lat(), latlng.lng()));
				}
			}
		}else if(request.readyState >= 1 && request.readyState < 4){}
	}
	this.centerStreet=function(street){
		var latlong;
		var idx;
		idx = this.indexOfId(street);
		if(idx != -1){
			latlng = this.streets[idx].polyline.getVertex(0);//getPolylineCenter(pts);
			if(latlng.lat != 0 && latlng.lng != 0){
				if(map.getZoom() < 15)
					map.setCenter(new google.maps.LatLng(latlng.lat(), latlng.lng()), 15);
				else
					map.panTo(new google.maps.LatLng(latlng.lat(), latlng.lng()));
			}
		}else{
			this.panToStreet(street);
		}
	}
	this.setActiveStreet=function(sid){
		var idx;
		var old_sid = this.activeStreet;

		this.activeStreet = sid;
		if(old_sid != -1){
			idx = this.indexOfId(old_sid);
			if(idx != -1){
				this.setLineStyle(this.streets[idx]);
			}
		}
		if(sid != -1){
			idx = this.indexOfId(sid);
			if(idx != -1)
				this.setLineStyle(this.streets[idx]);
		}
		if(sid == -1)
			this.hideStreetPosMarker();
	}
	this.setStreetHot=function(sid,hot){
		var idx = this.indexOfId(sid);
		if(idx == -1) return;
		if(hot){
			this.streets[idx].polyline.setStrokeStyle(LINECOLOR_HOT);
		}else{
			this.setLineStyle(this.streets[idx]);
		}
	}
	this.showBusinessMarker=function(id, name, lat, lng, pan, iconOpt){
		var latlng = new google.maps.LatLng(lat, lng);
		if(pan == true || this.map.getBounds().containsLatLng(latlng) == false)
			this.map.panTo(latlng);

		this.clearMarkers('hot');

		var m;
		if (iconOpt != undefined) {
			var icon = new google.maps.Icon();
			icon.image = iconOpt.src;
			icon.iconSize = new google.maps.Size(iconOpt.width, iconOpt.height);
			icon.iconAnchor = new google.maps.Point(iconOpt.offsetX, iconOpt.offsetY);
			m = new google.maps.Marker(latlng,{icon: icon,draggable:false,title:name,zIndexProcess:function(marker,b){return 890000001}});
		}else{
			var baseIcon = new google.maps.Icon(G_DEFAULT_ICON);
			baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
			baseIcon.iconSize = new google.maps.Size(20, 34);
			baseIcon.shadowSize = new google.maps.Size(37, 34);
			baseIcon.iconAnchor = new google.maps.Point(9, 34);
			baseIcon.infoWindowAnchor = new google.maps.Point(9, 2);
			
			m = new google.maps.Marker(latlng, {icon:baseIcon, title:name/*,zIndexProcess:markerZIndex2*/});
		}

		google.maps.Event.addListener(m, "click", function(latlng){owner.onMapMarkerClick('business',id);});
		this.map.addOverlay(m);
		this.markers['hot'].push(m);
	}
	this.hideBusinessMarker=function(){
		this.clearMarkers('hot');
	}
	this.highlightBusinessMarker=function(id){
		for(var i=0;i<this.markers['editing'].length;i++){
			var m= this.markers['editing'][i];
			if(id == m.businessid){
				var latlng = m.getLatLng();
				if(this.map.getBounds().containsLatLng(latlng) == false)
					this.map.panTo(latlng);

				m.openInfoWindowHtml("ID: "+m.businessid+"<br />NAME: <strong>"+m.getTitle()+"</strong><br /><br /><br /><div align='right'><a href=\"javascript:parent.editBusiness('"+m.businessid+"')\">edit</a> | <a href=\"javascript:parent.delBusiness('"+m.businessid+"')\">delete</a></div><br /><div align='center'>Drag me to update business location.</div>");
			}
		}
	}
	this.initMarkers=function(){
		for(var i=0; i < this._markerGroups.length; i++)
			this.markers[this._markerGroups[i]] = new Array();
//		this.markers['editing'] = new Array();
//		this.markers['hot'] = new Array();
	}
	this.clearMarkers=function(group){
		// remove all markers
		if(group == undefined){
			for(var i=0; i < this._markerGroups.length; i++){
				for(var j=0; j < this.markers[this._markerGroups[i]].length; j++){
					this.map.removeOverlay(this.markers[this._markerGroups[i]][j]);
				}
				this.markers[this._markerGroups[i]].length = 0;
			}
		}else{
			for(var j=0; j < this.markers[group].length; j++){
				this.map.removeOverlay(this.markers[group][j]);
			}
			this.markers[group].length = 0;
		}
	}
	this.addMarkers=function(group, data){
		var m;
		var icon;
		var baseIcon = new google.maps.Icon(G_DEFAULT_ICON);
		baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
		baseIcon.iconSize = new google.maps.Size(20, 34);
		baseIcon.shadowSize = new google.maps.Size(37, 34);
		baseIcon.iconAnchor = new google.maps.Point(9, 34);
		baseIcon.infoWindowAnchor = new google.maps.Point(9, 2);
		
		if(group == 'editing'){
			for(var i=0;i<data.length; i++){
				icon = new google.maps.Icon(baseIcon);
				icon.image = "http://www.google.com/mapfiles/marker"+data[i].letter+".png";
				m = new google.maps.Marker(new google.maps.LatLng(data[i].lat,data[i].lng), {icon:icon,draggable:data[i].draggable,title:data[i].name});
				m.businessid = data[i].id;
				google.maps.Event.addListener(m, "mouseover", function(latlng){this.show();});
				google.maps.Event.addListener(m, "click", function(latlng){this.openInfoWindowHtml("ID: "+this.businessid+"<br />NAME: <strong>"+this.getTitle()+"</strong><br /><br /><div align='right'><a href=\"javascript:parent.editBusiness('"+this.businessid+"')\">edit</a> | <a href=\"javascript:parent.delBusiness('"+this.businessid+"')\">delete</a></div><br /><br /><div align='center'>Drag me to update business location.</div>");});
				if(data[i].draggable == true){
					google.maps.Event.addListener(m, "dragstart", this.markerOnDragStart);
					google.maps.Event.addListener(m, "dragend", this.markerOnDragEnd);
				}
				this.markers[group].push(m);
			}
			for(var i=0; i < this.markers[group].length; i++){
				this.map.addOverlay(this.markers[group][i]);
			}
		}else
		{
			for(var i=0;i<data.length; i++){
				m = new google.maps.Marker(new google.maps.LatLng(data[i].lat,data[i].lng), {icon:data[i].icon,title:data[i].name,clickable:true,zIndexProcess:markerZIndex});
				m.businessid = data[i].id;
				m.zIndexTop = ((i==0) ? true : false);
				google.maps.Event.addListener(m, "mouseover", function(latlng){
					owner.setMarkerZIndexTop(this);
				});
				google.maps.Event.addListener(m, "click", function(latlng){owner.onMapMarkerClick('business',this.businessid);});
				
				this.markers[group].push(m);
			}
			for(var i=0; i < this.markers[group].length; i++){
				this.map.addOverlay(this.markers[group][i]);
			}
		}
	}
	this.getGroupOfMarker=function(marker){		
		for(var i=0; i < this._markerGroups.length; i++){
			for(var j=0; j < this.markers[this._markerGroups[i]].length; j++){
				if(this.markers[this._markerGroups[i]][j] == marker){
					return this._markerGroups[i];
				}
			}
		}
		return '';
	}
	this.setMarkerZIndexTop=function(marker){
		if(marker.zIndexTop) return;
		var group = this.getGroupOfMarker(marker);
		if(group.length > 0){
			this.rearrangeMarkers(group, marker.businessid);
			/*
			for(var i=0; i < this.markers[group].length; i++){
				this.markers[group][i].zIndexTop = ((marker == this.markers[group][i]) ? true : false);
			}
			*/
		}
	}
	function markerZIndex(marker, b){
		return (marker.zIndexTop ? 890000000 : google.maps.Overlay.getZIndex(marker.getLatLng().lat()));
	}	
	this.rearrangeMarkers=function(group, id){
		var list=[];
		for(var i=0;i<this.markers[group].length; i++){
			var item = this.markers[group][i];
			m = new google.maps.Marker(item.getLatLng(), {icon:item.getIcon(),title:item.getTitle(),clickable:true,zIndexProcess:markerZIndex});
			m.num = i+1;
			m.businessid = item.businessid;
			m.zIndexTop = ((id==item.businessid) ? true : false);
			google.maps.Event.addListener(m, "mouseover", function(latlng){
				owner.setMarkerZIndexTop(this);
			});
			google.maps.Event.addListener(m, "click", function(latlng){owner.onMapMarkerClick('business',this.businessid);});
			
			list.push(m);
		}
		this.clearMarkers(group);
		for(var i=0; i < list.length; i++){
			this.markers[group].push(list[i]);
			this.map.addOverlay(this.markers[group][i]);
		}
	}
	
	this.markerOnDragStart=function(latlng){
		owner._draggingMarker.marker = this;
		owner._draggingMarker.latlng = latlng;
	}
	this.markerOnDragEnd=function(latlng){
		if(confirm("Do you want to update the postion of this business?")){
			owner.onMarkerPosChanged(this.businessid, latlng);
		}else{
			this.setLatLng(owner._draggingMarker.latlng);
		}
	}
	this.endMarkerDrag=function(result){
		if(result == false && this._draggingMarker && this._draggingMarker.marker){
			this._draggingMarker.marker.setLatLng(this._draggingMarker.latlng);
		}
		this._draggingMarker.marker = null;
		this._draggingMarker.latlng = null;
	}
	this.setLineStyle=function(street, linestyle){
		if(!street.polyline) return;
		if(linestyle != undefined)
			street.polyline.setStrokeStyle(linestyle);
		else if(street.id == this.activeStreet){
			street.polyline.setStrokeStyle(LINECOLOR_ON);
		}else{
			if(street.active==1) street.polyline.setStrokeStyle(LINECOLOR_ACTIVE);
			else if(street.photo==1) street.polyline.setStrokeStyle(LINECOLOR_INACTIVE);
			else street.polyline.setStrokeStyle(LINECOLOR_INACTIVE_NOPHOTO);
		}
	}
	this.panTo=function(lat,lng){
		this.map.panTo(new google.maps.LatLng(lat,lng));
	}
	this.setStreetPosMarker=function(pos){
		if (this._streetPosMarker == null) {			
			var icon = new google.maps.Icon();
			icon.image = "images/posonmap.png";
			icon.iconSize = new google.maps.Size(25, 25);
			icon.iconAnchor = new google.maps.Point(12, 12);
			this._streetPosMarker = new google.maps.Marker(pos, {icon:icon,draggable:false,title:""});
			this.map.addOverlay(this._streetPosMarker);
		}else {
			this._streetPosMarker.setLatLng(pos);			
		}
	}
	this.hideStreetPosMarker=function(){
		if (this._streetPosMarker != null) {
			this.map.removeOverlay(this._streetPosMarker);
			this._streetPosMarker = null;
		}
	}
	this.getStreetPosMarkerLatLng=function(){
		return this._streetPosMarker ? this._streetPosMarker.getLatLng() : null;
	}
// EDITING	
	this.deleteStreet=function(streetid){
		var idx = this.indexOfId(streetid);
		if(idx != -1){
			this.map.removeOverlay(this.streets[idx].polyline);
			this.streets.splice(idx, 1);
		}
	}
	this.editStreetLine=function(streetid){
		this.popupMenu.hide();
		var idx = this.indexOfId(streetid);
		if(idx != -1){
			var pl = this.streets[idx].polyline;
			this._drawingPts.length = 0;
			for(i = 0; i < pl.getVertexCount(); i++){
				this._drawingPts.push(new google.maps.LatLng(pl.getVertex(i).lat(), pl.getVertex(i).lng()));
			}
			this.isDrawing = true;
			if (owner._startPointMarker) {
				map.removeOverlay(owner._startPointMarker);
				owner._startPointMarker = null;
			}
			this._editingStreet = this.streets[idx].id;
			this.streets[idx].polyline.enableEditing();

			this.onEditStreetLine();
		}
	}
	this.saveEditStreetLine=function(){
		if(this._editingStreet == -1) return;
		var idx = this.indexOfId(this._editingStreet);
		var pl = this.streets[idx].polyline;
		this.onPolylineCreated(this._editingStreet, Math.round(pl.getLength()));
	}
	this.endEditStreetLine=function(cancel){
		if(this._editingStreet == -1) return;
		var idx = this.indexOfId(this._editingStreet);
		this.streets[idx].polyline.disableEditing();
		this._editingStreet = -1;
		this.isDrawing = false;
		if(cancel == true){
			this.map.removeOverlay(this.streets[idx].polyline);
			var pl = new google.maps.Polyline(this._drawingPts, "#0000FF", 4, 0.4);
			this.streets[idx].polyline = pl;
			this.map.addOverlay(pl);
			google.maps.Event.addListener(pl, "mouseover", polylineOnMouseOver);
			google.maps.Event.addListener(pl, "mouseout", polylineOnMouseOut);
			google.maps.Event.addListener(pl, "click", polylineOnClick);
		}
		this.onCancelEditStreetLine();
	}
	this.redrawLine=function(id){
		this._redrawingLine = id;
		var idx = this.indexOfId(id);
		this.streets[idx].polyline.hide();
		//this.setLineStyle(this.streets[idx], LINECOLOR_REDRAWING);
		
		if (owner._startPointMarker) {
			map.removeOverlay(owner._startPointMarker);
			owner._startPointMarker = null;
		}		
		this.beginDrawLine();
	}
	this.endRedrawLine=function(result){
		if(this._redrawingLine == -1) return;
		var idx = this.indexOfId(this._redrawingLine);
		if(result){
			this.map.removeOverlay(this.streets[idx].polyline);
			var pl = new google.maps.Polyline(this._drawingPts, "#0000FF", 4, 0.4);
			this.streets[idx].polyline = pl;
			this.setLineStyle(this.streets[idx]);			
			this.map.addOverlay(pl);
			google.maps.Event.addListener(pl, "mouseover", polylineOnMouseOver);
			google.maps.Event.addListener(pl, "mouseout", polylineOnMouseOut);
			google.maps.Event.addListener(pl, "click", polylineOnClick);
			
		}else{ // cancel or error
			// this.setLineStyle(this.streets[idx]);
			this.streets[idx].polyline.show();			
		}
		this.redrawLine = -1;
		this.cancelDrawLine();
	}
	this.beginDrawLine=function(){
		if(this.map.getZoom() < 17){
			alert("You need to zoom in more to draw a street line.");
			return;
		}
		this.map.disableDoubleClickZoom();
		
		this._drawingLine = null;
		this.isDrawing = true;
		
		this.map.getDragObject().setDraggableCursor("crosshair");
		this.onBeginDrawLine();
	}
	this.endDrawLine=function(){
		if(owner._drawingLine.getVertexCount() > 1){
			owner._drawingPts.length = 0;
			for(var i=0; i < owner._drawingLine.getVertexCount(); i++)
				owner._drawingPts.push(owner._drawingLine.getVertex(i));
			
			owner.onPolylineCreated(owner._redrawingLine, Math.round(owner._drawingLine.getLength()));			
		}
		owner.cancelDrawLine(true);
	}
	this.cancelDrawLine=function(end){
		if(end == undefined) end = false;
		if(owner._drawingLine != null){
			google.maps.Event.clearListeners(owner._drawingLine, "endline");
			google.maps.Event.clearListeners(owner._drawingLine, "cancelline");
			owner._drawingLine.disableEditing();
			map.removeOverlay(owner._drawingLine);
		}
		owner.isDrawing = false;
		owner.editingStreet = -1;
		owner._drawingLine = null;
		map.getDragObject().setDraggableCursor("url(http://maps.google.com/intl/en_us/mapfiles/openhand.cur),default");		

		if(end==false){
			if(owner._redrawingLine != -1){
				var idx = owner.indexOfId(owner._redrawingLine);
				owner.streets[idx].polyline.show();
				//owner.setLineStyle(owner.streets[idx]);
			}
			owner._redrawingLine = -1;
		}
		map.enableDoubleClickZoom();
		owner.onCancelDrawLine();
	}
	this.undoDrawLine=function(){
		if(!this.isDrawing || !this._drawingLine || this._drawingLine.getVertexCount() == 0)
			return;

//		this._drawingLine.deleteVertex(this._drawingLine.getVertexCount() - 1);
	}
	/*
	this.polylineCreated=function(distance){
		this.onPolylineCreated(-1, distance);//this._editingStreet);
	}
	*/
	this.getDrawingLinePoints=function(){
		var result = null;
		if(this._editingStreet != -1){
			var idx = this.indexOfId(this._editingStreet);
			var pl = this.streets[idx].polyline;
			result = new Array();
			for(i = 0; i < pl.getVertexCount(); i++){
				result.push(new google.maps.LatLng(pl.getVertex(i).lat(), pl.getVertex(i).lng()));
			}
		}else if(this._drawingPts != null && this._drawingPts.length > 1){
			result = new Array();
			for(i = 0; i < this._drawingPts.length; i++){
				result.push(new google.maps.LatLng(this._drawingPts[i].lat(), this._drawingPts[i].lng()));
			}
		}
		return result;
	}
	this.addClusterMarker=function(latlng){
		var icon = new google.maps.Icon();
		icon.image = "images/camera.png";
		icon.iconSize = new google.maps.Size(48, 37);
		icon.iconAnchor = new google.maps.Point(22, 18);
		
		var m = new google.maps.Marker(latlng, {icon:icon,title:'Click to zoom',clickable:true});
		google.maps.Event.addListener(m, "click", this.clusterMarkerClick);		
		this._clusterMarkers.push(m);
	}
	this.clusterMarkerClick=function(latlng){
		var z = Math.min(19,map.getZoom() + 2);		
		map.setCenter(this.getLatLng(), z);
	}
	this.getMarkerBounds=function(latlng, zoom, projection){
		var pt,sw,ne;
		pt = projection.fromLatLngToPixel(latlng, zoom);
		sw = projection.fromPixelToLatLng(new google.maps.Point(pt.x - 22, pt.y - 18 + 37), zoom);
		ne = projection.fromPixelToLatLng(new google.maps.Point(pt.x - 22 + 48, pt.y - 18), zoom);
		return (new google.maps.LatLngBounds(sw, ne));
	}
	this.clusterStreetLines=function(){
		var l,grouped,b,c,cb;
		var zoom = this.map.getZoom();
		var projection = this.map.getCurrentMapType().getProjection();
		var streets = this.streets;
		for(var i=0; i < streets.length; i++)
			streets[i].grouped = false;
		for(var i=0; i < streets.length; i++){
			if(streets[i].grouped) continue;
			grouped = false;
			cb = this.getMarkerBounds(streets[i].polyline.getBounds().getCenter(),zoom,projection);
			for(var j=i+1; j < streets.length; j++){
				l = streets[j];
				b = this.getMarkerBounds(l.polyline.getBounds().getCenter(),zoom,projection);
				if(l.grouped==false && cb.intersects(b)){
					grouped = true;
					l.grouped = true;
					cb.extend(l.polyline.getBounds().getCenter());					
				}
			}
			if(grouped){
				this.addClusterMarker(cb.getCenter());
			}else{
				this.addClusterMarker(streets[i].polyline.getBounds().getCenter());
			}
		}
		// add cluster markers
		for(var i = 0; i < this._clusterMarkers.length; i++){
			map.addOverlay(this._clusterMarkers[i]);
		}
	}
	this.clearClusterMarkers=function(){
		for(var i=0; i < this._clusterMarkers.length; i++){
			map.removeOverlay(this._clusterMarkers[i]);
		}
		this._clusterMarkers.length = 0;
	}
}

function PSEditorPopupMenu(menuid)
{
	this._menu = document.getElementById(menuid);
	this._menus = [ // option [owner, active, photo]
				   {name:"Edit Street",onclick:"showStreet(id)",option:[0,0,1]},
				   {name:"-",onclick:"", option:[]},
				   {name:"Upload Photo",onclick:"uploadStreetPhoto(id)", option:[0,0,1]},
				   {name:"Edit Information",onclick:"editStreetInfo(id)",option:[0,0,0]},
				   {name:"Edit Polyline",onclick:"editPolyline(id)",option:[1,0,0]},
				   {name:"Deactivate",onclick:"activateStreet(id, 0)",option:[]},
				   {name:"Activate",onclick:"activateStreet(id, 1)"},
				   {name:"-",onclick:""},
				   {name:"Delete",onclick:"deleteStreet(id)"},
				   {name:"-",onclick:""},
				   {name:"Close Menu",onclick:"(id)"},
				  ];
	
	this.popup=function(street, x, y){
		this.updateMenu(street);
		this._menu.style.left = x+"px";
		this._menu.style.top = y+"px";
		this._menu.style.display = "";
	}
	this.popupForMap=function(x, y, latlng){
		this.updateMenuForMap(latlng);
		this._menu.style.left = x+"px";
		this._menu.style.top = y+"px";
		this._menu.style.display = "";
	}
	this.hide=function(){
		if(this._menu)	
			this._menu.style.display = "none";
	}	
	this.updateMenu=function(street, findOnMapMenu){
		var s = '';
		
		s += "<ul>";
		s += "<div class=\"pmtitle\">ID: " + street.id + "</div>";
		
		if(street.photo == 1)
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psEditStreet(" + street.id + ")\">Edit Street</li>\r\n";
			
	
		if(street.isowner == true)
		{
			s += "<div class=\"pmdivider\"><img src=\"./images/blank.gif\" /></div>";
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psUploadStreetPhoto(" + street.id + ")\">Upload Photo</li>\r\n";
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psEditStreetInfo(" + street.id + ")\">Edit Information</li>\r\n";
			if(street.active == 1)
				s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psActivateStreet(" + street.id + ", 0)\">Deactivate</li>\r\n";
			else
				s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psActivateStreet(" + street.id + ", 1)\">Activate</li>\r\n";

			s += "<div class=\"pmdivider\"><img src=\"./images/blank.gif\" /></div>";
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psEditStreetLine(" + street.id + ")\">Edit Street Line</li>\r\n";
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psRedrawStreetLine(" + street.id + ")\">Redraw Street Line</li>\r\n";
		
			s += "<div class=\"pmdivider\"><img src=\"./images/blank.gif\" /></div>";
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psDeleteStreet(" + street.id + ")\">Delete Street</li>\r\n";
		}
		/*
		s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psOnClosePopupMenu();\">Close Menu</li>";
		*/
		s += "</ul>";

		this._menu.innerHTML = s;
	}
	this.updateMenuForMap=function(latlng){
		var s = '';
		
		s += "<ul>";
		s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psAddBusiness(" + latlng.lat() + "," + latlng.lng() + ")\">Add Business Here</li>\r\n";
		/*if(g_userlevel == 997)
			s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psAddLabel(" + latlng.lat() + "," + latlng.lng() + ")\">Add Label Here</li>\r\n";
		*/
		s += "</ul>";

		this._menu.innerHTML = s;
	}
}

function PSPopupMenu()
{
	this._menus = [ // option [owner, active, photo]
				   {name:"Add Business Here",onclick:"addBusiness(lat,lng)",option:[0,0,1]}
				  ];
	this._menuHTML = '';
	this._showing = false;
	var owner = this;

	this.popupForMap=function(x, y, latlng){
		if(this._showing) this.hide();
		this.updateMenuForMap(latlng);
		
		$(document.body).append(this._menuHTML);
		$("#PSPopupMenu").css("left", x+"px");
		$("#PSPopupMenu").css("top", y+"px");
		
		$(document).bind("keydown", this.onKeyDown);
		this._showing = true;
	}
	this.onKeyDown = function(evt){
		if (evt.keyCode == 27) // ESC
			owner.hide();
	}
	this.hide=function(){
		$("#PSPopupMenu").remove();
		this._showing = false;
		$(document).unbind("keydown", this.onKeyDown);			
	};
	this.updateMenuForMap=function(latlng){
		var s = '';
		var div = document.createElement("DIV");
		div.id = "PSPopupMenu";
		var ul = document.createElement("UL");
		var li;
		
		li = document.createElement("LI");
		li.onmouseout = function(){this.className = '';};
		li.onmouseover = function(){this.className='hot';};
		li.onclick = function(){
			owner.hide();
			psAddBusiness(latlng.lat(), latlng.lng());
		};
		li.innerHTML = 'Add Business Here';
		ul.appendChild(li);

		if(g_userLevel >= 500){ // EDITOR		
			li = document.createElement("LI");
			li.onmouseout = function(){this.className = '';};
			li.onmouseover = function(){this.className='hot';};
			li.onclick = function(){
				owner.hide();
				psAddSpot(latlng.lat(), latlng.lng());
			};
			li.innerHTML = 'Add Spot Here';
			ul.appendChild(li);
			
			li = document.createElement('LI');
			li.onmouseout = function(){this.className = '';};
			li.onmouseover = function(){this.className = 'hot';};
			li.onclick = function() {
				owner.hide();
				psAddVideo(latlng.lat(), latlng.lng());
			};
			li.innerHTML = 'Add Video Here';
			ul.appendChild(li);
		}
		div.appendChild(ul);
		
		/*		
		s += "<div id=\"PSPopupMenu\"><ul>";
		s += "<li onmouseout=\"this.className=''\" onmouseover=\"this.className='hot'\" onclick=\"psAddBusiness(" + latlng.lat() + "," + latlng.lng() + ")\">Add Business Here</li>\r\n";
		s += "</ul></div>";
		*/
		this._menuHTML = div;//s;
	}	
}

function pmItemOut(obj){}
function pmItemOver(obj){}
