	// ----------------- BEGIN REQUIRED INTERFACE METHODS --------------------//

	function VInitMap()
	{
        var latLon = new VELatLong(this.centerPoint.latitude, this.centerPoint.longitude);

		var mapStyle = VEConvertMapStyle(this.mapType);
		
		// zoom level 1- is world view, 17 is max match w/google, 19 is absolute max zoom)
		var zoom = 17 - this.zoomLevel;

		var mode = VEMapMode.Mode2D;
		var fixed = false;
		var showModeSwitch = true;
		var tileBuffer = 1;

		this.map = new  VEMap(this._mapDiv.id);
		this.map.AttachEvent("onstartpan", _SEMap_ClosePopups);
		this.map.AttachEvent("onstartzoom", _SEMap_ClosePopups);
		this.map.AttachEvent("onendzoom", VUpdateView);
		this.map.AttachEvent("onchangemapstyle", VUpdateView);

	    var showDashboard = true;
		// SetDashboardSize must be called before calling LoadMap
		switch (this.controlSize)
		{
			case "none":
                showDashboard = false;
                break;
			case "small":
				this.map.SetDashboardSize(VEDashboardSize.Tiny);
				break;
			case "normal":
				this.map.SetDashboardSize(VEDashboardSize.Small);
				break;
			case "large":
                this.map.SetDashboardSize(VEDashboardSize.Normal);
				break;
		}

		this.map.LoadMap(latLon, zoom, mapStyle, fixed, mode, showModeSwitch, tileBuffer);
        if (showDashboard)
            this.map.ShowDashboard();
        else
            this.map.HideDashboard();

        this.map.Hide3DNavigationControl();
		this._mapDiv.onmousemove = _SEMap_MouseMoveHandler;

		var s = document.body.onscroll;
		if(s)
			document.body.onscroll = function(){s();SEMap_OnScroll(SEMaps[SEMaps.length-1]);}
		else
			document.body.onscroll = function(){SEMap_OnScroll(SEMaps[SEMaps.length-1]);}

		this.map.AttachEvent("onmouseover", VDisableInfoBox);
		this.map.AttachEvent("onmousedown", VCustomDragZoom);

		
		this.map.DeleteAllShapes();
        this.map.DeleteAllShapeLayers();
		this.pushpinShapeLayer = new VEShapeLayer();
        this.map.AddShapeLayer(this.pushpinShapeLayer);
		this.pushpinShapes = new Array();

		VFixPoweredByLogo(this);
		VUpdateView();
	}
	
	function VEConvertMapStyle(mapType)
	{
	    var mapStyle = VEMapStyle.Road;
		if (mapType == "aerial")
			{mapStyle = VEMapStyle.Aerial;}
		else if(mapType == "oblique")
			{mapStyle = VEMapStyle.Oblique;}
		else if (mapType == "hybrid")
			{mapStyle = VEMapStyle.Hybrid;}
		else if (mapType == "birdseye")
			{mapStyle = VEMapStyle.Birdseye;}
		else if (mapType == "birdseyehybrid")
			{mapStyle = VEMapStyle.BirdseyeHybrid;}
        return mapStyle
	}
	function VCustomDragZoom(e)
	{
	    if (e.altKey || e.middleMouseButton)
	    {
	        var seMap = SEMap_GetCurrentMap();
	        seMap.dragZoomStart(e);	        
	        return true;
	    }
	}
	
	function VUpdateView()
	{
		var map = SEMap_GetCurrentMap()
		map._originalMapView = map.map.GetMapView();
		_SEMap_ClosePopups();
	}

    function VDisableInfoBox(e)
    {
        if (e.elementID)
            return true;
    }
	function VPanMap(direction, xDelta, yDelta, onEndPanCallback)
	{
		if (onEndPanCallback)
		{
		    this._onEndPanCallBack = onEndPanCallback;
		    this.map.AttachEvent("onendpan", onEndPanCallback);
		    this._isPanning = true;
		}
		switch(direction)
		{
			case "down":
				this.map.Pan(0, (this._mapDiv.clientHeight * this.panFraction));
				break;
			case "up":
				this.map.Pan(0, -(this._mapDiv.clientHeight * this.panFraction));
				break;
			case "left":
				this.map.Pan( -(this._mapDiv.clientWidth * this.panFraction), 0);
				break;
			case "right":
				this.map.Pan( (this._mapDiv.clientWidth * this.panFraction), 0);
				break;
			case "":
				this.map.Pan(-parseInt(xDelta), parseInt(yDelta));
				break;
		}
		setTimeout('VClearEndPanCallback(' + this.id + ')', 2000);
	}

	function VClearEndPanCallback(myMap)
	{
	    if (myMap._onEndPanCallBack && typeof(myMap._onEndPanCallback) != 'undefined')
	    {
	        myMap.map.DetachEvent("onendpan", myMap.onEndPanCallback);
	        myMap._onEndPanCallBack = null;
	    }
	    myMap._isPanning = false;
	}

	function VSetCenterZoom(centerPoint, zoomLevel)
	{
		var oldZoom = this.zoomLevel;
		this.centerPoint = centerPoint;
		this.zoomLevel = zoomLevel;
		if (_SEMap_IsValidLatLong(centerPoint.latitude, centerPoint.longitude))
		{
		    this.map.SetCenterAndZoom(new VELatLong(centerPoint.latitude, centerPoint.longitude), 17 - zoomLevel);
		    if (_SEMap_UserAgent('firefox') && (Math.abs(this.getBounds().northWest.latitude - centerPoint.latitude) < .001))
		    {
			    // VirtualEarth/Firefox 1.5 bug - doesn't set latitude correctly
			    this.map.Pan(0, -(this._mapDiv.clientHeight * .5));
		    }
		    if (oldZoom == zoomLevel)
			    this.functionToCallOnPan();
	    }
	    VUpdateView();
	}

	function VClearMarkers()
	{
		if (this.map)
		{
			this.pushpinShapeLayer.DeleteAllShapes();
			this.pushpinShapes = new Array();
		}

	}

	function VSetBestMapView(bounds)
	{
		var boundsPoints = new Array();
		boundsPoints.push(new VELatLong(bounds.northWest.latitude, bounds.northWest.longitude));
		boundsPoints.push(new VELatLong(bounds.southEast.latitude, bounds.southEast.longitude));

		this.map.SetMapView(boundsPoints);
		this.zoomLevel = 17 - this.map.GetZoomLevel();
		this.centerPoint.latitude = (bounds.northWest.latitude + bounds.southEast.latitude) /2;
		this.centerPoint.longitude = (bounds.northWest.longitude + bounds.southEast.longitude) /2;
	}

	function VGetBounds()
	{
		var southEastLL = new VELatLong();
		var	northWestLL = new VELatLong();
		if (this.map)
		{
			var mapView = null;
			try
			{
			    mapView = this.map.GetMapView();
			}
			catch(e){}

			if (mapView)
			{
			    southEastLL = mapView.BottomRightLatLong;
			    northWestLL = mapView.TopLeftLatLong;
			}

		}
		if (northWestLL.Latitude)
		    return new SEBounds(new SEPoint(northWestLL.Latitude, northWestLL.Longitude),
		        new SEPoint(southEastLL.Latitude, southEastLL.Longitude));
		else
			return new SEBounds(new SEPoint(), new SEPoint());

	}

	function VAddMoveResizeEvents()
	{
		this.map.AttachEvent("onendpan", this.functionToCallOnZoom);
		this.map.AttachEvent("onendzoom", this.functionToCallOnZoom);
		this.map.AttachEvent("onendcontinuouspan", this.functionToCallOnPan);
	}

	var VResizeTimeoutId = -1;
	function VResize()
	{
		if (_SEMap_UserAgent("gecko"))
			VDoResize(this);
		else
			VResizeTimeoutId = setTimeout('VDoResize(' + this.id + ')', 100);
	}

	function VDoResize(map)
	{
		if (map)
		{
			map._mapDiv.style.width = "100%";

			var width = document.getElementById(map.id.replace("_map", "_td")).offsetWidth;
			var height = document.getElementById(map.id.replace("_map", "_td")).offsetHeight;

			if (_SEMap_UserAgent("gecko"))
			{
				if (map.map)
				{
					map.map.Resize(100,100);
					if (width > 10 && height > 10)
					    map.map.Resize(width -2 ,  height-2);
				}
			}
			else if (map.map && width > 10 && height > 10)
				map.map.Resize(width -2 ,  height-2);
		}
	}

	function VLoadMarkerDivText(puDiv, text)
	{
		if (puDiv && puDiv.isPopup && text && text.length > 0)
		{
			var contentHTML = "<table border=0 id='" + this.createMarkerID(puDiv.markerIndex) + "_table' class=PopupTable cellpadding=0 cellspacing=0>"
				+ "<tr><td>"
				+ text
				+ "</td></tr>"
				+ "<tr><td id='" + VFooterCellID(puDiv) + "'></td></tr>"
				+ "</table>";
			puDiv.contentCell.innerHTML = contentHTML;
			return true;
		}
		return false;
	}

	function VLoadDynamicFooterRow(puDiv)
	{
		var footerCell = document.getElementById(VFooterCellID(puDiv));
		if (puDiv.map.map.IsBirdseyeAvailable() && footerCell && (footerCell.innerHTML == ""))
		{
			footerCell.innerHTML = "<table border=0 cellpadding=0 cellspacing=0 bgcolor=#FFFFCC width=100% ><tr><td>&nbsp;&nbsp;"
				+ "<a href=javascript:VOpenBirdsEyePopup('" + puDiv.id + "') ><img border=0 src='/Common/SEMapping/i/oblique/be_small.gif' align=middle /></a></td>"
				+ "<td><img src=/common/images/clear.gif width=7></td><td><a href=javascript:VOpenBirdsEyePopup('" + puDiv.id + "') >Click here for Bird's Eye view imagery!</a>"
				+ "</td></tr></table>";
			puDiv.marker.previousHeight = null;
		}
	}

	function VFooterCellID(puDiv)
	{
		return puDiv.map.createMarkerID(puDiv.markerIndex) + '_footer';
	}

	function VAddPushpin(markerId, latitude, longitude, iconWidth, iconHeight, pushpinHtml, zIndex, tooltipHtml)
	{//if (markerId.indexOf("59") != -1) debugger
		var pushpinHtml1 = "<DIV id='" + markerId + "pp' style='background-color:transparent;width:20px;' ;>\n"
			+ pushpinHtml
			+ "</DIV>";

	    var pushpin = new VEShape(VEShapeType.Pushpin, new VELatLong(latitude, longitude));
        pushpin.SetCustomIcon(pushpinHtml1);
        this.pushpinShapeLayer.AddShape(pushpin);
        this.pushpinShapes[markerId] = pushpin;

        pushpin.SetZIndex(zIndex);

        var divTooltip = document.createElement("DIV");
	    divTooltip.id= markerId + "_tooltip";
        divTooltip.style.position = "absolute";
        divTooltip.style.display = "none";
        divTooltip.className = "tooltip";
        divTooltip.innerHTML = tooltipHtml;
        this._mapDiv.parentElement.insertBefore(divTooltip, this._mapDiv);

        var divPopup = document.createElement("DIV");
	    divPopup.id= markerId + "_popup";
        divPopup.style.position = "absolute";
        divPopup.style.display = "none";
        divPopup.innerHTML = "";
        divPopup.style.zIndex = _SEMap_PopupZIndex;
        this._mapDiv.parentElement.insertBefore(divPopup, this._mapDiv);
    }

	function VChangeIconSource(pushpinImg, newSrc, markerIndex)
	{
	    if (pushpinImg && pushpinImg.src)
	    {
	        if (!_SEMap_IsSameUrl(pushpinImg.src, newSrc))
		    {
		        var markerID = this.createMarkerID(markerIndex);
	            var ppShape = this.pushpinShapes[markerID];
	            var currentIcon = ppShape.GetCustomIcon();
	            var re = new RegExp(/<img.*src=[\'\"]?([^\'\" ]*)[\'\"]? .*>/i);
	            var aMatches = re.exec(currentIcon);
	            if (aMatches.length > 1)
	            {
	                var newIcon = currentIcon.replace(aMatches[1], newSrc);
	                ppShape.SetCustomIcon(newIcon);
	            }
	            pushpinImg.src = newSrc;
	        }
	    }
	}

	function  VSetMarkerZIndex(map, markerID, zIndex)
	{
		if (map && map.pushpinShapes && map.pushpinShapes[markerID]
		    && map.pushpinShapes[markerID].GetZIndex() != zIndex)
		     map.pushpinShapes[markerID].SetZIndex(zIndex);
	}

	function VOpenBirdsEyePopup(sDiv)
	{
		var puDiv = document.getElementById(sDiv);
		if (puDiv.marker.htmlBirdsEyeDetailUrl == "")
			puDiv.marker.htmlBirdsEyeDetailUrl = puDiv.marker.htmlPageUrl;
		var url = "/Common/SEMapping/ObliquePopup.aspx"
			+ "?latitude=" + puDiv.marker.location.latitude
			+ "&longitude=" + puDiv.marker.location.longitude
			+ "&sourceApp=" + puDiv.map.sourceApp
			+ "&detailPath=" + escape(puDiv.marker.htmlBirdsEyeDetailUrl);

		var mPopup = window.open(url, puDiv.markerId,
				'fullscreen=0' +
				',toolbar=0' +
				',status=0' +
				',statusbar=0' +
				',menubar=0'  +
				',scrollbars=0'  +
				',resizable=1' +
				',directories=0'  +
				',location=0'+
				',width=800' +
				',top=100' +
				',left=100' +
				',height=600'
			);
		mPopup.focus();
	}



	function VGetXY(myPosition)
	{
		var xy = this.map.LatLongToPixel(new VELatLong(myPosition.latitude, myPosition.longitude));
		xy.x = parseInt(xy.x);
		xy.y = parseInt(xy.y );

		return xy;
	}

	function VMap_GetMapDimensions()
	{
	    var originalXY = this.map.LatLongToPixel(this._originalMapView.TopLeftLatLong);

	    this._mapDivOffsetX = parseInt(originalXY.x);
	    this._mapDivOffsetY = parseInt(originalXY.y);
	}

	function VDrawPolyline()
	{
	}

	function VAttachEvent(eventname, functionObject)
	{
		this.map.AttachEvent(eventname, functionObject);
	}
	function VDetachEvent(eventname, functionObject)
	{
		this.map.DetachEvent(eventname, functionObject);

	}
	function VDisableDragging()
	{
		// this appears to be a MSVE bug - it doesn't seem to stop the dragging
		//this.map.SetAnimationEnabled(false)
	}
	function VEnableDragging()
	{
		//this.map.SetAnimationEnabled(true)
	}

	function VAttachMouseEvents()
	{
	}
	function VDetachMouseEvents()
	{
	}
	
	function VSetForPrint()
	{
	    var pOptions = new VEPrintOptions(true);
        this.map.SetPrintOptions(pOptions);        
    }
    function VHideScaleBar()
	{
	    this.map.HideScalebar();        
    }

	function VIncludePointInView(seLatLong)
	{
	   return false;
//	   var thisMapView = this.map.GetMapView();
//	    if (seLatLong.latitude > thisMapView.TopLeftLatLong.Latitude
//	        || seLatLong.latitude < thisMapView.BottomRightLatLong.Latitude
//	        || seLatLong.longitude < thisMapView.TopLeftLatLong.Longitude
//	        || seLatLong.longitude > thisMapView.BottomRightLatLong.Longitude)
//	        {
//	            this.map.PanToLatLong(new VELatLong(seLatLong.latitude, seLatLong.longitude));
//	            return true;
//	         }
//	         return false;
	}

	// ----------------- END REQUIRED INTERFACE METHODS --------------------//



	function VLatLngFromPixel(map, x, y)
	{
		var myLocation = new VEPixel(x, y);
		if (map.GetMapStyle() != null)
		    return  map.PixelToLatLong(myLocation);
		return null;
	}

	function VGetZoomLevel()
	{
		return 17 - this.map.GetZoomLevel();
	}

	function VShowXY(e)
	{
		alert ("Clicked point=" + semapVirtualEarth_map.map.GetX(e.view.latlong.longitude) +
			", " + semapVirtualEarth_map.map.GetY(e.view.latlong.latitude));
	}


	function VGetDashboard()
	{
		if (!this.dashboard)
		{
			this.dashboard = new SEMap_Dashboard();
			this.dashboard.div = SE_FindChildNodeByClass(this._mapDiv, "Dashboard", true);
		}

		if (this.dashboard.div)
		{
			if (!this.dashboard.width) this.dashboard.width = this.dashboard.div.offsetWidth;
			if (!this.dashboard.height) this.dashboard.height = this.dashboard.div.offsetHeight;

			this.dashboard.top = this.dashboard.div.offsetTop;
			this.dashboard.left = this.dashboard.div.offsetLeft;
			this.dashboard.topMargin = this.dashboard.div.offsetTop;
			this.dashboard.leftMargin = this.dashboard.div.offsetLeft;
		}

		if (!this.dashboard.div)
		{
			this.dashboard.div = document.createElement("span");
			this.dashboard.width = 0;
			this.dashboard.height = 0;
			this.dashboard.top = 0;
			this.dashboard.left = 0;
		}
	}

	function VFixPoweredByLogo(map)
	{
//        if (_SEMap_UserAgent("gecko"))
//		{
//			for (i=0;i<document.images.length;i++)
//			{
//				if (document.images[i].src.toLowerCase().indexOf("logo") != -1)
//				{
//					document.images[i].src = map._imagePath + "/logo_powered_by.png";
//					break;
//				}
//			}
//		}
	}

    function VAddEvent(elm, evType, fn, useCapture)
    {
        if (elm.addEventListener)
        {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        }
        else if (elm.attachEvent)
        {
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        }
        else
        {
            elm['on' + evType] = fn;
        }
    }


// drawing methods
function VInitDrawing()
{
    if (this._drawShapeLayer)
    {
        this._drawShapeLayer.DeleteAllShapes();
    }
    this._drawShapeLayer = new VEShapeLayer();
        this.map.AddShapeLayer(this._drawShapeLayer);
    this._drawGeomType = null;
    this._drawCurrentShape = null;
    this._drawPoints = new Array();
    this._drawCurrentLatLong;
    this._tempShape = null;
    this._tempPoints = null;
    this._drawCirclePoints = null;
    this._tempCircle = null;
    this._tempDistance = 0;
    this._drawShapeIndex = 1;
    this._drawCurrentShapeID = "";
    this._drawProximityDeltaLatLong = null;
    this._drawProximityPixels = 5;
    this.drawIsDrawing = false;
    
    // methods
    this.drawPolyMouseClick = VDrawPolyMouseClick;
    this.drawPolyMouseMove = VDrawPolyMouseMove;
    this.drawDeleteShape = VDrawDeleteShape;
    this.drawGetCirclePoints = VDrawGetCirclePoints;
    this.drawIsCloseToStartOrEndPoint = VDrawIsCloseToStartOrEndPoint;
    this.drawLoadShape = VDrawLoadShape;
    this.drawResizeToFitSelection = VDrawResizeToFitSelection;
}

function VStartDraw(geomType, drawCallback)
{
    
    this.drawInit();
    
    this._drawGeomType = geomType.toLowerCase();
    this.map.AttachEvent("onclick", V_DrawPolyMouseClick);
    this.map.AttachEvent("onmousemove", V_DrawMouseMove);
    this.drawIsDrawing = true;
    VDrawSetCursor(this)
    this.drawCallback = drawCallback;
}

function VDrawSetCursor(seMap)
{
    if (seMap.drawIsDrawing)
    {
        seMap._mapDiv.style.cursor='crosshair';
        setTimeout('VDrawSetCursor(' + seMap.id + ')', 200);
    }
}

function VDrawDone(isClear)
{
    try
    {
        _SEMap_ClosePopups()
        this.drawIsDrawing = false;
        this.map.DetachEvent("onmousemove", V_DrawPolyMouseMove);
        this.map.DetachEvent("onclick", V_DrawPolyMouseClick);
        this._drawShapeLayer.DeleteShape(this._tempShape);
        this._drawShapeLayer.DeleteShape(this._tempCircle);
    }
    catch (err)
    {
        
    }

    if (this._drawGeomType == "circle" && !(this._drawCirclePoints && this._drawCirclePoints.length > 3))
    {
        this._drawCirclePoints = null;
        this._drawPoints = new Array();
        this.mapBoundaryPoints = new Array();
    }
    else if (this._drawPoints.length < 3 )
    {
        this._drawPoints = new Array();
        this.mapBoundaryPoints = new Array();
    }
    else
    {
        if (!isClear)
        {
            this.drawLoadShape();    
            this.drawResizeToFitSelection(this._drawPoints); 
        }  
    }
    this._mapDiv.style.cursor = "";
    this._tempPoints = null;
    this._tempDistance = 0;
    
    if (this.drawCallback)
        this.drawCallback();
    if (this.functionToCallOnZoom)
        this.functionToCallOnZoom(true);
}

function VDrawResizeToFitSelection(points)
{
	var northWest = new SEPoint(-90, 180);
	var southEast = new SEPoint(90, -180);
	for (i = 0; i< points.length; i++)
	{  
	    if (points[i].Latitude < southEast.latitude) 
	        southEast.latitude = points[i].Latitude;
	    if (points[i].Longitude > southEast.longitude) 
	        southEast.longitude = points[i].Longitude;
	    if (points[i].Latitude > northWest.latitude) 
	        northWest.latitude = points[i].Latitude;
	    if (points[i].Longitude < northWest.longitude) 
	        northWest.longitude = points[i].Longitude;
	    
	}
	var bounds = new SEBounds(northWest, southEast);			
	this.setBestMapView(bounds);				 
	this.isLoading = false;
	this.updateBounds();
}

function VDrawLoadBoundaryPoints()
{
    this.drawInit();
    for (i=0; i < this.mapBoundaryPoints.length; i++)
    {
        var sePoint = this.mapBoundaryPoints[i];
        this._drawPoints[i] = new VELatLong(sePoint.latitude, sePoint.longitude);
    }
    this._drawGeomType = VEShapeType.Polygon.toLowerCase();
    this.drawLoadShape();
}

function VDrawLoadShape()
{
    this._drawCurrentShape = null;
    switch (this._drawGeomType)
    {
        case "polygon":
        case "rectangle":
            if (this._drawPoints.length > 2)
                this._drawCurrentShape = new VEShape(VEShapeType.Polygon, this._drawPoints);
            
            break;
        case "polyline":
            this._drawCurrentShape = new VEShape(VEShapeType.Polyline, this._drawPoints);
            break;
        case "circle":
            this._drawCurrentShape = new VEShape(VEShapeType.Polygon, this._drawCirclePoints);
            break;
        case "point":
            this._drawCurrentShape = new VEShape(VEShapeType.Pushpin, this._drawCurrentLatLong);
            break;
    }
    
    if (this._drawCurrentShape)
    {
        VSetShapeColor(this._drawCurrentShape);
   
        this._drawShapeLayer.AddShape(this._drawCurrentShape);
        this._drawCurrentShapeID = "shape" + this._drawShapeIndex;
        this._drawShapeIndex++;
    }
}

function VSetShapeColor(shape)
{
    shape.HideIcon();
    var lineColor = new VEColor(0, 0, 0, 1);
    var fillColor = new VEColor(128, 128, 128, .3);

    shape.SetLineColor(lineColor);
    shape.SetLineWidth(1);
    shape.SetFillColor(fillColor);
}

function VDrawGetPoints()
{
    var sePoints = new Array();
    if (this._drawPoints)
    {
        for (var i=0; i < this._drawPoints.length; i++)
        {
            sePoints[sePoints.length] = new SEPoint(this._drawPoints[i].Latitude, this._drawPoints[i].Longitude);
        }    
    }
    return sePoints;
}
function VDrawGetPointsString()
{
    var myPoints = this.drawGetPoints();
    var ret = "";
    for (i=0; i < myPoints.length; i++)
    {
        ret += (ret != "" ? "|" : "") + myPoints[i].latitude + "," + myPoints[i].longitude;
    }  
    return ret;
}

// ------- static draw methods ------------
function V_DrawSetCurrentMap(e)
{
    var seMap = SEMap_GetCurrentMap();
    var xy = VAdjustMapXYForBrowser(e);
   
    seMap._drawCurrentLatLong = seMap.map.PixelToLatLong(new VEPixel(xy.x, xy.y));
   
    if (!seMap._drawProximityDeltaLatLong)
    {
        var proximityLatLong = seMap.map.PixelToLatLong(
            new VEPixel(xy.x + seMap._drawProximityPixels, xy.y + seMap._drawProximityPixels));
        seMap._drawProximityDeltaLatLong = new VELatLong(
            Math.abs(proximityLatLong.Latitude) - Math.abs(seMap._drawCurrentLatLong.Latitude), 
            Math.abs(proximityLatLong.Longitude) - Math.abs(seMap._drawCurrentLatLong.Longitude))
    }     
    return seMap;
}

function V_DrawMouseMove(e)
{
    var seMap = V_DrawSetCurrentMap(e);
}

function V_DrawPolyMouseClick(e)
{
    var seMap = V_DrawSetCurrentMap(e);
    seMap.drawPolyMouseClick(e);
}

function V_DrawPolyMouseMove(e)
{
    var seMap = V_DrawSetCurrentMap(e);
    seMap.drawPolyMouseMove();
}

function VDrawGetDistance(p1, p2, units)
{
    var p1Lat = V_DrawLatLonToRadians(p1.Latitude);
    var p1Lon = V_DrawLatLonToRadians(p1.Longitude);

    var p2Lat = V_DrawLatLonToRadians(p2.Latitude);
    var p2Lon = V_DrawLatLonToRadians(p2.Longitude);
    
    if (!p1Lat)
    {
        p1Lat = V_DrawLatLonToRadians(p1.latitude);
        p1Lon = V_DrawLatLonToRadians(p1.longitude);

        p2Lat = V_DrawLatLonToRadians(p2.latitude);
        p2Lon = V_DrawLatLonToRadians(p2.longitude);
    }

    var R = 6371; // earth's mean radius in km
    var dLat  = p2Lat - p1Lat;
    var dLong = p2Lon - p1Lon;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(p1Lat) * Math.cos(p2Lat) * Math.sin(dLong/2) * Math.sin(dLong/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var disKm = R * c;
    //var disMiles = disKm * 0.6214;
    if (units && units == "miles")
        return (disKm * 0.6214);
    else
        return (disKm);
}

function V_DrawLatLonToRadians( point ) {
	return point * Math.PI / 180;	
}
// ------- end static draw methods ------------


function VDrawPolyMouseClick(e)
{
    if (this._drawPoints.length == 0 && this._drawGeomType != "point")
    {
        this.map.DetachEvent("onmousemove", V_DrawMouseMove);
        this.map.AttachEvent("onmousemove", V_DrawPolyMouseMove);
        this._mapDiv.style.cursor='crosshair';
    }

    if (this._drawGeomType == "circle" && (this._tempPoints && this._tempPoints.length == 2))
    {
        this._drawPoints[0] = this._tempPoints[0];
        this._drawPoints[1] = this._tempPoints[1];
        this.drawDone();
    }
    else  if (this._drawGeomType == "rectangle" && (this._tempPoints && this._tempPoints.length == 2))
    {
        this._drawPoints.length = 4
        this._drawPoints[0] = this._tempPoints[0];
        this._drawPoints[1] = new VELatLong(this._tempPoints[0].Latitude, this._tempPoints[1].Longitude);
        this._drawPoints[2] = this._tempPoints[1];        
        this._drawPoints[3] = new VELatLong(this._tempPoints[1].Latitude, this._tempPoints[0].Longitude);
        this.drawDone();
    }
    else
    {
        if (this._drawPoints.length > 2 && this.drawIsCloseToStartOrEndPoint())
            this.drawDone();
        else
            this._drawPoints.push(this._drawCurrentLatLong);
    }

    if (e.rightMouseButton)
    {
        this.drawDone();
    }
    else
    {
        this._mapDiv.style.cursor='crosshair';
    }
}

function VDrawIsCloseToStartOrEndPoint()
{
    if (this._drawPoints.length > 0)
    {
        var iLast =  this._drawPoints.length - 1;
        if (Math.abs(Math.abs(this._drawCurrentLatLong.Latitude) - Math.abs(this._drawPoints[0].Latitude))
            < Math.abs(this._drawProximityDeltaLatLong.Latitude))
        {
            if (Math.abs(Math.abs(this._drawCurrentLatLong.Longitude) - Math.abs(this._drawPoints[0].Longitude))
                < Math.abs(this._drawProximityDeltaLatLong.Longitude))
                return true;
        }
        else if (Math.abs(Math.abs(this._drawCurrentLatLong.Latitude) - Math.abs(this._drawPoints[iLast].Latitude))
            < Math.abs(this._drawProximityDeltaLatLong.Latitude))
        {
            if (Math.abs(Math.abs(this._drawCurrentLatLong.Longitude) - Math.abs(this._drawPoints[iLast].Longitude))
                < Math.abs(this._drawProximityDeltaLatLong.Longitude))
                {
                return true;
                }
        }
    }
    return false;
}


function VDrawPolyMouseMove()
{
    this._tempPoints = this._drawPoints.slice(0, this._drawPoints.length);

    if (this._drawGeomType == "circle" && this._tempPoints.length <= 2)
    {
        this._tempPoints[1] = this._drawCurrentLatLong;
        this._tempDistance = VDrawGetDistance(this._tempPoints[0], this._tempPoints[1]);

    }
    else if (this._drawGeomType == "rectangle" && this._tempPoints.length == 2)
    {
        this._tempPoints[1] = this._drawCurrentLatLong;
    }
    else
    {
        if (!this.drawIsCloseToStartOrEndPoint())
            this._tempPoints.push(this._drawCurrentLatLong);
        else
            return;
    }

    try
    {
        this._drawShapeLayer.DeleteShape(this._tempShape);
        this._drawShapeLayer.DeleteShape(this._tempCircle);
    }
    catch (err)
    {
    }
    
    if (this._tempPoints.length == 2)
    {
        if (this._drawGeomType == "polygon")
        { 
            this._tempShape = new VEShape(VEShapeType.Polyline, this._tempPoints);
            VSetShapeColor(this._tempShape);
            this._drawShapeLayer.AddShape(this._tempShape);           
         }
         else if (this._drawGeomType == "rectangle")
         {
            rectPoints = new Array();
            rectPoints[0] = this._tempPoints[0];
            rectPoints[1] = new VELatLong(this._tempPoints[0].Latitude, this._tempPoints[1].Longitude);
            rectPoints[2] = this._tempPoints[1];        
            rectPoints[3] = new VELatLong(this._tempPoints[1].Latitude, this._tempPoints[0].Longitude);
            
            this._tempShape = new VEShape(VEShapeType.Polygon, rectPoints);
            VSetShapeColor(this._tempShape);
            this._drawShapeLayer.AddShape(this._tempShape);
         }
    }

    if (this._tempPoints.length > 2)
    {
        switch (this._drawGeomType)
        {
            case "polygon":
                this._tempShape = new VEShape(VEShapeType.Polygon, this._tempPoints);
                break;
            case "polyline":
                this._tempShape = new VEShape(VEShapeType.Polyline, this._tempPoints);
                break;
        }
        VSetShapeColor(this._tempShape);
        this._drawShapeLayer.AddShape(this._tempShape);
    }
}

//Draw Circle
function VDrawGetCirclePoints()
{
    var R = 6371; // earth's mean radius in km
    var lat = (this._drawPoints[0].Latitude * Math.PI) / 180; //rad
    var lon = (this._drawPoints[0].Longitude * Math.PI) / 180; //rad
    var d = parseFloat(this._tempDistance) / R;  // d = angular distance covered on earth's surface
    this._drawCirclePoints = new Array();
    for (x = 0; x <= 360; x++)
    {
        var p2 = new VELatLong(0,0);
        var brng = x * Math.PI / 180; //rad
        p2.Latitude = Math.asin(Math.sin(lat)*Math.cos(d) + Math.cos(lat)*Math.sin(d)*Math.cos(brng));
        p2.Longitude = ((lon + Math.atan2(Math.sin(brng)*Math.sin(d)*Math.cos(lat), Math.cos(d)-Math.sin(lat)*Math.sin(p2.Latitude))) * 180) / Math.PI;
        p2.Latitude = (p2.Latitude * 180) / Math.PI;
        this._drawCirclePoints.push(p2);
    }
    return this._drawCirclePoints;
}

function VDrawDeleteShape(shapeID)
{
    var delShape = this._drawShapeLayer.GetShapeByID(shapeID);
    this._drawShapeLayer.DeleteShape(delShape);

}

// overlay methods
function VOverlayDraw(overlaySEPoints)
{   
    if (this._overlayShapeLayer)
    {
        this._overlayShapeLayer.DeleteAllShapes();
    }
    this._overlayShapeLayer = new VEShapeLayer();
        this.map.AddShapeLayer(this._overlayShapeLayer);
    this._overlayPoints = new Array();
    if (overlaySEPoints)
         this._overlayBoundaryPoints = overlaySEPoints;
    
    for (i=0; i < this._overlayBoundaryPoints.length; i++)
    {
        var sePoint = this._overlayBoundaryPoints[i];
        this._overlayPoints[i] = new VELatLong(sePoint.latitude, sePoint.longitude);
    }
    
    this._overlayCurrentShape = null;
    if (this._overlayPoints.length > 2)
        this._overlayCurrentShape = new VEShape(VEShapeType.Polygon, this._overlayPoints);
            
     if (this._overlayCurrentShape)
     {
        VSetOverlayShapeColor(this._overlayCurrentShape, new VEColor(0, 0, 0, 1), new VEColor(128, 128, 255, .3), 1, true);
        this._overlayShapeLayer.AddShape(this._overlayCurrentShape);
        this._overlayCurrentShapeID = "shape" + this._overlayShapeIndex;
        this._overlayShapeIndex++;
    }
}

function VSetOverlayShapeColor(shape, lineColor, fillColor, lineWidth, hideIcon)
{
    if (hideIcon)
        shape.HideIcon();
    shape.SetLineColor(lineColor);
    shape.SetLineWidth(lineWidth);
    shape.SetFillColor(fillColor);
}

//  ---- DragZoom Methods
function VInitDragZoom()
{
    if (this._dragZoomShapeLayer)
        this._dragZoomShapeLayer.DeleteAllShapes();
    this._dragZoomShapeLayer = new VEShapeLayer();
        this.map.AddShapeLayer(this._dragZoomShapeLayer);
    this._dragZoomPoints = new Array();
    this._dragZoomCurrentLatLong;
    this._tempDragZoomPoints = new Array();
    this._isDragZooming = false;
    
    // methods
    this.dragZoomMouseClick = VDragZoomMouseClick;
    this.dragZoomMouseMove = VDragZoomMouseMove;    
}

function VDragZoomStart(e)
{
    this.dragZoomInit();
    this.map.AttachEvent("onclick", V_DragZoomMouseClick);
    this.map.AttachEvent("onmousemove", V_DragZoomMouseMove);
    this._isDragZooming = true;
    VDragZoomSetCursor(this)
    this.dragZoomMouseClick(e);
}

function V_DragZoomMouseClick(e)
{
    SEMap_GetCurrentMap().dragZoomMouseClick(e);
}

function VDragZoomMouseClick(e)
{
    var seMap = SEMap_GetCurrentMap();
    seMap._dragZoomCurrentLatLong = VDrawGetCurrentLatLong(seMap, e);
    
    if (this._tempDragZoomPoints.length == 0)
    {
        this._tempDragZoomPoints[0] = seMap._dragZoomCurrentLatLong;
        VDragZoomSetCursor(this);
        return;
    }
    this._tempDragZoomPoints[1] = seMap._dragZoomCurrentLatLong;    
    this._dragZoomPoints.length = 4
    this._dragZoomPoints[0] = this._tempDragZoomPoints[0];
    this._dragZoomPoints[1] = new VELatLong(this._tempDragZoomPoints[0].Latitude, this._tempDragZoomPoints[1].Longitude);
    this._dragZoomPoints[2] = this._tempDragZoomPoints[1];        
    this._dragZoomPoints[3] = new VELatLong(this._tempDragZoomPoints[1].Latitude, this._tempDragZoomPoints[0].Longitude);
    this.dragZoomDone();
}

function VDrawGetCurrentLatLong(seMap, e)
{  
    var xy = VAdjustMapXYForBrowser(e);
    return seMap.map.PixelToLatLong(new VEPixel(xy.x, xy.y));
}

function V_DragZoomMouseMove(e)
{
    SEMap_GetCurrentMap().dragZoomMouseMove(e);
}

function VDragZoomMouseMove(e)
{
    var seMap = SEMap_GetCurrentMap();
    seMap._dragZoomCurrentLatLong = VDrawGetCurrentLatLong(seMap, e);
    this._tempDragZoomPoints[1] = this._dragZoomCurrentLatLong;
    
    this._dragZoomShapeLayer.DeleteAllShapes();
    
    rectPoints = new Array();
    rectPoints[0] = this._tempDragZoomPoints[0];
    rectPoints[1] = new VELatLong(this._tempDragZoomPoints[0].Latitude, this._tempDragZoomPoints[1].Longitude);
    rectPoints[2] = this._tempDragZoomPoints[1];        
    rectPoints[3] = new VELatLong(this._tempDragZoomPoints[1].Latitude, this._tempDragZoomPoints[0].Longitude);
            
    _tempDragZoomShape = new VEShape(VEShapeType.Polygon, rectPoints);
    VSetShapeColor(_tempDragZoomShape);
    this._dragZoomShapeLayer.AddShape(_tempDragZoomShape);

}

function VDragZoomSetCursor(seMap)
{
    if (seMap._isDragZooming)
    {
        seMap._mapDiv.style.cursor='crosshair';
        setTimeout('VDragZoomSetCursor(' + seMap.id + ')', 200);
    }
}

function VDragZoomDone()
{
    this._isDragZooming = false;
    this.map.DetachEvent("onmousemove", V_DragZoomMouseMove);
    this.map.DetachEvent("onclick", V_DragZoomMouseClick);
    this._dragZoomShapeLayer.DeleteAllShapes();
    this._mapDiv.style.cursor = "";
    this.drawResizeToFitSelection(this._dragZoomPoints);
    this._dragZoomPoints = null;
}

function VAdjustMapXYForBrowser(e)
{
    var xy = new SE_XY(e.mapX, e.mapY);
    if(SE_UserAgent("msie"))
    {
        //xy.x += document.body.scrollLeft;
        //xy.y += document.body.scrollTop;
    }
    return xy;
}

