
	//public global variables
	var SEMap_IsDraggingMap = false;
	var SEMaps = new Array();
	var SEMap_HttpRequest;
	// all private global variables
	var _SEMap_NoScrollDiv = null;
	var _SEMap_ScrollTimeoutId;
	var _SEMap_CurrentPopupDiv = null;
	var _SEMap_CurrentTooltipDiv = null;
	var _SEMap_CurrentMap = null;
	var _SEMap_BaseZIndex = 10000;
	var _SEMap_TooltipZIndex = 10000;
	var _SEMap_PopupZIndex = 10000;
	var _SEMap_CurrentPushpin = null;
	var _SEMap_MouseTimer = null;
	var _SEMap_LastPopupName = "";
	var _SEMap_ZOOMAREA_KEYCODE = 18; // 'Alt' key zooms an area when the mouse is moved (not dragged).
	var _SEMap_ResizeTimeoutId = null;
	var _SEMap_LoadingMsg = "&nbsp;Loading...";
	var _SEMap_Popup = 'popup';

	function SEPoint(myLatitude, myLongitude)
	{
	    // defaults to middle of US
		if (myLatitude)
		    this.latitude = myLatitude;
		else
		    this.latitude = 31.5;
		
		if (myLongitude)
		    this.longitude = myLongitude;
		else
		    this.longitude = -94.7;
	}

	function SE_XY(X, Y)
	{
		this.x = X;
		this.y = Y;
	}

	function SEIcon(iconSrc, iconWidth, iconHeight)
	{
		this.src = iconSrc;
		this.width = iconWidth;
		this.height = iconHeight;
	}
	function SEBounds(northwest, southeast)
	{
		this.northWest = northwest;
		this.southEast = southeast;
	}

	function SEMarker()
	{
		this.map;
		this.location = new SEPoint();
		this.popupHtml = "";
		this.title = "";
		this.tooltipHtml = "";
		this.htmlPageUrl = "";
		this.htmlBirdsEyeDetailUrl = "";
		this.previousHeight;
		this._top;
		this._left;
		this._popupDiv;
		this._tooltipDiv;
		this._markerDiv;
		this._getImage = _SEMap_GetMarkerImage;
		this._getMarkerDiv = _SEMap_GetMarkerDiv;
		this._createPopupDiv = _SEMap_CreatePopupDiv;
		this._getPopupDiv = _SEMap_GetPopupDiv;
		this._setZIndex = _SEMap_SetMarkerZIndex;
		this._isVisible = _SEMap_MarkerIsVisible;
	}

	function SEMap_Dashboard()
	{
		this.top;
		this.left;
		this.width;
		this.height;
		this.topMargin = 5;
		this.leftMargin = 5;
		this.bottomMargin = 5;
		this.rightMargin = 5;
		this.div = null;
	}

	function SEMap(mapDiv, vendor)
	{
		//private
		this._imagePath = "/common/semapping/images/";

		//public properties
		this.centerPoint;
		this.mapType = "street"; // street, aerial, hybrid or oblique
		this.zoomLevel = 14; // zooms - 16 is world view, 0 is max zoom)
		this.vendor = vendor; //GoogleMaps, VirtualEarth, MapPoint
		this.panFraction = .8;
		this.controlSize = "normal"; // none, small, normal, large
		this.disableDragZoom = false;
		this.markers = new Array();
		this.markerIcon = new SEIcon(this._imagePath + "icon_house_16x16t.gif", 16, 16);
		this.markerIconSelected = new SEIcon(this._imagePath + "icon_house_selected_t.gif", 14, 14);
		this.functionToCallOnZoom = _SEMap_NOP;
		this.functionToCallOnPan = _SEMap_NOP;
		this.onPopupOpen = _SEMap_NOP;
		this.onPopupClose = _SEMap_NOP;
		this.onTooltipOpen = _SEMap_NOP;
		this.onTooltipClose = _SEMap_NOP;
		this.mouseOverAction = "";
		this.enableClickPopup = true;
		this.enableMouseOverHighlight = true;
		this.closePopupAfter = 1500; // milliseconds
		this.closePopupAfterClick = 10000; // milliseconds
		this.companyID = null;
		this.officeID = null;
		this.userID = null;
		this.contactID = null;
		this.homepageID = null;
		this.popupType = "box";
		this.popupFormat = "";
		this.propertyDetailUrl = "";
		this.requestShowingUrl = "";
		this.hasCurrentPopup = _SEMap_HasCurrentPopup;
		this.map;
		this.id = "";
		this.isOpeningWindow = false;
		this.isLoading = true;
		this.eventsDisabled = false;
		this.sourceApp = "";
		this.namePrefix = "";
		this.updateMsgDiv = null;
		this.popupTableWidth = 260;
		this.isPublic = false;
		this.mapBoundaryPoints = new Array();
		this.mapBoundariesTempGUID = "";
		this.drawIsDrawing = false;
		this.isDragZoom = false;
		this.markerRectangle = null;
		this.sourceApp = null;

		// --------- public methods --------
		this.addMarkers = _SEMap_AddMarkers;
		this.fitMarkers = _SEMap_FitMarkers;
		this.reCenterOnSelection = _SEMap_RecenterOnSelection;
		this.highlightPushpin = _SEMap_HighlightPushpin;
		this.highlightAndTooltip = _SEMap_HighlightAndTootip;
		this.showUpdatingMsg = _SEMap_ShowUpdatingMsg;
		this.showTooltip = _SEMap_ShowTooltip;
		this.openPopup = _SEMap_OpenPopup;
		this.closeDiv = _SEMap_CloseDiv;
		this.isBigMove = _SEMap_IsBigMove;
		this.updateBounds = _SEMap_UpdateBounds;
		this.clearDrawing = SEMap_ClearDrawing;

		// resize and recenter the map to show all of the current markers
		this.addMarker = _SEMap_AddMarker;
		if (vendor == "VirtualEarth6")
		{
			this.getZoomLevel = VGetZoomLevel;
			this.drawPolyline = VDrawPolyline;
			this.addMoveResizeEvents = VAddMoveResizeEvents;
			this.getBounds = VGetBounds;
			this.clearMapMarkers = VClearMarkers;
			this.setCenterZoom = VSetCenterZoom;
			this.setBestMapView = VSetBestMapView;
            this.getDashboard = VGetDashboard;
            this.drawInit = VInitDrawing;
            this.drawStart = VStartDraw; 
            this.drawDone = VDrawDone;
            this.drawGetPoints = VDrawGetPoints;
            this.drawGetPointsString = VDrawGetPointsString;
            this.drawLoadBoundaryPoints = VDrawLoadBoundaryPoints;
            this.drawGetDistance = VDrawGetDistance;
            this.dragZoomInit = VInitDragZoom;
            this.dragZoomStart = VDragZoomStart;
            this.dragZoomDone = VDragZoomDone;
            this.getDirections = VGetDirections;
            this.overlayDraw = VOverlayDraw; 
            this.setForPrint = VSetForPrint;
            this.hideScaleBar = VHideScaleBar;
		}
		else if(vendor == "GoogleMaps")
		{
			this.getZoomLevel = GGetZoomLevel;
			this.addMarker = GAddMarker;
			this.drawPolyline = GDrawPolyline;
			this.addMoveResizeEvents = GAddMoveResizeEvents;
			this.getBounds = GGetBounds;
			this.clearMapMarkers = GClearMarkers;
			this.setCenterZoom = GSetCenterZoom;
			this.setBestMapView = GSetBestMapView;
		}
		else if(vendor == "MapPoint")
		{
			this.getZoomLevel = MGetZoomLevel;
			this.drawPolyline = MDrawPolyline;
			this.addMoveResizeEvents = MAddMoveResizeEvents;
			this.getBounds = MGetBounds;
			this.clearMapMarkers = MClearMarkers;
			this.setCenterZoom = MSetCenterZoom;
			this.setBestMapView = MSetBestMapView;
			this.getDashboard = MGetDashboard;
		}

		// private properties
		this._mapDiv = mapDiv;
		this._mouseTracker = null;
		this._hasResizeEvent = false;
		this._isPanning = false;
		// Virtual earth properties when map is panned under mapDiv
		this._mapDivOffsetX = 0;
		this._mapDivOffsetY = 0;
		this._originalMapView;

		// private methods
		this.init = _SEMap_Init;
		this.enableEvents = _SEMap_EnableEvents;
		this.disableEvents = _SEMap_DisableEvents;
		this.createMarkerID	= _SEMap_CreateMarkerID;
		this.loadPopupDiv = _SEMap_LoadPopupDiv;
		this.initializePopupDiv = _SEMap_InitializePopupDiv;
		this.clearMarkers = _SEMap_ClearMarkers;
		this._getPopupDimensions = _SEMap_GetPopupDimensions;
		this._getMarkerDimensions = _SEMap_GetMarkerDimensions;
		this._positionPopupDiv = _SEMap_PositionPopupDiv;
		this._setCurrentPopupDiv = _SEMap_SetCurrentPopupDiv;
        this._changeIconSrc = _SEMap_ChangeIconSource;
        switch (vendor)
		{
			case "VirtualEarth6":
				this._Init = VInitMap;
				this._pan = VPanMap;
				this._reSize = VResize;
				this._doResize = VDoResize;
				this._attachEvent = VAttachEvent;
				this._detachEvent = VDetachEvent;
				this._disableDragging = VDisableDragging;
				this._enableDragging = VEnableDragging;
				this._detachMouseEvents = VDetachMouseEvents;
				this._attachMouseEvents = VAttachMouseEvents;
				this._loadMarkerDivText = VLoadMarkerDivText;
				this._loadDynamicFooterRow = VLoadDynamicFooterRow;
				this._addPushpin = VAddPushpin;
				this._getXY = VGetXY;
				this._changeIconSrc = VChangeIconSource;
			    this._includePointInView = VIncludePointInView;
			    this._getMapDimensions = VMap_GetMapDimensions;
				break;
			case "GoogleMaps":
				this._Init = GInitMap;
				this._pan = GPanMap;
				this.openPopup = GOpenPopup;
				this.closePopup = GClosePopup;
				this.highlightPushpin = GHighlightPushpin;
				this._reSize = GResize;
				this._doResize = GDoResize;
				this._getLatLonFromPixel = GGetLatLonFromPixel;
				this._disableDragging = GDisableDragging;
				this._enableDragging = GEnableDragging;
				this._includePointInView = _SEMap_IncludePointInView;
				this._getMapDimensions = _SEMap_GetMapDimensions;
				break;
			case "MapPoint":
				this._Init = MInitMap;
				this._pan = MPanMap;
				this._reSize = MResize;
				this._doResize = MDoResize;
				this._zoomTo = MZoomTo;
				this._attachEvent = MAttachEvent;
				this._detachEvent = MDetachEvent;
				this._getLatLonFromPixel = MGetLatLonFromPixel;
				this._disableDragging = MDisableDragging;
				this._enableDragging = MEnableDragging;
				this._detachMouseEvents = MDetachMouseEvents;
				this._attachMouseEvents = MAttachMouseEvents;
				this._loadMarkerDivText = MLoadMarkerDivText;
				this._loadDynamicFooterRow = _SEMap_NOP;
				this._addPushpin = MAddPushpin;
				this._getXY = MGetXY;
				this._includePointInView = _SEMap_IncludePointInView;
				this._getMapDimensions = _SEMap_GetMapDimensions;
				break;
		}
	}

	function _SEMap_Init() {
		this.isOpeningWindow = true;
		$mapdiv = $("#" + this._mapDiv.id);
		$mapdiv.height($mapdiv.parent().availableHeight());
		this.isOpeningWindow = false;
	   SEMaps[SEMaps.length] = this;
	    
	   this._Init();
	   
		this._mouseTracker = new _SEMap_MouseTracker(this);

		if (!this._hasResizeEvent)
		{
			var prev_resize = window.onresize;
			if(prev_resize)
				window.onresize = function(){prev_resize();SEMap_OnResize();}
			else
				window.onresize = function(){SEMap_OnResize();}
			this._hasResizeEvent = true;
		}
		this._mapDivWidth = this._mapDiv.offsetWidth;
		this._mapDivHeight = this._mapDiv.offsetHeight;
		
	}

	function _SEMap_AddMarkers()
	{
		this.clearMarkers();
		for (var i=0; i < this.markers.length; i++)
		{
			var myMarker = this.markers[i];
			if (_SEMap_IsValidLatLong(myMarker.location.latitude, myMarker.location.longitude))
			{
				this.addMarker(i, myMarker.popupHtml, myMarker.htmlPageUrl, myMarker.location, this, "", myMarker.tooltipHtml);
			}
		}
	}
	function _SEMap_ClearMarkers()
	{
		for (var i=0; i < this.markers.length; i++)
		{
		    var markerID = this.createMarkerID(i);
		    var ttDiv = document.getElementById(markerID + "_tooltip");
		    if (ttDiv)
		        ttDiv.parentElement.removeChild(ttDiv);
		    var puDiv = document.getElementById(markerID + "_popup");
		    if (puDiv)
		        puDiv.parentElement.removeChild(puDiv);
		}
		this.clearMapMarkers();
		_SEMap_CurrentPopupDiv = null;
		_SEMap_CurrentTooltipDiv = null;
		_SEMap_CurrentPushpin = null;
	}

	function _SEMap_AddMarker(markerIndex, contentHtml, htmlPageUrl, latlong, currentMap, markerTitle, tooltipHtml)
	{
		var markerId = this.createMarkerID(markerIndex);
		var onClick = "";
		var onMouseOver = "";
		var onMouseOut = "";

		if (this.enableMouseOverHighlight)
		{
			onMouseOver = this.id + ".highlightPushpin('" + markerIndex + "', true, 'notpopup');";
			if (this.mouseOverAction == "nothing")
				onMouseOut = " setTimeout('" + this.id + ".highlightPushpin(" + markerIndex + ", false, _SEMap_Popup)'," +  this.closePopupAfter + "); ";
		}

		switch (this.mouseOverAction)
		{
			case "popup":
				onMouseOver = onMouseOver + this.id + ".openPopup(" + markerIndex + ", " + this.closePopupAfter + ");";
				onMouseOut = onMouseOut + "if(_SEMap_CurrentPopupDiv){clearTimeout(_SEMap_CurrentPopupDiv.closeTimeoutId);_SEMap_CurrentPopupDiv.closeTimeoutId=setTimeout('_SEMap_CloseDiv(' + _SEMap_CurrentPopupDiv.id + ',false)', " +  this.closePopupAfter + ");}";
				break;
			case "tooltip":
				onMouseOver = onMouseOver +  this.id + ".showTooltip(" + markerIndex + ", " +  this.closePopupAfter + ")";
				onMouseOut = onMouseOut + "if(_SEMap_CurrentTooltipDiv){clearTimeout(_SEMap_CurrentTooltipDiv.closeTimeoutId);_SEMap_CurrentTooltipDiv.closeTimeoutId=setTimeout('_SEMap_CloseDiv(' + _SEMap_CurrentTooltipDiv.id + ',false)', " +  this.closePopupAfter + ");}";
				break;
		}

		if (this.enableClickPopup)
			onClick = " onmousedown=\"" + this.id + ".openPopup(" + markerIndex + ", " + this.closePopupAfterClick + ");\"" ;

		onMouseOver = " onmouseover=\"" + onMouseOver + "\"";
		onMouseOut = " onmouseout=\"" + onMouseOut + "\"";
		if (! _SEMap_UserAgent("msie"))
		{
			tooltipHtml = "<table border=0 cellpadding=0 cellspacing=0 id=" + markerId + "_tttable><tr><td nowrap >"
			+ tooltipHtml
			+ "</td></tr></table>";
		}

		// remove any previus marker		
		this.markers[markerIndex]._markerDiv = null;
		this.markers[markerIndex]._popupDiv = null;
		this.markers[markerIndex]._tooltipDiv = null;
		this.markers[markerIndex].tooltipHtml = tooltipHtml;

		var pinHtml = "<img src='" + this.markerIcon.src + "' id='" + markerId + "_img' border=0 "
				+  onClick + " " + onMouseOver + " " + onMouseOut + " status=''/>";
		if (this.vendor != "VirtualEarth6")
		{
		    pinHtml += "<br/>"
				+ "<div id='" + markerId + "_popup' style='display:none'>"
				+ contentHtml
				+ "</div>"
				+ "<div id='" + markerId + "_tooltip' class=Tooltip style='display:none'>"
				+ tooltipHtml
				+ "</div>"
		}
		
		this._addPushpin(markerId,
			latlong.latitude,
			latlong.longitude,
			this.markerIcon.width,
			this.markerIcon.height,
			pinHtml,
			_SEMap_BaseZIndex, tooltipHtml)
	}

	function _SEMap_GetMarkerBounds(markers)
	{
		var bounds = null;
		if (markers.length > 1)
		{
			var minLat = markers[0].location.latitude;
			var maxLat = markers[0].location.latitude;
			var minLon = markers[0].location.longitude;
			var maxLon = markers[0].location.longitude;
			for (var i=0; i<markers.length; i++)
			{
				if (markers[i].location.latitude < minLat)
					minLat =  markers[i].location.latitude;
				if (markers[i].location.latitude > maxLat)
					maxLat = markers[i].location.latitude;
				if (markers[i].location.longitude < minLon)
					minLon = markers[i].location.longitude;
				if (markers[i].location.longitude > maxLon)
					maxLon = markers[i].location.longitude;
			}
			bounds = new SEBounds(new SEPoint(maxLat, minLon), new SEPoint(minLat, maxLon));
		}
		return bounds;
	}

	function _SEMap_DisableEvents()
	{
		this.eventsDisabled = true;
		setTimeout(this.id + ".enableEvents()", 3000);
	}
	function _SEMap_EnableEvents()
	{
		this.eventsDisabled = false;
	}

	function _SEMap_UpdateBounds()
	{
		var bounds = this.getBounds();
		if (bounds.northWest && document.getElementById(this.id.replace("_map", "_hidNWLat")))
		{
			document.getElementById(this.id.replace("_map", "_hidNWLat")).value = bounds.northWest.latitude;
			document.getElementById(this.id.replace("_map", "_hidNWLong")).value = bounds.northWest.longitude;
			document.getElementById(this.id.replace("_map", "_hidSELat")).value = bounds.southEast.latitude;
			document.getElementById(this.id.replace("_map", "_hidSELong")).value = bounds.southEast.longitude;
			this.zoomLevel = this.getZoomLevel();
			document.getElementById(this.id.replace("_map", "_hidZoomLevel")).value = this.zoomLevel;
		}
	}

	function _SEMap_IsBigMove()
	{
		if (!this.isLoading)
		{
			var currentBounds = new SEBounds(new SEPoint(document.getElementById(this.id.replace("_map", "_hidNWLat")).value,
				document.getElementById(this.id.replace("_map", "_hidNWLong")).value),
				new SEPoint(document.getElementById(this.id.replace("_map", "_hidSELat")).value,
				document.getElementById(this.id.replace("_map", "_hidSELong")).value));
			var newBounds = this.getBounds();
			var deltaLat = currentBounds.northWest.latitude - currentBounds.southEast.latitude;
			var deltaLong = currentBounds.southEast.longitude - currentBounds.northWest.longitude;
			return (
				(Math.abs(currentBounds.northWest.latitude - newBounds.northWest.latitude)/deltaLat > .1)
				|| (Math.abs(currentBounds.southEast.latitude - newBounds.southEast.latitude)/deltaLat > .1)
				|| (Math.abs(currentBounds.northWest.longitude - newBounds.northWest.longitude)/deltaLong > .1)
				|| (Math.abs(currentBounds.southEast.longitude - newBounds.southEast.longitude)/deltaLong > .1)
			);
		}
		return true;
	}
	
	function _SEMap_ClosePopups()
	{
	    if (_SEMap_CurrentPopupDiv)
			_SEMap_CurrentPopupDiv.close(_SEMap_CurrentPopupDiv, true);
	    if (_SEMap_CurrentTooltipDiv)
			_SEMap_CurrentTooltipDiv.close(_SEMap_CurrentTooltipDiv, true);
	}

	function _SEMap_RecenterOnSelection()
	{
		this.zoomLevel = this.getZoomLevel();
		if (_SEMap_CurrentPopupDiv)
			_SEMap_CurrentPopupDiv.close(_SEMap_CurrentPopupDiv, true);
		if (_SEMap_CurrentPushpin)
			this.setCenterZoom(this.markers[_SEMap_CurrentPushpin.markerIndex].location, this.zoomLevel);
	}

	// static stuff
	function SEMap_OnResize(mapID)
	{
		if (_SEMap_ResizeTimeoutId) return;

		if (mapID)
			var map = eval(mapID);
		else
			map = SEMap_GetCurrentMap();

		if(map && !map.isLoading)
			_SEMap_ResizeTimeoutId = setTimeout('SEMap_Resize(' + map.id + ')', 200);

		map._mapDivWidth = map._mapDiv.offsetWidth;
		map._mapDivHeight = map._mapDiv.offsetHeight;
	}

	function SEMap_Resize(mapID)
	{
    var map = null;
    if (mapID)
			map = eval(mapID);
		else
			map = SEMap_GetCurrentMap();
		if (map && !map.isLoading)
		{
			_SEMap_ResizeTimeoutId = null;
			map._reSize();
			map.functionToCallOnZoom();
		}
	}

	function SEMap_OnScroll(map, isScrolling)
	{
		if(!map)
			return;
		if (map.vendor.indexOf("VirtualEarth") > -1)
		{
			if (_SEMap_UserAgent('opera') || _SEMap_UserAgent('firefox'))
				return;

     var mapElement = null;
     if (_SEMap_UserAgent('msie'))
				mapElement = document.getElementById(map.id.replace("_map", "_td"));
			else
				mapElement = map._mapDiv;

			if(mapElement == null)
				return;

			if (_SEMap_NoScrollDiv == null)
			{
				_SEMap_NoScrollDiv=document.createElement("div");
				_SEMap_NoScrollDiv.style.position = "absolute";
				_SEMap_NoScrollDiv.style.left = "0px";
				_SEMap_NoScrollDiv.style.top = "0px";

				_SEMap_NoScrollDiv.style.width = mapElement.clientWidth + "px";
				_SEMap_NoScrollDiv.style.height = mapElement.clientHeight + "px";

				_SEMap_NoScrollDiv.style.backgroundColor = "white";
				_SEMap_NoScrollDiv.style.filter = "alpha(opacity=.01)";
				_SEMap_NoScrollDiv.style.MozOpacity =.01;
				_SEMap_NoScrollDiv.style.opacity = .01;
				_SEMap_NoScrollDiv.style.zIndex = "1999";
				mapElement.appendChild(_SEMap_NoScrollDiv);
				_SEMap_ScrollTimeoutId = setTimeout('SEMap_OnScroll(' + map.id + ',false)', 1000);
			}
			else if (isScrolling == false)
			{
				mapElement.removeChild(_SEMap_NoScrollDiv);
				_SEMap_NoScrollDiv = null;
			}
			else
			{
				clearTimeout(_SEMap_ScrollTimeoutId);
				_SEMap_ScrollTimeoutId = setTimeout('SEMap_OnScroll(' + map.id + ',false)', 1000);
			}
		}
	}

	function _SEMap_FitMarkers()
	{
		if (this.markers && this.markers.length == 1)
		{
			this.isOpeningWindow = true;
			this.setCenterZoom(this.markers[0].location, this.zoomLevel);
			this.isOpeningWindow = false;
		}
		else
		{
			var bounds = _SEMap_GetMarkerBounds(this.markers);
			if (bounds != null)
			{
				this.isOpeningWindow = true;
				this.setBestMapView(bounds);
				this.zoomLevel = this.getZoomLevel()
				this.isOpeningWindow = false;
			}
        }
        this.updateBounds();
	}

	function _SEMap_getObjectTop(refobj)
	{
		var y = 0;
		if (refobj)
		{
			if (refobj.offsetTop)
				y = refobj.offsetTop;
			var obj = refobj.offsetParent;
			while (obj != null) {
				y += obj.offsetTop;
				obj = obj.offsetParent;
			}
		}
		return y;
	}

	function _SEMap_FindByClass(sTagName, eClass, multiple)
	{
		var elements = document.getElementsByTagName(sTagName);
		var found = new Array();
		for (i=0; i<elements.length; i++)
		{
			if (elements[i].className.toLowerCase().indexOf(eClass.toLowerCase()) != -1)
			{
				if (!multiple)
					return elements[i];
				else
					found[found.length] = elements[i];
			}
		}
		if (!multiple)
			return null;
		else
			return found;
	}

	function _SEMap_getObjectLeft(refobj)
	{
		var x = 0;
		if (refobj)
		{
			if (refobj.offsetLeft)
				x = refobj.offsetLeft;
			if (refobj && refobj.offsetParent)
			var obj = refobj.offsetParent;
			while (obj) {
				x += obj.offsetLeft;
				obj = obj.offsetParent;
			}
		}
		return x;
	}

	function _SEMap_getContainerWidth(map)
	{
		return document.getElementById(map.id.replace("_map", "_td")).clientWidth;
	}

	function _SEMap_getContainerHeight(map)
	{
		return document.getElementById(map.id.replace("_map", "_td")).clientHeight;
	}

	function _SEMap_isInBounds(x, xMin, xMax)
	{
		if ((x < xMax) && (x > xMin))
			return true;
		return false;
	}

	function _SEMap_IsInDiv(div)
	{
		if (div)
		{
			var map = SEMap_GetCurrentMap();
			var divLeft = _SEMap_getObjectLeft(div);
			var divTop = _SEMap_getObjectTop(div);
			return (
				(map._mouseTracker.mousex < divLeft + div.offsetWidth)
				&& (map._mouseTracker.mousex > divLeft)
				&& (map._mouseTracker.mousey < divTop + div.offsetHeight)
				&& (map._mouseTracker.mousey > divTop)
			)	;
		}
		else
			return true;
	}

	function _SEMap_GetXmlHttp()
	{
		if (!SEMap_HttpRequest)
		{
			var x=null;
			try
			{
				x=new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(e)
			{
				try
				{
					x=new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch(exc)
				{
					x=null;
				}
			}
			if(!x&&typeof XMLHttpRequest!="undefined")
			{
				x=new XMLHttpRequest();
			}
			return x;
		}
		else
			return SEMap_HttpRequest;
	}

	function SEMap_GetHtmlPage(url, returnFunction)
	{
		SEMap_HttpRequest = _SEMap_GetXmlHttp();
		if (SEMap_HttpRequest)
		{
			if (SE_UserAgent('gecko'))
			    SEMap_HttpRequest.abort();
			SEMap_HttpRequest.open('GET', url, true);
			SEMap_HttpRequest.onreadystatechange = returnFunction;
			SEMap_HttpRequest.send(null);
		}
	}

	function _SEMap_GetHtmlIsIdle()
	{
		return (!SEMap_HttpRequest || (SEMap_HttpRequest.readyState == 0) || (SEMap_HttpRequest.readyState == 4));
	}

	function _SEMap_UserAgent(userAgentText)
	{
		var _userAgent = navigator.userAgent.toLowerCase();
		if (userAgentText == "msie")
			return (_userAgent.indexOf(userAgentText) != -1) && (_userAgent.indexOf('opera') == -1) ;
		else
			return _userAgent.indexOf(userAgentText) != -1;
	}

	// icon and popup methods
	function _SEMap_ShowTooltip(markerIndex, closePopupAfter)
	{
		if (this.drawIsDrawing)   return;
		
		var map = SEMap_GetCurrentMap();
		
		if (_SEMap_CurrentPopupDiv && _SEMap_CurrentPopupDiv.isShowing && (_SEMap_CurrentPopupDiv.markerIndex == markerIndex) )
			return;

		if (_SEMap_CurrentTooltipDiv && _SEMap_CurrentTooltipDiv.isShowing && (_SEMap_CurrentTooltipDiv.markerIndex == markerIndex) )
			return;

		if (map)
		{
			var marker = map.markers[markerIndex];
			if (marker._isVisible())
			{			
			    var puDiv = map._setCurrentPopupDiv(_SEMap_CurrentTooltipDiv, "_tooltip", markerIndex, closePopupAfter);
			    puDiv.close = map.closeDiv;
			    puDiv.margin = 5;
			    puDiv.isPopup = false;
			    puDiv.contentCell = null;
			    var markerId = map.createMarkerID(markerIndex);
			    puDiv.popupTable = document.getElementById(markerId + "_tttable");
			    puDiv.style.width = null;
			    _SEMap_CurrentTooltipDiv = puDiv;
    			
			    _SEMap_ShowPopup(puDiv);

			    // external callback function
			    map.onTooltipOpen(markerIndex);

			    // pre-load the popup
			    if (!marker._popupDiv &&  _SEMap_GetHtmlIsIdle())
				    marker._popupDiv = map.initializePopupDiv(marker._popupDiv, markerIndex, closePopupAfter, true);
		    }
		}
	}

	function _SEMap_LoadPopupDiv(markerIndex, isLoadOnly)
	{
		var marker = this.markers[markerIndex];

		// if we don't have the marker html - get it, save it as text and in a div
		if (SEMap_HttpRequest && (SEMap_HttpRequest.readyState == 4) )
		{
			marker.popupHtml = SEMap_HttpRequest.responseText;
			if (marker && (typeof(marker._popupDiv) == 'undefined' || !marker._popupDiv))
			    marker._getPopupDiv(markerIndex, "_popup");
			marker._popupDiv.isLoaded = this._loadMarkerDivText(marker._popupDiv, marker.popupHtml);
		}

		// create and load the marker div if necessary
		if (typeof(marker._popupDiv) != 'undefined' && marker._popupDiv && marker._popupDiv.innerHTML && !isLoadOnly)
		{
			// execute the js in the innerHTML that is being passed back
			if (_SEMap_CurrentPopupDiv && _SEMap_CurrentPopupDiv.loadingTimeoutID)
				clearTimeout(_SEMap_CurrentPopupDiv.loadingTimeoutID);
			if (this.updateMsgDiv) this.showUpdatingMsg(false);

			_SEMap_CurrentPopupDiv = marker._popupDiv;
			if (marker._popupDiv && marker._popupDiv.contentCell && (marker._popupDiv.contentCell.innerHTML != ""))
			{
				_SEMap_GetExecReturnedJS(marker._popupDiv);
				_SEMap_ShowPopup(_SEMap_CurrentPopupDiv);
			}
		}
	}

	function _SEMap_GetExecReturnedJS(contentElement)
	{
		var jsPopup  = "";
		if (contentElement)
		{
			var jsNode = SEMap_FindChildNode(contentElement, "PopupJS");
			if (jsNode)
			{
				jsPopup = jsNode.innerHTML;
				if (_SEMap_UserAgent("opera") )
				{
					jsPopup = jsPopup.HTMLDecode();
					jsNode.parentNode.removeChild(jsNode);
				}
			}
		}
		eval(jsPopup);
	}

	function SEMap_LoadReturnedText(contentElement)
	{
		if ((SEMap_HttpRequest.readyState == 4) && (contentElement))
		{
			var retText = SEMap_HttpRequest.responseText;
			contentElement.innerHTML = retText;
			_SEMap_GetExecReturnedJS(contentElement);
			return true;
		}
	}

	function _SEMap_SetCurrentPopupDiv(currentDiv, typeSuffix, markerIndex, closePopupAfter)
	{
		if (this._mouseTracker && this._mouseTracker.startTracking)
			return;

		if (currentDiv)
		{
			if (currentDiv.markerIndex != markerIndex)
			{
				currentDiv.close(currentDiv, true);
			}
		}

		marker = this.markers[markerIndex];
		currentDiv = marker._getPopupDiv(markerIndex, typeSuffix);

		// unless we are over something that is intentionally preventing the close (e.g. a link)
		if (currentDiv) currentDiv.dontClose = false;
		if (currentDiv && currentDiv.marker && (typeSuffix == "_popup"))
		{
			// we have already saved this one - just make it current and reposition it
		}
		else
		{
			// create and remember this marker's div
			marker._createPopupDiv(markerIndex, closePopupAfter, typeSuffix);
			currentDiv = marker._getPopupDiv(markerIndex, typeSuffix);
		}

		this.highlightPushpin(markerIndex, true, "popup");
		// prevent closing immediately upon opening (happens because the mapDiv click seems to fall through sometimes)
		currentDiv.openTime = new Date().getTime();

		return currentDiv;
	}


	function _SEMap_CreatePopupDiv(markerIndex, closePopupAfter, typeSuffix)
	{
		//marker method
		var puDiv = this._getPopupDiv(markerIndex, typeSuffix);
		puDiv.close = this.map.closeDiv;
		puDiv.closePopupAfter = closePopupAfter;

		puDiv.map = this.map;
		puDiv.marker = this;
		puDiv.markerIndex = markerIndex;
		puDiv.marker._setZIndex(markerIndex, _SEMap_PopupZIndex);
		puDiv.offsetBottom = 5;
		puDiv.offsetRight = 5;
		puDiv.effectiveImageWidth =  this.map.markerIcon.width/2 - puDiv.offsetRight;
		puDiv.effectiveImageHeight =  this.map.markerIcon.height/2  - puDiv.offsetBottom;
	}

	function _SEMap_HasCurrentPopup()
	{
		return (_SEMap_CurrentPopupDiv && _SEMap_CurrentPopupDiv.isPopup);
	}

	function _SEMap_OpenPopup(markerIndex, closePopupAfter, loadOnly)
	{
		SE_CancelEvent(window.event);
		if (this.drawIsDrawing) 
		    return;
		var puDiv = _SEMap_CurrentPopupDiv;

		if (puDiv && puDiv.isShowing && puDiv.isPopup && (puDiv.markerIndex == markerIndex) )
			return;

		if (puDiv)
		{
			clearTimeout(_SEMap_CurrentPopupDiv.loadingTimeoutID);
			if (this.updateMsgDiv) this.showUpdatingMsg(false);
			puDiv.style.display = "none";
			_SEMap_CurrentPopupDiv = null;
			_SEMap_UnHighlightPushpin(puDiv.map, markerIndex);
		}
		if (_SEMap_CurrentTooltipDiv) _SEMap_CurrentTooltipDiv.close(_SEMap_CurrentTooltipDiv, true);

		puDiv = SEMap_GetCurrentMap()._setCurrentPopupDiv(puDiv, "_popup", markerIndex, closePopupAfter);
		_SEMap_CurrentPopupDiv = puDiv ;
		if(!(puDiv.isLoaded && puDiv.isPopup))
			puDiv = SEMap_GetCurrentMap().initializePopupDiv(puDiv, markerIndex, closePopupAfter, loadOnly);

		if (puDiv && puDiv.contentCell )
		{
		    var tries = 0;
		    while (puDiv.contentCell.innerHTML == "" && tries < 4)
	        {
	            SE_JSDelay(1000);
	            tries++;
	        }
			
			if (puDiv.contentCell.innerHTML != "")
			{
			    _SEMap_GetExecReturnedJS(puDiv.contentCell);			   
			    _SEMap_ShowPopup(puDiv);
			    this.onPopupOpen(markerIndex);			   
			}
		}
		else
		    window.status = 'no content yet'
	}

	function _SEMap_InitializePopupDiv(puDiv, markerIndex, closePopupAfter, loadOnly) {
	    
	    if (document.getElementById("tbPopup")) {
	        if (puDiv == null) {
	            marker = this.markers[markerIndex];
	            marker._createPopupDiv(markerIndex, closePopupAfter, "_popup");

	            puDiv = marker._getPopupDiv(markerIndex, "_popup");
	        }
	        puDiv.map = this;
	        puDiv.innerHTML = "";
	        puDiv.className = 'PopupDiv';
	        puDiv.isPopup = true;
	        puDiv.isShowing = false;
	        puDiv.isLoaded = false;
	        puDiv.margin = 15;
	        puDiv.popupTable = document.getElementById("tbPopup").cloneNode(true);
	        puDiv.popupTable.id = this.createMarkerID(markerIndex) + "_table";
	        puDiv.appendChild(puDiv.popupTable);
	        puDiv.contentCell = SEMap_FindChildNode(puDiv.popupTable, puDiv.map.id.replace("_map", "_popupContent"));

	        if ((puDiv.marker.htmlPageUrl != "") && (puDiv.marker.popupHtml == "")) {
	            // add the specific format for this page
	            var targetURLQS = puDiv.marker.htmlPageUrl.trim().split("?");
	            var targetURL = targetURLQS[0];
	            var targetOldQS = "";
	            if (targetURLQS.length > 1)
	                targetOldQS = targetURLQS[1];
	            
	            var targetQS = "companyid=" + puDiv.map.companyID
				    + "&userid=" + puDiv.map.userID
				    + "&officeid=" + puDiv.map.officeID
				    + "&homepageid=" + puDiv.map.homepageID
				    + "&pageformat=" + puDiv.map.popupFormat
				    + "&sourceapp=" + puDiv.map.sourceApp
				    + "&propertyDetailUrl=" + puDiv.map.propertyDetailUrl
				    + "&requestShowingUrl=" + puDiv.map.requestShowingUrl
				    + "&isPublic=" + puDiv.map.isPublic
				    + "&contactid=" + puDiv.map.contactID;

	            targetURL += SE_BuildQueryStringWithoutDups(targetOldQS, targetQS);
	            
	            if (!loadOnly) {
	                if (puDiv.isPopup)
	                    puDiv.loadingTimeoutID = setTimeout(puDiv.map.id + '.showUpdatingMsg(true, "' + _SEMap_LoadingMsg + '")', 200);
	                SEMap_GetHtmlPage(targetURL, function() { SEMap_GetCurrentMap().loadPopupDiv(markerIndex, false); })
	            }
	            else {
	                SEMap_GetHtmlPage(targetURL, function() { SEMap_GetCurrentMap().loadPopupDiv(markerIndex, true); })
	            }
	        }
	        else if (puDiv.marker.popupHtml != "")
	            puDiv.contentCell.innerHTML = puDiv.marker.popupHtml;
	        return puDiv;
	    }
	}

	function _SEMap_OverDiv(e, div)
	{
		if(_SEMap_CurrentPopupDiv && (_SEMap_IsInDiv(_SEMap_CurrentPopupDiv)) && (!_SEMap_CurrentPopupDiv.dontClose))
		{
			div.map._disableDragging();
			clearTimeout(div.closeTimeoutId);
			div.dontClose = div.isPopup;
			div.map._detachMouseEvents();
			div.ondblclick=_SEMap_CancelEvent;
			if (!div.isPopup)
				div.map._mapDiv.onmousedown=function(){div.map.openPopup(div.markerIndex, div.map.closePopupAfter);}
			else
				div.map._mapDiv.onmousedown=_SEMap_NOP;
		}
	}
	function _SEMap_OutofDiv(e, div)
	{
		if(div && (!_SEMap_IsInDiv(div)))
		{
			div.map._enableDragging();
			div.dontClose=false;
			clearTimeout(div.closeTimeoutId);
			if (div.closePopupAfter)
				div.closeTimeoutId = setTimeout('_SEMap_CloseDiv(' + div.id + ', false)',  div.closePopupAfter );
			div.map._attachMouseEvents();
			div.ondblclick=function(){}
			if (div.map && div.map._mapDiv && div.close)
				div.map._mapDiv.onmousedown=function(){div.close(div, true);}
		}
	}

	function _SEMap_CreateMarkerID(markerIndex)
	{
		return this.id + "_m" + markerIndex;
	}

	function _SEMap_GetMarkerImage(markerIndex)
	{	// marker method
		return  document.getElementById(this.map.createMarkerID(markerIndex) + '_img');
	}

	function _SEMap_GetMarkerDiv(markerIndex)
	{	// marker method
		if (!this._markerDiv)
			this._markerDiv = document.getElementById(this.map.createMarkerID(markerIndex));
		return this._markerDiv;
	}

	function _SEMap_GetPopupDiv(markerIndex, puType)
	{	// marker method
		if (puType == "_popup")
        {
			if (!this._popupDiv)
				this._popupDiv = document.getElementById(this.map.createMarkerID(markerIndex) + "_popup");
			return this._popupDiv;
        }
		else
        {
			if (!this._tooltipDiv)
			    this._tooltipDiv = document.getElementById(this.map.createMarkerID(markerIndex) + "_tooltip");
			return this._tooltipDiv;
        }
    }

    function _SEMap_HighlightAndTootip(markerIndex, isHighlight, callSource)
	{
	    this.highlightPushpin(markerIndex, isHighlight, callSource);			
	    if (isHighlight)
	        this.showTooltip(markerIndex, this.closePopupAfter);
	}

	function _SEMap_HighlightPushpin(markerIndex, isSelected, callSource)
	{
        // loop thorugh images, current div should be highighted, current pushpin should be highlighted
		// unless arguments overrule setting
		var needNew = true;
		if (callSource == "popup")
		{
			if (!isSelected)
			{
				_SEMap_UnHighlightPushpin(this, markerIndex);
				needNew = false;
			}
		}
		else
		{
		
			// we don't always get a mouseout to unhighlight the marker - so loop through them all and unhighlight appropriately
			for (var i=0; i<this.markers.length; i++)
			{
				if (_SEMap_CurrentPopupDiv &&  (i == _SEMap_CurrentPopupDiv.markerIndex) )
				{
					if (markerIndex != _SEMap_CurrentPopupDiv.markerIndex)
					{
						// lower the curretn popup below the tooltips but above the icons
						_SEMap_CurrentPopupDiv.marker._setZIndex(markerIndex, _SEMap_PopupZIndex);
					}
					else
						needNew = false;
					continue;
				}
				else if ((i == markerIndex) && !isSelected)
				{
					_SEMap_UnHighlightPushpin(this, i);
					needNew = false;
				}
				else if  (i != markerIndex)
				{
					_SEMap_UnHighlightPushpin(this, i);
				}
			}
		}
		if (!needNew || this.drawIsDrawing)   return;
		

		// create a new current pushpin
		var pushpinImg;
		var marker = this.markers[markerIndex];
		
		if (isSelected && marker)
		{
			if (!marker._isVisible())
			{
			    _SEMap_ClosePopups();
			   
			}	
			else            
                _SEMap_HighlightIcon(this, markerIndex);
		}
	}	
	
	function _SEMap_HighlightIcon(myMap, markerIndex)
	{
	    var marker = myMap.markers[markerIndex];
		pushpinImg = myMap.markers[markerIndex]._getImage(markerIndex);		
	    if (pushpinImg)
	    {
		    marker._setZIndex(markerIndex, _SEMap_TooltipZIndex);
		    if (( _SEMap_CurrentPopupDiv) && (_SEMap_CurrentPopupDiv.markerIndex != markerIndex))
			    _SEMap_CurrentPopupDiv.marker._setZIndex(markerIndex, _SEMap_PopupZIndex);
            myMap._changeIconSrc(pushpinImg, myMap.markerIconSelected.src, markerIndex);
		}
	}

	function _SEMap_ChangeIconSource(pushpinImg, newSrc, markerIndex)
	{
		 if (!_SEMap_IsSameUrl(pushpinImg.src, newSrc))
		{
		    pushpinImg.src = newSrc;
		}
	}
	
	function _SEMap_IncludePointInView()
	{
	    return false;
	}
	
	function _SEMap_MarkerIsVisible()
	{
	    bounds = this.map.getBounds();
	    return (!(this.location.latitude > bounds.northWest.latitude
    	        || this.location.latitude < bounds.southEast.latitude
    	        || this.location.longitude < bounds.northWest.longitude
    	        || this.location.longitude > bounds.southEast.longitude))
    }
	
	function _SEMap_UnHighlightPushpin(map, markerIndex)
	{
		var pushpin = map.markers[markerIndex]._getImage(markerIndex);
		if (pushpin)
		{
			if (!_SEMap_IsSameUrl(pushpin.src, map.markerIcon.src))
			{
				if ((! _SEMap_CurrentPopupDiv) ||(_SEMap_CurrentPopupDiv.markerIndex != markerIndex))
				{
				
					map._changeIconSrc(pushpin, map.markerIcon.src, markerIndex);
					map.markers[markerIndex]._setZIndex(markerIndex, _SEMap_BaseZIndex);
				}
				else
					map.markers[markerIndex]._setZIndex(markerIndex, _SEMap_PopupZIndex);
			}
		}
	}

	function _SEMap_SetMarkerZIndex(markerIndex, zindex)
	{
		if (this.map.vendor == "VirtualEarth6")
		    VSetMarkerZIndex(this.map, this.map.createMarkerID(markerIndex), zindex);
		else if (this._getMarkerDiv(this.markerIndex) && this._getMarkerDiv(this.markerIndex).style.zIndex != zindex)
			this._getMarkerDiv(this.markerIndex).style.zIndex = zindex;

	}

	function _SEMap_ShowPopup(currentDiv)
	{
		if (currentDiv)
		{
			if (currentDiv.openTimeoutId)
				clearTimeout(currentDiv.openTimeoutId);

            currentDiv.map._loadDynamicFooterRow(currentDiv);

            currentDiv.map._positionPopupDiv(currentDiv);
            
			currentDiv.isShowing = true;
			if (currentDiv.closePopupAfter)
			    currentDiv.closeTimeoutId = setTimeout('_SEMap_CloseDiv(' + currentDiv.id + ',false)', currentDiv.closePopupAfter );
			else
				clearTimeout(currentDiv.closeTimeoutId);
		}
	}

	function _SEMap_ClosePopup(forceEvent)
	{
		_SEMap_CloseDiv(_SEMap_CurrentPopupDiv, forceEvent);
	}
	function _SEMap_CloseDiv(currentDiv, forceEvent)
	{
		var force = forceEvent;
		if (typeof forceEvent == "object")
			force = false;
		if (force && currentDiv) currentDiv.dontClose = false;

		if (currentDiv && !currentDiv.dontClose)
		{
			var puDiv = currentDiv;
			// prevent closing immediately upon opening (happens because the mapDiv click seems to fall through sometimes)
			if(currentDiv.openTime && currentDiv.isPopup)
			{
				if (((new Date().getTime() - currentDiv.openTime) < 200) || !currentDiv.isShowing)
					return;
			}

			if (_SEMap_IsInDiv(_SEMap_CurrentPushpin) && !force && currentDiv.map && currentDiv.map.closePopupAfter)
			{
				currentDiv.closeTimeoutId = setTimeout('_SEMap_CloseDiv(' + currentDiv.id + ',false)', currentDiv.map.closePopupAfter);
				return;
			}
			clearTimeout(currentDiv.closeTimeoutId);
			clearTimeout(currentDiv.openTimeoutId);
			if  (((!_SEMap_CurrentPopupDiv) || (_SEMap_CurrentPopupDiv == currentDiv)) && currentDiv.marker)
			{
				currentDiv.marker._setZIndex(currentDiv.markerIndex, _SEMap_BaseZIndex);
			}
			
			currentDiv.style.display = "none";
			currentDiv.isShowing = false;
			if (currentDiv.isPopup)
				_SEMap_CurrentPopupDiv = null;
			else
				_SEMap_CurrentTooltipDiv = null;

			if (currentDiv.map)
			{
				if (currentDiv.isPopup)

					currentDiv.map.onPopupClose(currentDiv.markerIndex);
				else
					currentDiv.map.onTooltipClose(currentDiv.markerIndex);

				currentDiv.map.highlightPushpin(currentDiv.markerIndex, false, "popup");
			}


			currentDiv = null;
		}
	}

	function _SEMap_PositionPopupDiv(puDiv)
	{
		if (puDiv)
		{
			puDiv.style.visibility = "hidden";
			puDiv.style.display = "block";
			var extraPixels = 0;
			if (puDiv.popupTable && ! _SEMap_UserAgent("msie"))
			{
				puDiv.style.width = (puDiv.popupTable.offsetWidth + extraPixels) + "px";
				//puDiv.style.height = (puDiv.popupTable.offsetHeight) + "px";
			}

			puDiv.map._getPopupDimensions(puDiv);
			// we need to get the top left corner in a known spot to start!
			// we put it at the top right corner of image marker
			
			puDiv.style.left = (puDiv.marker._left + puDiv.effectiveImageWidth ) + "px";
			puDiv.style.top = (puDiv.marker._top -  this.markerIcon.height) + "px";
			
			if (puDiv.isPopup)
				puDiv.style.top = (puDiv.marker._top  -(puDiv._height - puDiv.offsetBottom )) + "px";
			else
				puDiv.style.top = (puDiv.marker._top  -(puDiv._height - puDiv.offsetBottom )) + "px";
				
			if (puDiv.map.slideMapToShowMarker && puDiv.isPopup)
				_SEMap_SlideMapToShowMarker(puDiv);
			else
				_SEMap_SlideMarkerToFitMap(puDiv);
			
			_SEMap_SetPopupVisible(puDiv.map, puDiv);
		}
	}
	
	function _SEMap_SetPopupVisible(map, puDiv)
	{
	    if (!map._isPanning && puDiv) {
	        puDiv.style.visibility = "visible";
	        puDiv.style.zIndex = 9999;
	        $(".PopupTable").boxShadow(4, 4, 3, "#555555");            
	    }
	}

	function _SEMap_SlideMarkerToFitMap(puDiv)
	{
		// perform calculations relative to the map div
		// DO NOT use DOM.offset dimensions as this cause the page sizes to be calculated about .2 seconds per)
		if (puDiv) {
		    var map = puDiv.map;
			puDiv.map._getPopupDimensions(puDiv);
			// can it fit to top and right
			var rightOverlap = puDiv._left + puDiv._width - map._mapDivWidth;
			var leftExtraSpace = puDiv._left - (puDiv._width - puDiv.offsetRight) - puDiv.margin;
			if (rightOverlap > - puDiv.margin)
			{
				// not enough room on right - is there room on the left?
			    if (leftExtraSpace > 0) {
			        puDiv.style.left = (puDiv.marker._left
					    - (puDiv._width - puDiv.offsetRight)) + "px";
			    }
			    else {
			        if (map._mapDivWidth > puDiv._width + (2 * puDiv.margin))
			            puDiv.style.left = puDiv.marker._left
						    + (puDiv._left - puDiv.marker._left)
						    - rightOverlap - puDiv.margin;
			        else
			            puDiv.style.left = puDiv.marker._left
						    - (puDiv.marker._left - puDiv.margin);
			    }
			}
			var topOverlap = - puDiv._top;
			var bottomExtraSpace = (map._mapDivHeight - (puDiv.marker._top + puDiv._height - puDiv.offsetBottom));
			if (puDiv._top < - puDiv.margin)
			{
				// not enough room on top - is there room on the bottom?
				if (bottomExtraSpace > puDiv.margin)
					puDiv.style.top = puDiv.marker._top + puDiv.marker._height + "px";
				else
					if (map._mapDivHeight > puDiv._height + (2 * puDiv.margin))
						puDiv.style.top = puDiv.marker._top - (puDiv._height + puDiv.effectiveImageHeight) + topOverlap + puDiv.margin;
		if (puDiv.isPopup) {
		    puDiv.style.top = Math.max(parseInt(puDiv.style.top) - puDiv.marker._height, puDiv.margin) + "px";
		}
			}
			
		
			if (_SEMap_OverlapsDashboard(puDiv.map, puDiv))
			{
				if (puDiv.map.dashboard.width < puDiv.map.dashboard.height)
				{
				    _SEMap_FixHorizontalDashboardOverlap(puDiv);
                    if (_SEMap_OverlapsDashboard(puDiv.map, puDiv))
			            _SEMap_FixVerticalDashboardOverlap(puDiv);
			     }
			     else
			     {
				    _SEMap_FixVerticalDashboardOverlap(puDiv);
				    if (_SEMap_OverlapsDashboard(puDiv.map, puDiv))
			            _SEMap_FixHorizontalDashboardOverlap(puDiv);
			     }
			 }				
		 }
	}
	
	function _SEMap_FixHorizontalDashboardOverlap(puDiv)
	{
	    var leftOverlap = ((puDiv.map.dashboard.rightMargin + puDiv.map.dashboard.left) + puDiv.map.dashboard.width) - puDiv._left;
		if (leftOverlap > 0)
		{
			var newLeft = ((puDiv.map.dashboard.rightMargin + puDiv.map.dashboard.left) + puDiv.map.dashboard.width)  ;
			if (newLeft + puDiv._width < puDiv.map._mapDivWidth )
				puDiv.style.left = (newLeft ) + "px";
		}
	}
	
	function _SEMap_FixVerticalDashboardOverlap(puDiv)
	{
		topOverlap = (puDiv.map.dashboard.height + (puDiv.map.dashboard.bottomMargin + puDiv.map.dashboard.top)- puDiv._top)  ;
		if (topOverlap > 0)
		{
			var newTop = puDiv._top + topOverlap;
			bottomExtraSpace = puDiv.map._mapDivHeight - (newTop + puDiv._height + puDiv.margin);
			if (bottomExtraSpace > 0)
				puDiv.style.top = (newTop) +"px";
			else
				puDiv.style.top = "0px";
			if (puDiv.isPopup)
				puDiv.style.top = (parseInt(puDiv.style.top) - puDiv.marker._height) + "px";
		}
	}

	function _SEMap_SlideMapToShowMarker(puDiv) {
	    
		// put it in the middle just under the dashboard
		if (puDiv)
		{	    
			map = puDiv.map;
			puDiv.map._getPopupDimensions(puDiv);
			map.getDashboard();
			var deltaX = map._mapDiv.offsetWidth/2 - (puDiv.marker._left + puDiv.marker._width/2);
			var deltaY = (puDiv.map.dashboard.height + puDiv.map.dashboard.top + puDiv.margin) 
			    - (puDiv._top );

			if ((Math.abs(deltaX) > 5) || ((Math.abs(deltaY) > 5))) {
			    map._pan("", deltaX, -deltaY, _SEMap_MovePopupAfterPan);
			    _SEMap_MovePopupAfterPan();
			}
			else
			    _SEMap_MovePopupAfterPan();
			if (map.vendor != "VirtualEarth6")
			    _SEMap_MovePopupAfterPan()
		}
	}

    function _SEMap_MovePopupAfterPan()
    {
        myMap = SEMap_GetCurrentMap();
        VClearEndPanCallback(myMap);
        if(_SEMap_CurrentPopupDiv)
		{
            var puDiv = _SEMap_CurrentPopupDiv;
            myMap._getPopupDimensions(puDiv);
	        puDiv.style.left = (puDiv.marker._left - (puDiv._width - puDiv.marker._width )/2) + "px";
	        puDiv.style.top =  (puDiv.marker._top - (puDiv._height - puDiv.offsetBottom))  + "px";
	        
	        _SEMap_SetPopupVisible(myMap, puDiv);
	    }
    }
    
	function _SEMap_OverlapsDashboard(map, div)
	{
		if (div && ! map.vendor == 'VirtualEarth6')
		{
			map._getPopupDimensions(div);
			map.getDashboard();
			if (
				( div._left <  (map.dashboard.left + map.dashboard.width)) &&
				( div._top <  (map.dashboard.top + map.dashboard.height))
				)
					return true;
		}
		return false;
	}

	function _SEMap_GetPopupDimensions(puDiv)
	{
		// set dimensions relative to map div
		if (puDiv)
		{
			this._getMapDimensions();
			this._getMarkerDimensions(puDiv);
			
			if (puDiv.style.top != "")
			{
			    puDiv._top = parseInt(puDiv.style.top) ;
			    puDiv._left = parseInt(puDiv.style.left) ;
			}
			else
			{
			    puDiv._top = 0;
			    puDiv._left = 0;
			}
			
			if (puDiv.isPopup && puDiv.isLoaded)
			{
				if (!puDiv.marker.previousHeight)
				{
					puDiv._height = puDiv.offsetHeight;
					puDiv.marker.previousHeight = puDiv._height;
				}
				else
					puDiv._height = puDiv.marker.previousHeight;
				puDiv._width = this.popupTableWidth;
			}
			else
			{
				puDiv._height = puDiv.offsetHeight;
				puDiv._width = puDiv.offsetWidth;
			}
		}
	}
    function _SEMap_GetMapDimensions()
	{
	    this._mapDivOffsetX = 0;
	    this._mapDivOffsetY = 0;
	}
	
	function _SEMap_GetMarkerDimensions(puDiv)
	{
		// set dimensions relative to map div
		// icon is centered on point
		var myMarker = puDiv.marker;
		var xy = this._getXY(myMarker.location);
		myMarker._top = xy.y - myMarker.map.markerIcon.height/2;
		myMarker._left = xy.x - myMarker.map.markerIcon.width/2;
		myMarker._width =  myMarker.map.markerIcon.width;
		myMarker._height = myMarker.map.markerIcon.height;
	}

	function _SEMap_MouseTracker(map)
	{
		this.map = map;
		this.mapObject;
		this.mapx1;
		this.mapx2;
		this.mapy1;
		this.mapy2;
		this.maparea;
		this.zoomx1;
		this.zoomy1;
		this.zoomx2;
		this.zoomx2;
		this.zoomarea;
		this.mapwidth;
		this.mapheight;
		this.mousex;
		this.zoomLayer;
		this.startTracking = false;
		this.gpstart;
		this.multiplier;

		this.zoomLayer = document.getElementById(map.namePrefix + "ZoomLayer");
		if (this.zoomLayer)
		    this.zoomLayer.style.visibility = "hidden";
		this.mapx1 = _SEMap_getObjectLeft(this.map._mapDiv);
		this.mapy1 = _SEMap_getObjectTop(this.map._mapDiv);
		this.mapwidth = parseFloat(this.map._mapDiv.clientWidth);
		this.mapheight = parseFloat(this.map._mapDiv.clientHeight);
		this.mapx2 = this.mapx1 + this.mapwidth;
		this.mapy2 = this.mapy1 + this.mapheight;
	}

	function _SEMap_SetValidZoomArea(e)
	{
		var mouseTracker = SEMap_GetCurrentMap()._mouseTracker;
		if (!_SEMap_UserAgent('safari'))
		{
			mouseTracker.mousex = e.clientX + document.body.scrollLeft;
			mouseTracker.mousey = e.clientY + document.body.scrollTop;
		}
		else
		{
			mouseTracker.mousex = e.clientX;
			mouseTracker.mousey = e.clientY;
		}

		if (mouseTracker.mousex > mouseTracker.mapx2) mouseTracker.mousex = mouseTracker.mapx2;
		if (mouseTracker.mousex < mouseTracker.mapx1) mouseTracker.mousex = mouseTracker.mapx1;
		if (mouseTracker.mousey < mouseTracker.mapy1) mouseTracker.mousey = mouseTracker.mapy1;
		if (mouseTracker.mousey > mouseTracker.mapy2) mouseTracker.mousey = mouseTracker.mapy2;
	}

	function _SEMap_MouseOutHandler()
	{
		_SEMap_StopDrag();
	}

	function SEMap_GetCurrentMap(e)
	{
		if (!e) e = window.event;
		if (e)
		{
      var mousex;
      var mousey;
      for (i=0; i<SEMaps.length ; i++)
			{
//				if (!_SEMap_UserAgent("safari"))
//				{
					mousex = e.clientX + document.body.scrollLeft;
					mousey = e.clientY + document.body.scrollTop;
//				}
//				else
//				{
//					mousex = e.clientX;
//					mousey = e.clientY;
//				}
					if (!SEMaps[i])
					    continue;
				var div = SEMaps[i]._mapDiv;
				var divLeft = _SEMap_getObjectLeft(div);
				var divTop = _SEMap_getObjectTop(div);
				if (
					(mousex < divLeft + div.clientWidth)
					&& (mousex > divLeft)
					&& (mousey < divTop + div.clientHeight)
					&& (mousey > divTop)
				)
				{
					_SEMap_CurrentMap = SEMaps[i];
					return _SEMap_CurrentMap;
				}
			}
		}
		if(!_SEMap_CurrentMap && (SEMaps.length > -1))
			_SEMap_CurrentMap = SEMaps[0];
		return _SEMap_CurrentMap;
	}

	function _SEMap_MouseMoveHandler(e)
	{
		if (!e) e = window.event;

		_SEMap_CurrentMap = SEMap_GetCurrentMap(e);
		if (!_SEMap_CurrentMap || !_SEMap_CurrentMap._mouseTracker)
		        return;
		var mouseTracker = _SEMap_CurrentMap._mouseTracker;

		if (!_SEMap_UserAgent("safari"))
		{
			mouseTracker.mousex = e.clientX + document.body.scrollLeft;
			mouseTracker.mousey = e.clientY + document.body.scrollTop;
		}
		else
		{
			mouseTracker.mousex = e.clientX;
			mouseTracker.mousey = e.clientY;
		}
		if (!mouseTracker.startTracking )
		{
			if(_SEMap_CurrentPopupDiv)
			{
				if (!_SEMap_IsInDiv(_SEMap_CurrentPopupDiv))
					_SEMap_OutofDiv(e, _SEMap_CurrentPopupDiv);
				else
					_SEMap_OverDiv(e, _SEMap_CurrentPopupDiv);
			}
			return;
		}

		if ((_SEMap_isInBounds(mouseTracker.mousex, mouseTracker.mapx1, mouseTracker.mapx2))
			&& (_SEMap_isInBounds(mouseTracker.mousey, mouseTracker.mapy1, mouseTracker.mapy2)))
		{
			_SEMap_SetValidZoomArea(e);

			var w = parseFloat(mouseTracker.mousex) - parseFloat(mouseTracker.zoomx1);
			var h = parseFloat(mouseTracker.mousey) - parseFloat(mouseTracker.zoomy1);

			if (w < 0) {
				w = Math.abs(w);
				mouseTracker.zoomLayer.style.left = mouseTracker.mousex;
			}
			mouseTracker.zoomLayer.style.width = w;

			if (h < 0) {
				h = Math.abs(h);
				mouseTracker.zoomLayer.style.top = mouseTracker.mousey;
			}
			mouseTracker.zoomLayer.style.height = h;
		}
		else
		{
			_SEMap_MouseOutHandler();
		}
	}

	function _SEMap_KeyDownHandler(e)
	{
		if (!e) e = window.event;
		mouseTracker = SEMap_GetCurrentMap()._mouseTracker;
		if (e.keyCode == _SEMap_ZOOMAREA_KEYCODE)
		    SE_CancelEvent(e)
		return;
        
        if ((mouseTracker.startTracking == false)
			&& ((e.keyCode == _SEMap_ZOOMAREA_KEYCODE) || (_SEMap_UserAgent("safari")))
			&& !SEMap_IsDraggingMap)
		{

			mouseTracker.zoomx1 = mouseTracker.mousex;
			mouseTracker.zoomy1 = mouseTracker.mousey;
			if ((_SEMap_isInBounds(mouseTracker.zoomx1, mouseTracker.mapx1, mouseTracker.mapx2))
				&& (_SEMap_isInBounds(mouseTracker.zoomy1, mouseTracker.mapy1, mouseTracker.mapy2)))
			{
				// we need to track the time make sure we don't treat clicks as drags in safari
				if (_SEMap_UserAgent('safari')) 	_SEMap_MouseTimer = new Date();

				mouseTracker.startTracking = true;
				mouseTracker.gpstart = mouseTracker.map._getLatLonFromPixel(mouseTracker.zoomx1 - mouseTracker.mapx1, mouseTracker.zoomy1 - mouseTracker.mapy1);
				mouseTracker.map._disableDragging();
				mouseTracker.zoomLayer.style.visibility = "visible";
				mouseTracker.zoomLayer.style.left = mouseTracker.zoomx1;
				mouseTracker.zoomLayer.style.top = mouseTracker.zoomy1;
				mouseTracker.zoomLayer.style.width = 0;
				mouseTracker.zoomLayer.style.height = 0;
				document.body.style.cursor = "crosshair";
			}
		}
	}

	function _SEMap_StopDrag()
	{
		_SEMap_CurrentMap._mouseTracker.startTracking = false;
		_SEMap_CurrentMap._mouseTracker.zoomLayer.style.visibility = "hidden";
		document.body.style.cursor = "default";
	}

	function _SEMap_KeyUpHandler(e)
	{
		SEMap_IsDraggingMap = false;

		mouseTracker = SEMap_GetCurrentMap()._mouseTracker;

		if (!mouseTracker.startTracking)
			return;
		if (!e) e = window.event;

		if ((e.keyCode != _SEMap_ZOOMAREA_KEYCODE) && (!(_SEMap_UserAgent("safari"))))
			return;

		_SEMap_StopDrag();

		if (_SEMap_MouseTimer)
		{
			// don't handle safari clicks as drag events (really fast or really small clicks)
			if (
				(_SEMap_MouseTimer == null)
				||((new Date()).getTime() - _SEMap_MouseTimer.getTime() < 175)
				||((Math.abs(mouseTracker.mousex - mouseTracker.zoomx1) < 10) && (Math.abs(mouseTracker.mousey - mouseTracker.zoomy1) < 10))
				)
			{
				// this is a probably a click
				_SEMap_MouseTimer = null;
				return;
			}
		}
		_SEMap_MouseTimer = null;

		if(typeof(mouseTracker.gpstart) == 'undefined')
			return;

		mouseTracker.zoomx2 = mouseTracker.mousex;
		mouseTracker.zoomy2 = mouseTracker.mousey;

		mouseTracker.gpend = mouseTracker.map._getLatLonFromPixel(mouseTracker.mousex - mouseTracker.mapx1, mouseTracker.mousey - mouseTracker.mapy1);

		var northWest = new SEPoint();
		var southEast = new SEPoint();
		if (mouseTracker.gpend.latitude > mouseTracker.gpstart.latitude)
		{
			northWest.latitude = mouseTracker.gpend.latitude;
			southEast.latitude = mouseTracker.gpstart.latitude;
		}
		else
		{
			southEast.latitude = mouseTracker.gpend.latitude;
			northWest.latitude = mouseTracker.gpstart.latitude;
		}
		if (mouseTracker.gpend.longitude > mouseTracker.gpstart.longitude)
		{
			southEast.longitude = mouseTracker.gpend.longitude;
			northWest.longitude = mouseTracker.gpstart.longitude;
		}
		else
		{
			northWest.longitude = mouseTracker.gpend.longitude;
			southEast.longitude = mouseTracker.gpstart.longitude;
		}
		mouseTracker.map.setBestMapView(new SEBounds(northWest, southEast));

		mouseTracker.map._enableDragging()	;
	}

	function SEMap_OpenPage(url,width,height)
	{
		if (_SEMap_LastPopupName == "")
			_SEMap_LastPopupName = 'winpop0';
		else
			_SEMap_LastPopupName = 'winpop' + parseInt(_SEMap_LastPopupName.replace('winpop', '')) + 1;

		if(width == undefined)
			width = "800";
		else
			width = width;

		if(height == undefined)
			height = "600";
		else
			height = height;

		var winPop = window.open(url, _SEMap_LastPopupName, 'fullscreen=no,toolbar=no,status=no,menubar=no,scrollbars=yes,resizable=yes,directories=no,location=no,width=' + width + ',height=' +  height + ',top=50,left=50', false);
		try
		{
			winPop.focus();
		}
		catch (e) {}
	}
	
	function SEMap_ClearDrawing()
    {
        var seMap = SEMap_GetCurrentMap();
        ctl = document.getElementById(seMap.id.replace("_map", "_btnClear"));
        seMap.drawDone(true);
        seMap.drawInit();
        document.getElementById(seMap.id.replace("_map", "_hidMapBoundaryPoints")).value = "";
        ctl.style.display = "none";
     
        if (seMap.functionToCallOnZoom)
            seMap.functionToCallOnZoom(true)
    }                      

	function _SEMap_ShowUpdatingMsg(showMsg, sMsg)
	{
		var divMsg = this.updateMsgDiv;
		if (!sMsg)
			sMsg = "Locating matching properties.<br/>Please wait...";
		if (showMsg && (divMsg == null))
		{
			divMsg = document.createElement("div");

			divMsg.className = "tooltip";
			if (this._mapDiv.offsetWidth < 100) divMsg.style.width = "100px";
			divMsg.innerHTML = "<table cellspacing=0 cellpadding=0 id=tbMapUpdateMsg><tr><td><strong>" + sMsg + "</strong></td></tr></table>";
			this._mapDiv.appendChild(divMsg);
			//divMsg.style.width = (document.getElementById("tbMapUpdateMsg").offsetWidth + 4) + "px";
			divMsg.style.width = "180px";
			divMsg.style.height = (document.getElementById("tbMapUpdateMsg").offsetHeight + 4) + "px";
			this.updateMsgDiv = divMsg;
		}

		if (showMsg)
		{
			divMsg.style.top = ((this._mapDiv.offsetHeight - divMsg.offsetHeight)/2) + "px";
			divMsg.style.left = ((this._mapDiv.offsetWidth - divMsg.offsetWidth)/2) + "px";
			divMsg.style.display = "block";
		}
		else
		{
			if(divMsg)
			    divMsg.style.display = "none";
			try{
				divMsg.parentNode.removeChild(divMsg);
			} catch(e){}
			this.updateMsgDiv = null;
		}
	}
	
	
	function _SEMap_CancelEvent(e)
	{
		if (!e)
			e = window.event;
		if (e)
		{
			if (e.stopPropagation)
				e.stopPropagation();

			if (e.preventDefault)
				e.preventDefault();

			e.returnValue = false;
			e.cancelBubble = true;
		}
		return false;
	}

	function SEMap_FindChildNode(startNode, id)
	{
		if (startNode && startNode.childNodes)
		{
			var iCount = startNode.childNodes.length ;
			var childNode = null;
			for(var i=0; i<iCount; i++)
			{
				var thisNode = startNode.childNodes[i];
				if (thisNode.id && (thisNode.id.toUpperCase() == id.toUpperCase()))
					return thisNode;
				else
				{
					childNode = SEMap_FindChildNode(thisNode, id);
					if (childNode != null) return childNode;
				}
			}
		} else
			return null;
	}



	// -------------- not used ----------------

	function _SEMap_PNGsNeedFixing()
	{
		var arVersion = navigator.appVersion.split("MSIE");
		var version = parseFloat(arVersion[1]);
		return ((version >= 5.5) && (version < 7.0) );
	}

	function _SEMap_CorrectPNGs(nodeToFix) // correctly handle PNG transparency in Win IE 5.5 & 6.
	{
		if (_SEMap_PNGsNeedFixing())
		{
			_SEMap_CorrectPNGs1(nodeToFix);
		}
	}

	function _SEMap_CorrectPNGs1(nodeToFix) // correctly handle PNG transparency in Win IE 5.5 & 6.
	{

		var iCount = nodeToFix.childNodes.length ;
		for(var i=0; i<iCount; i++)
		{
			var img = nodeToFix.childNodes[i];
			if (img.tagName && (img.tagName.toUpperCase() == "IMG"))
			{
				var imgName = img.src.toUpperCase();
				if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
				{
					var imgID = (img.id) ? "id='" + img.id + "' " : "";
					var imgClass = (img.className) ? "class='" + img.className + "' " : "";
					var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
					var imgStyle = img.style.cssText + ";display:k;line-height:1px;font-size:1px;";
					if (img.align == "left") imgStyle = "float:left;" + imgStyle;
					if (img.align == "right") imgStyle = "float:right;" + imgStyle;
					if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle;
					var strNewHTML = "<span " + imgID + imgClass + imgTitle
					+ " style=\"" + "width:" + img.style.width + "px; height:" + img.style.height + "px;" + imgStyle + ";"
					+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
					+ "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" ;
					img.outerHTML = strNewHTML;
				}
			}
			_SEMap_CorrectPNGs(img);
		}
	}

	function _SEMap_IsSameUrl(url1, url2)
	{
		var myUrl1 = url1.toLowerCase().replace(window.location.protocol + "//" + window.location.host, "");
		var myUrl2 = url2.toLowerCase().replace(window.location.protocol + "//" + window.location.host, "");
		return myUrl2 == myUrl1;
	}
	function _SEMap_NOP()
	{}

	function _SEMap_IsValidLatLong(latitude, longitude)
	{
		if(latitude && longitude)
		{
			return(Math.abs(latitude) > .01) && (Math.abs(longitude) > .01) && (Math.abs(latitude) < 180) && (Math.abs(longitude) < 180) ;
		}
    }
    function SEMap_IsValidLatitude(latitude)
	{
	    return (latitude > -90.1 && latitude < 90.1)
	}
	function SEMap_IsValidLongitude(longitude)
	{
	    return (longitude > -180.1 && longitude < 180.1)
	}


	function SE_Map_ShowSimple(mapDivID, nwLat, nwLon, seLat, seLon) {
	    var sbMap = new VEMap(mapDivID);
        sbMap.HideDashboard();
        sbMap.HideScalebar();
        var nw = new VELatLong(nwLat, nwLon);
        var se = new VELatLong(seLat, seLon);
        var cp = new VELatLong((nw.Latitude + se.Latitude)/2 , (nw.Longitude + se.Longitude)/2);
        sbMap.LoadMap(cp, 14, 'r', true);
        var boundsPoints = new Array();
        boundsPoints.push(nw);
        boundsPoints.push(se);
        sbMap.SetMapView(boundsPoints);
	}

		
