// ----------------------------------------------------------------
//     				   ArcWeb Services Site Starter Client
// ----------------------------------------------------------------
// Purpose:  Manages "active" navigation functionality.  
//           + Manages map coordinate logic.
//           + Uses DHTML to produce rubber-banding effect 
//             when user zooms in or out.  This is handled
//             by the zoomBox class.
// ----------------------------------------------------------------
// Notes:		
// -------------------------------------------------------------------

// The following variables are global to the page.
	// These vars reference HTML tags in the page whose
	// values may be read or set dynamically. 
  var m_radZoomIn; 
  var m_radRecenter;
  var m_txtXCoord;
  var m_txtYCoord;
  var m_imgLoading;
  var m_imgMapCanvas;
  var m_imgMapLayer;
  var m_divMapBorder;
  var m_divZoomBox;
	var m_divMapTools;
	var m_divNorth;
	var m_divSouth;
	var m_divEast;
	var m_divWest;
  var	m_hvMinX;
  var	m_hvMinY;
  var	m_hvMaxX;
  var	m_hvMaxY;
	var m_hvMapPage;
	var m_hvPageName;
	var m_SessionName;
	var m_OriginalQueryString;
	var m_CustomAction;
	var m_ActionParams;
	var m_BorderOffset;
	
	var clickCount = 0;
	
	var m_markerLayer;

	var m_SessionTimeout;
	var m_PageTimedOut;
	var m_TheTimeout;
	
	var m_IsPanning;
	var m_ZoomLevel;
	
	var m_mainLoadingTop;
	var m_mainLoadingLeft;
	
	var req; // xmlhttpRequestObject
	
	var m_ForcePostBack;
	
	var _mapMarkerTracker;
	
	var _mapBubbleManager;
	
	var _mapMarkerBubble;
	var _markerBalloonString;
	var _markerBalloonStringImage;
	
	// Added 6/7/2006 - User method to call when the active map is updated
	// in this user method the programmer can do anything but will most likely
	// call UpdateStaticMapImage with the id of the static map image to udpate.
	var m_inLineRefreshDelegate = null;

	// These vars represent javascript classes that will
	// handle logic.
    var m_mapViewer;  // Object of type map.  Handles map coordinate management.

    var m_zbxZoom;      // Object of type zoombox.  Handles drawing the zoombox.  
				        // Operates entirely within page coordinates and has no 
				        // awareness of the map space or even the image that 
				        // represents the map on the page.

    var m_iToolMode;    // Indicates the currently selected tool, where
				        //				+ zoom in  = 1
				        //				+ recenter = 2	

	var m_sClientBrowserType;	// Possible values: "IE", "Netscape"
	var m_sClientPlatform;		// Possible values: "Windows","Mac"
    
    		           // The array that stores the level extent widths				  
	//var m_ExtentWidths = new Array(0.005, 0.015, 0.035, 0.1, 0.3, 0.75, 2, 6, 10, 30, 110);
	//var m_ExtentWidths = new Array(8000, 24000, 72000, 148000, 296000, 592000, 1776000, 5328000, 15984000);
	var m_ExtentWidths = new Array(1500, 2500, 4000, 7000, 15000, 25000, 45000, 68000, 92000);

	var m_lTimerID = 1; // used only for hiding the "Wait" image for Netscape 6.x

	var m_debug = false;
	
	var m_onResizeDelegate = null;

	// Determine browser type and platform.

	if (navigator.appName.indexOf("Netscape")>=0) {
		m_sClientBrowserType = 'Netscape';
	} else if (navigator.appName.indexOf('Microsoft') >=0) {
		m_sClientBrowserType = 'IE';
	} else if (navigator.appName.indexOf('Safari') >= 0) {
		m_sClientBrowserType = 'Safari';
	} else {
		window.location = "unsupported.htm";
	}

	if (navigator.userAgent.indexOf("Win") >= 0) {
		m_sClientPlatform = 'Windows';
	} else if (navigator.platform.indexOf("Mac") >= 0) {
		m_sClientPlatform = 'Mac';
	} else {
		window.location = "unsupported.htm";
	}
    

// *******************************************************************
// *********************** STARTUP FUNCTION **************************
// *******************************************************************


function startUp() {

	//alert('Start Up!');

// Purpose: Fires when the page first loads.  
// Find the HTML tags that will be used throughout the
// page.
	m_radZoomIn = document.getElementById("radZoomIn");
	m_radRecenter = document.getElementById("radRecenter");
	m_imgMapCanvas = document.getElementById("imgMapCanvas");
	//m_imgMapCanvas = document.getElementById("imgLayer");
	m_imgMapLayer = document.getElementById("mapLayer");
    m_imgLoading = document.getElementById("imgLoading");
	m_divZoomBox = document.getElementById("divZoomBox");
	m_divMapBorder = document.getElementById("divMapBorder");
  	m_divNorth = document.getElementById("divNorth");
  	m_divSouth = document.getElementById("divSouth");
  	m_divEast = document.getElementById("divEast");
  	m_divWest = document.getElementById("divWest");
  	m_divMapTools = document.getElementById("divMapTools");
	m_hvMinX = document.getElementById("hvMinX");
	m_hvMinY = document.getElementById("hvMinY");
	m_hvMaxX = document.getElementById("hvMaxX");
	m_hvMaxY = document.getElementById("hvMaxY");
	m_hvMapPage = document.getElementById("hvMapPage");
	m_hvPageName = document.getElementById("hvPageName");
	m_hCurrentTool = document.getElementById("hCurrentTool");
	m_SessionName = document.getElementById("hSessionName");
	m_OriginalQueryString = document.getElementById("hOriginalQueryString");
	m_CustomAction = document.getElementById("hCustomAction");
	m_ActionParams = document.getElementById("hActionParams");
	m_SessionTimeout = document.getElementById("hSessionTimeout");
	m_ZoomLevel = document.getElementById("hZoomLevel");
	m_SessionTimeout = m_SessionTimeout.value;
	m_BorderOffset = document.getElementById("hBorderOffset");
	m_ForcePostBack = document.getElementById("hForcePostBack");
	//m_markerLayer = document.getElementById("markerLayer");
		
	_mapMarkerTracker = new mapMarkerTracker();	
	_mapBubbleManager = new mapBubbleManager();
	
	_mapMarkerBubble = document.getElementById("markerBubble");
	_markerBalloonString = document.getElementById("markerBalloonString");
  _markerBalloonStringImage = document.getElementById("markerBalloonStringImage");
		
	if (m_ForcePostBack == null)
		m_ForcePostBack = "false";
	else
		m_ForcePostBack = m_ForcePostBack.value;
		
	// Create a map coordinate manager.
	m_mapViewer = new map(GetImageLeft(),
  						  GetImageTop(),
						  m_imgMapCanvas.width,	
						  m_imgMapCanvas.height,
						  m_ExtentWidths,
						  new rect(m_hvMinX.value, m_hvMinY.value, m_hvMaxX.value, m_hvMaxY.value)
						  );

	//alert('After Create: ' + m_mapViewer.getExtent().getBottom());

	// Create a zoom box.
    m_zbxZoom = new zoomBox(m_divZoomBox);
   
	//Orient other page elements - Map Border, Map Tools, Loading Image, Border Navigation.
    posLoadingImage(true);
    //posBorder();
   
	// Assign custom event handlers to mousedown, mousemove, 
	// and mouseup.
	if (m_sClientBrowserType == 'Netscape') {
		//document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
		nsAddListeners();
    		//event.preventDefault();
	}
	else
	{
		document.onmousedown = handleMouseDown;
		document.onmousemove = handleMouseMove;
		document.onmouseup = handleMouseUp;
	}
	
	// Assign an event handler to the m_imgMapCanvas onload event.
	m_imgMapCanvas.onload = hideWaitImage;
	
	window.onresize = screenResize;
	
	var imgType = m_imgMapCanvas.src;
	imgType = imgType.substr(imgType.length-3, 3);	
	
	if (imgType=='gif')
	{
		//alert('Submit: ' + m_mapViewer.getExtent().getBottom());
		//Request a map.		
		//submit();
		actualSubmit("true");
	}
	
	// Initialize the tool mode. 
	if (typeof(useTools)!="undefined" && useTools!=null)
	{
	//alert(m_hCurrentTool.value);
		handleToolClick(m_hCurrentTool.value);
		UpdateToolImages(m_hCurrentTool.value);
	}	
	else
	{
		handleToolClick(9);
	}
	
	posBorder();
	//setMarkerLayerUp();
	
	InLineRefreshDelegate();
}

function addIdentifyMarker(mapX, mapY)
{
  var identifyMarker = new mapMarker('identifyTool', mapX, mapY, '/aspnet_client/system_web/CoEGenericGIS/v3/images/arrow_green.gif');
  
  _mapMarkerTracker.removeMarkerById('identifyTool');
  
  _mapMarkerTracker.AddMarker(identifyMarker);
}

function nsRemoveListeners()
{
	document.removeEventListener("mousemove", handleMouseMove,   true);
    document.removeEventListener("mouseup",   handleMouseUp, true);
	document.removeEventListener("mousedown",   handleMouseDown, true);
}


function nsAddListeners()
{
	document.addEventListener("mousemove", handleMouseMove, true);
    document.addEventListener("mouseup",   handleMouseUp, true);
	document.addEventListener("mousedown", handleMouseDown, true);
}

// *******************************************************************
// *********************** EVENT HANDLERS  ***************************
// *******************************************************************

function handleMouseDown(evt) {
// Purpose:  Any time a mouse button is depressed, this function
//           is given the opportunity to respond to the event.
//
//           For the purposes of the map, we are only interested
//           in the click if it happened within the map area, so 
//           an initial check kicks us out of the function if the
//           click has not occurred in the map area.
//
//           If the click is over the map, then -- depending on
//           the tool mode -- either the zoombox must be started
//           or a recenter must be performed.


	// Get event coordinates by browser-specific means.
	var eventX;
	var eventY;

	var scrollX = 0;
	var scrollY = 0;

	


	if (m_sClientBrowserType == 'Netscape') {
		
		if (!checkIt('safari'))
		{	
			scrollX = window.pageXOffset;
			scrollY = window.pageYOffset;
		}		

		eventX = evt.clientX + scrollX;
		eventY = evt.clientY + scrollY;	

		evt.preventDefault();
	} else {
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
		
		eventX = event.clientX + scrollX;
		eventY = event.clientY + scrollY;
	}

	//alert('x: ' + eventX + ' y: ' + eventY);

	// Check to see if click is over map
	if (!(m_mapViewer.isEventOverMap(eventX, eventY))) {	
			return;
	} 
	
	// If we made it this far we need to hide the map bubble
	_mapBubbleManager.hideMapBubble();
	
	// Numbers in () represent old numbers
	switch(m_iToolMode) {
		case 0: // zoom in mode (1)
			if ((m_sClientBrowserType == 'IE') && (m_sClientPlatform == 'Windows')) {
			// For IE, a call to "setCapture" is made to ensure that
				// new IE dragging events do not interfere with capturing 
				// the mousemove events -- effectively, this turns off 
				// drag and drop events temporarily.
				//DisplayDebug('setCapture() called.');
				m_imgMapCanvas.setCapture(); 
			}
			//DisplayDebug('Zoom started.');
			m_zbxZoom.show();
			m_zbxZoom.start(eventX, eventY);
			break;
		case 1: // zoom out mode (3)
			if ((m_sClientBrowserType == 'IE') && (m_sClientPlatform == 'Windows')) {
	  		// For IE, a call to "setCapture" is made to ensure that
				// new IE dragging events do not interfere with capturing 
				// the mousemove events -- effectively, this turns off 
				// drag and drop events temporarily.
				m_imgMapCanvas.setCapture(); 
			}
			m_zbxZoom.show();
			m_zbxZoom.start(eventX, eventY);
			break;
		case 2: // Pan mode (2)
			if ((m_sClientBrowserType == 'IE') && (m_sClientPlatform == 'Windows')) {
	  		// For IE, a call to "setCapture" is made to ensure that
				// new IE dragging events do not interfere with capturing 
				// the mousemove events -- effectively, this turns off 
				// drag and drop events temporarily.
				m_imgMapCanvas.setCapture(); 
			}
			m_IsPanning = true;
			
			// If it is not IE - hide the markers
			if (m_sClientBrowserType != 'IE')
          _mapMarkerTracker.ClearMarkerImages();
			
			StartPan(eventX, eventY);
			break;
		case 3: // center on point mode (2)
  			var ptUserClick = m_mapViewer.toMapPoint(eventX, eventY);
			m_mapViewer.recenter(ptUserClick);
			//Request a new map.
			submit();
			break;
		case 4: // Point selection (5)
			m_zbxZoom.start(eventX, eventY);
			break;
		case 5: // Box Selection Mode (4)
			if ((m_sClientBrowserType == 'IE') && (m_sClientPlatform == 'Windows')) {
	  		// For IE, a call to "setCapture" is made to ensure that
				// new IE dragging events do not interfere with capturing 
				// the mousemove events -- effectively, this turns off 
				// drag and drop events temporarily.
				m_imgMapCanvas.setCapture(); 
			}
			m_zbxZoom.show();
			m_zbxZoom.start(eventX, eventY);
			break;		
		case 8: // Identify 
			m_zbxZoom.start(eventX, eventY);
			break;
		case 9: // Generic click event
			m_zbxZoom.start(eventX, eventY);
			break;
		case 10: // Box Selection Mode (4)
			if ((m_sClientBrowserType == 'IE') && (m_sClientPlatform == 'Windows')) {
	  		// For IE, a call to "setCapture" is made to ensure that
				// new IE dragging events do not interfere with capturing 
				// the mousemove events -- effectively, this turns off 
				// drag and drop events temporarily.
				m_imgMapCanvas.setCapture(); 
			}
			m_zbxZoom.show();
			m_zbxZoom.start(eventX, eventY);
			break;		
	}
}

function handleMouseMove(evt) {
// Purpose:  Any time the mouse moves anywhere on the document, 
//           this function is given the opportunity to respond to 
//           the event.

	// Get event coordinates by browser-specific means.

	var eventX;
	var eventY;
	
	var scrollX = 0;
	var scrollY = 0;

	if (m_sClientBrowserType == 'Netscape') {
		
		if (!checkIt('safari'))
		{	
			scrollX = window.pageXOffset;
			scrollY = window.pageYOffset;
		}		
		
		eventX = evt.clientX + scrollX;
		eventY = evt.clientY + scrollY;	

		evt.preventDefault();	
	} else {
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
		
		eventX = event.clientX + scrollX;
		eventY = event.clientY + scrollY;
	}

	// If the mouse isn't currently over the map, we
    // have nothing to do.
	//if (!(m_mapViewer.isEventOverMap(eventX, eventY))) {
		//return;
	//} 		
		
    // If the current tool is zoom in and a zoombox is in progress, update the zoom box.
	if ((m_iToolMode == 0) || (m_iToolMode==1) || (m_iToolMode==5) || (m_iToolMode==10)) 
	{
		if (m_zbxZoom.isInProgress()) {
			//DisplayDebug('m_zbxZoom.isInProgress: ' + m_zbxZoom.isInProgress());
			//DisplayDebug('Mouse Move: ' + eventX + ',' + eventY);
			m_zbxZoom.update(eventX, eventY);
		}
	}
	else if (m_iToolMode == 2)
	{
		if (m_IsPanning)
		{
			panMouse(eventX, eventY);
		}
	}
}

function handleMouseUp(evt) {
	// Purpose:  Any time a mouse button is released, this function is 
	//					 given the opportunity to respond to the event.

	// If a ZoomBox is not in progress, we've got nothing to do.
	if (!(m_iToolMode == 0)&&!(m_iToolMode==1)&&!(m_iToolMode==2)&&!(m_iToolMode==4)&&!(m_iToolMode==5)&&!(m_iToolMode==8)&&!(m_iToolMode==9)&&!(m_iToolMode==10)) {
		return;
	}
	
	if (!(m_zbxZoom.isInProgress())&&(!m_IsPanning)) {
		return;
	}
		
	// We have established that we are drawing a zoom box and are zooming
	// Release the capture that was set in the mousedown
	// handler (again, this is something that we have to do because
	// of drag events in IE).
	if ((m_sClientBrowserType == 'IE') && (m_sClientPlatform == 'Windows')) {
		document.releaseCapture();
	}
	else
	{
		nsRemoveListeners();
		nsAddListeners();
	}	

	var eventX;
	var eventY;
	
	var scrollX = 0;
	var scrollY = 0;

	if (m_sClientBrowserType == 'Netscape') {
		
		if (!checkIt('safari'))
		{	
			scrollX = window.pageXOffset;
			scrollY = window.pageYOffset;
		}		
		
		eventX = evt.clientX + scrollX;
		eventY = evt.clientY +scrollY;		
	} else {
		scrollX = document.body.scrollLeft;
		scrollY = document.body.scrollTop;
		
		eventX = event.clientX + scrollX;
		eventY = event.clientY + scrollY;
	}
	
	// Stop the current effect.
	m_zbxZoom.stop();
	
	if (m_IsPanning)
		StopPan(eventX, eventY);

	// Are we zooming in?
	if (m_iToolMode == 0)
	{
			// If the width of the zoom box is less than five pixels, treat is as a single click and zoom in a fixed amount
			if ((Math.abs(m_zbxZoom.getStartX() - m_zbxZoom.getEndX()) < 5) && (Math.abs(m_zbxZoom.getStartY() - m_zbxZoom.getEndY()) < 5))  
			{	
				// First we need the width and height of the of the image
				var imgWidth = m_imgMapCanvas.width;
				var imgHeight = m_imgMapCanvas.height;
				
				// Now calculate a percentage to create a virtual zoom box - this is the height and width of the box
				var rectangleHeight = imgHeight * .30;
				var rectangleWidth = imgWidth * .30;
				
				//alert('rHeight: ' + rectangleHeight + ' rWidth: ' + rectangleWidth);
				
				// Now get start and end points around where the user clicked
				var startX = m_zbxZoom.getStartX() - rectangleWidth;
				var startY = m_zbxZoom.getStartY() - rectangleHeight;
				var endX = m_zbxZoom.getStartX() + rectangleWidth;
				var endY = m_zbxZoom.getStartY() + rectangleHeight;
				
				//alert('mapCenterX: ' + m_zbxZoom.getStartX() + ' mapCenterY: ' + m_zbxZoom.getStartY());
				//alert('startX ' +  startX + ' startY: ' + startY + ' endX: ' + endX + ' endY: ' + endY);
				
				var ptStart = m_mapViewer.toMapPoint(startX, startY);
				var ptEnd   = m_mapViewer.toMapPoint(endX, endY);
				
				//alert ('ptStart.x: ' + ptStart.x + ' ptStart.y: ' + ptStart.y + ' ptEnd.x: ' + ptEnd.x + ' ptEnd.y: ' + ptEnd.y);
				// Save the extents
				m_mapViewer.setExtent(new rect(ptStart.x,ptStart.y,ptEnd.x,ptEnd.y));
			} 
			else 
			{
  				borderWidth = 0;
  				if (m_sClientBrowserType == 'Netscape') {
					borderWidth = 4; // 2 times border width
				}
				var ptStart = m_mapViewer.toMapPoint(m_zbxZoom.getStartX()+borderWidth, m_zbxZoom.getStartY()+borderWidth);
				var ptEnd   = m_mapViewer.toMapPoint(m_zbxZoom.getEndX()+borderWidth, m_zbxZoom.getEndY()+borderWidth);
				
				//alert ('ptStart.x: ' + ptStart.x + ' ptStart.y: ' + ptStart.y + ' ptEnd.x: ' + ptEnd.x + ' ptEnd.y: ' + ptEnd.y);
				
				m_mapViewer.setExtent(new rect(ptStart.x,ptStart.y,ptEnd.x,ptEnd.y));
			}
			
			//Request a new map.
			submit();
	}
	else if ((m_iToolMode == 5) || (m_iToolMode == 10)) // We are box selecting
	{
			borderWidth = 0;
  				
  			if (m_sClientBrowserType == 'Netscape') {
				borderWidth = 4;  // 2 times border width
			}
			
			var ptStart = m_mapViewer.toMapPoint(m_zbxZoom.getStartX()+borderWidth, m_zbxZoom.getStartY()+borderWidth);
			var ptEnd   = m_mapViewer.toMapPoint(m_zbxZoom.getEndX()+borderWidth, m_zbxZoom.getEndY()+borderWidth);
			
			if ((ptStart.x - ptEnd.x) < 5)
			{
				ptStart.x -= 5;
				ptEnd.x += 5;
			}

			if ((ptStart.y - ptEnd.y) < 5)
			{
				ptStart.y -= 5;
				ptEnd.y += 5;	
			}

			var actionString = ptStart.x + '~' + ptStart.y + '~' + ptEnd.x + '~' + ptEnd.y;
			
			//customActionSubmit('boxselect', actionString);
			customActionSubmit(((m_iToolMode == 5) ? 'boxselect' : 'multiselect'), actionString);
	}
	else if (m_iToolMode == 4 || m_iToolMode == 8)  // We are point selecting or identifying
	{
			var eventX;
			var eventY;
			var scrollX;
			var scrollY;			

			if (m_sClientBrowserType == 'Netscape') {
				scrollX = window.pageXOffset;
				scrollY = window.pageYOffset;
		
				eventX = evt.clientX + scrollX;
				eventY = evt.clientY +scrollY;		
			} else {
				scrollX = document.body.scrollLeft;
				scrollY = document.body.scrollTop;
		
				eventX = event.clientX + scrollX;
				eventY = event.clientY + scrollY;
			}
			
			var ptStart = m_mapViewer.toMapPoint(eventX - 5, eventY - 5);
			var ptEnd   = m_mapViewer.toMapPoint(eventX + 5, eventY + 5);
			
			var actionString = ptStart.x + '~' + ptStart.y + '~' + ptEnd.x + '~' + ptEnd.y;
			
			customActionSubmit(((m_iToolMode == 4) ? 'boxselect' : 'identify'), actionString);
			/*				
			if (m_iToolMode == 4)	
			{
        var actionString = ptStart.x + '~' + ptStart.y + '~' + ptEnd.x + '~' + ptEnd.y;
        
        customActionSubmit('boxselect', actionString);
      }
      else
        performIdentify(eventX, eventY, ptStart.x, ptStart.y, ptEnd.x, ptEnd.y);*/
        
			//customActionSubmit(((m_iToolMode == 4) ? 'boxselect' : 'identify'), actionString);
	}
	else if (m_iToolMode == 1) // We are zooming out
	{
		if ((Math.abs(m_zbxZoom.getStartX() - m_zbxZoom.getEndX()) < 5) && (Math.abs(m_zbxZoom.getStartY() - m_zbxZoom.getEndY()) < 5))  {	
			// First we need the width and height of the of the image
				var imgWidth = m_imgMapCanvas.width;
				var imgHeight = m_imgMapCanvas.height;
				
				// Now calculate a percentage to create a virtual zoom box - this is the height and width of the box
				var rectangleHeight = imgHeight * .30;
				var rectangleWidth = imgWidth * .30;
				
				// Now get start and end points around where the user clicked
				var zleft = m_zbxZoom.getStartX() - rectangleWidth;
				var ztop = m_zbxZoom.getStartY() - rectangleHeight;
				var zright = m_zbxZoom.getStartX() + rectangleWidth;
				var zbottom = m_zbxZoom.getStartY() + rectangleHeight;
				
					borderWidth = 0;
  				
  				if (m_sClientBrowserType == 'Netscape') {
					borderWidth = 4; // 2 times border width
				}
				
				// Get our current Extent
				var m_rctExtent = m_mapViewer. getExtent();
				
				//alert('zright: ' + zright + ' zleft: ' + zleft + ' ztop: ' + ztop + ' zbottom: ' + zbottom);
				
				// Calculate distances between our extents
				var xDistance = Math.abs(m_rctExtent.getRight()-m_rctExtent.getLeft());
				var yDistance = Math.abs(m_rctExtent.getTop()-m_rctExtent.getBottom());
				
				//alert('xDistance: ' + xDistance + ' yDistance: ' + yDistance);
				
				// Get the Width and and Height of the Zoom Box
				var zWidth = Math.abs(zright-zleft);
				var zHeight = Math.abs(ztop-zbottom);
				
				// Caclulate a ratio between the image size and the height/width of the zoom box
				var xRatio = m_imgMapCanvas.width / zWidth;
				var yRatio = m_imgMapCanvas.height / zHeight;
				
				// Get values to add to our extents
				var xAdd = xRatio * xDistance / 2;
				var yAdd = yRatio * yDistance / 2;
		
				// Add those values to our extents
				var eLeft = m_rctExtent.getLeft() - xAdd;
				var eRight = m_rctExtent.getRight() + xAdd;
				var eTop = m_rctExtent.getTop() + yAdd;
				var eBottom = m_rctExtent.getBottom() - yAdd;
				
				//alert('eLeft: ' + eLeft + ' eRight: ' + eRight + ' eTop: ' + eTop + ' eBottom: ' + eBottom);
				
				var ptStart = m_mapViewer.toMapPoint(eLeft, eTop);
				var ptEnd = m_mapViewer.toMapPoint(eRight, eBottom);
				
				//alert ('ptStart.x: ' + ptStart.x + ' ptStart.y: ' + ptStart.y + ' ptEnd.x: ' + ptEnd.x + ' ptEnd.y: ' + ptEnd.y);
					
				m_mapViewer.setExtent(new rect(eLeft,eTop,eRight,eBottom));
				
				//Request a new map.
				submit();
				}
			else {
  				borderWidth = 0;
  				
  				if (m_sClientBrowserType == 'Netscape') {
					borderWidth = 4; // 2 times border width
				}
				
				// Get our current Extent
				var m_rctExtent = m_mapViewer. getExtent();
				
				// Get the widths of the Zoom Box 
				var zright = m_zbxZoom.getEndX()+borderWidth;
				var zleft = m_zbxZoom.getStartX()+borderWidth;
				var ztop = m_zbxZoom.getStartY()+borderWidth;
				var zbottom = m_zbxZoom.getEndY()+borderWidth;
				
				//alert('zright: ' + zright + ' zleft: ' + zleft + ' ztop: ' + ztop + ' zbottom: ' + zbottom);
				
				// Calculate distances between our extents
				var xDistance = Math.abs(m_rctExtent.getRight()-m_rctExtent.getLeft());
				var yDistance = Math.abs(m_rctExtent.getTop()-m_rctExtent.getBottom());
				
				//alert('xDistance: ' + xDistance + ' yDistance: ' + yDistance);
				
				// Get the Width and and Height of the Zoom Box
				var zWidth = Math.abs(zright-zleft);
				var zHeight = Math.abs(ztop-zbottom);
				
				// Caclulate a ration between the image size and the height/width of the zoom box
				var xRatio = m_imgMapCanvas.width / zWidth;
				var yRatio = m_imgMapCanvas.height / zHeight;
				
				// Get values to add to our extents
				var xAdd = xRatio * xDistance / 2;
				var yAdd = yRatio * yDistance / 2;
		
				// Add those values to our extents
				var eLeft = m_rctExtent.getLeft() - xAdd;
				var eRight = m_rctExtent.getRight() + xAdd;
				var eTop = m_rctExtent.getTop() + yAdd;
				var eBottom = m_rctExtent.getBottom() - yAdd;
				
				//alert('eLeft: ' + eLeft + ' eRight: ' + eRight + ' eTop: ' + eTop + ' eBottom: ' + eBottom);
				
				var ptStart = m_mapViewer.toMapPoint(eLeft, eTop);
				var ptEnd = m_mapViewer.toMapPoint(eRight, eBottom);
				
				//alert ('ptStart.x: ' + ptStart.x + ' ptStart.y: ' + ptStart.y + ' ptEnd.x: ' + ptEnd.x + ' ptEnd.y: ' + ptEnd.y);
					
				m_mapViewer.setExtent(new rect(eLeft,eTop,eRight,eBottom));
				
				//Request a new map.
				submit();
			}
		} 
		else if (m_iToolMode == 9)  // Raise the generic click event
		{
			var eventX;
			var eventY;
			
			var scrollX = 0;
			var scrollY = 0;

			if (m_sClientBrowserType == 'Netscape') {
		
				if (!checkIt('safari'))
				{	
					scrollX = window.pageXOffset;
					scrollY = window.pageYOffset;
				}		
		
				eventX = evt.clientX + scrollX;
				eventY = evt.clientY +scrollY;		
			} else {
				scrollX = document.body.scrollLeft;
				scrollY = document.body.scrollTop;
		
				eventX = event.clientX + scrollX;
				eventY = event.clientY + scrollY;
			}
			
			var ptStart = m_mapViewer.toMapPoint(eventX, eventY);
			var ptEnd   = m_mapViewer.toMapPoint(eventX + 1, eventY + 1);
			
			var actionString = ptStart.x + '~' + ptStart.y + '~' + ptEnd.x + '~' + ptEnd.y;
			
			customActionSubmit('clickevent', actionString);			
		}	
}

function doBarZoom(iLevel)
{
	m_mapViewer.setLevel(iLevel);
	
	setZoomBars(m_ZoomLevel.value, iLevel);
	
	submit();
}

function doBarZoomOneStep(dir)
{
	var iLevel;
	
	iLevel = parseInt(m_ZoomLevel.value) + dir;
	
	// Verify that we haven't gone beyond the number of steps
	if (iLevel >= 0 && iLevel<= 8)
	{	
		// Do the zoom
		doBarZoom(iLevel);
	}
}

function setZoomBars(oldValue, newValue)
{
	var oldId = oldValue + "_zoomButton";
	var newId = newValue + "_zoomButton";
	document.getElementById(oldId).src = "/aspnet_client/system_web/CoEGenericGIS/images/zoomBar_Unselected.gif";
	document.getElementById(newId).src = "/aspnet_client/system_web/CoEGenericGIS/images/zoomBar_selected.gif";
	
	m_ZoomLevel.value = newValue;
}

function fakeToolClick(iToolId)
{
    UpdateToolImages(iToolId);
    handleToolClick(iToolId);
}

function handleToolClick(iToolMode) {

	iToolMode = parseInt(iToolMode);

	switch(iToolMode) {
		case 0:
			// zoom in mode
			m_imgMapCanvas.style.cursor = "crosshair";
			break;
		case 1:
			// zoom out mode
			m_imgMapCanvas.style.cursor = "crosshair";
			break;
		case 2:
			// pan mode
			m_imgMapCanvas.style.cursor = "move";
			break;
		case 3:
			// Center on Point
			m_imgMapCanvas.style.cursor = "pointer";
			break;
		case 4:
			// Select Point mode
			m_imgMapCanvas.style.cursor = "pointer";
			break;
		case 5:
			// Select box mode
			m_imgMapCanvas.style.cursor = "crosshair";
			break;
		case 6:
			// Zoom to full extent
			iToolMode = m_iToolMode; // Set the tool mode back to what it was prior to this click (we can't select this tool)
			customActionSubmit('fullextent', "");
			break;
		case 7:
			// Clear All Selections Tool
			iToolMode = m_iToolMode; // Set the tool mode back to what it was prior to this click (we can't select this tool)
			customActionSubmit('clearselections', ""); // Clear the page...
			break;
		case 8:
			m_imgMapCanvas.style.cursor = "pointer";
			break;
		case 9:
			// Select box mode
			m_imgMapCanvas.style.cursor = "crosshair";
			break;
		case 10:
			// Multiselect Mode
			m_imgMapCanvas.style.cursor = "crosshair";
			break;
		default:
			//alert(iToolMode);
			
	}
	DisplayDebug('Tool Mode: ' + iToolMode);
	m_iToolMode = iToolMode;
}

function UpdateToolImages(newToolID)
{
	document.getElementById('tool_' + m_iToolMode).className = 'DefaultTool';
	document.getElementById('tool_' + newToolID).className = 'SelectedTool';
}

// *******************************************************************
// ********************** HELPER FUNCTIONS  **************************
// *******************************************************************

function pushFloatingWindow(windowDiv)
{
	m_mapViewer.addFloatingWindow(windowDiv);
}

function popFloatingWindow(windowDiv)
{
	m_mapViewer.removeFloatingWindow(windowDiv);
}

function hideWaitImage() {
    m_zbxZoom.hide();
    m_imgLoading.style.visibility = 'hidden';
    resetLayer();
	
    InLineRefreshDelegate();
    
    _mapMarkerTracker.redrawMarkers();
}

function hideWaitImageNoInline() {
    m_zbxZoom.hide();
    m_imgLoading.style.visibility = 'hidden';
    resetLayer();
    
    _mapMarkerTracker.redrawMarkers();
}

function InLineRefreshDelegate()
{
	if (m_inLineRefreshDelegate!=null)
		m_inLineRefreshDelegate();
}

function hideWaitImageForNetscape6() {
	if (m_imgMapCanvas.complete) {
		clearInterval(m_lTimerID);
		m_divZoomBox.style.visibility = 'hidden';
		m_imgLoading.style.visibility = 'hidden';
		resetLayer();
		InLineRefreshDelegate();
		
		_mapMarkerTracker.redrawMarkers();
	}
}

function moveEast() {
    m_mapViewer.moveEast();
    submit();
}

function moveNorth() {
    m_mapViewer.moveNorth();
    submit();
}

function moveSouth() {
    m_mapViewer.moveSouth();
    submit();
}

function moveWest() {
    m_mapViewer.moveWest();
    submit();
}

function moveNorthWest(){
	m_mapViewer.moveNorthWest();
	submit();
}

function moveSouthWest(){
	m_mapViewer.moveSouthWest();
	submit();
}

function moveNorthEast(){
	m_mapViewer.moveNorthEast();
	submit();
}

function moveSouthEast(){
	m_mapViewer.moveSouthEast();
	submit();
}

function persistExtent() {
	m_hvMinX.value = m_mapViewer.getExtent().getLeft();
	m_hvMinY.value = m_mapViewer.getExtent().getBottom();
	m_hvMaxX.value = m_mapViewer.getExtent().getRight();
	m_hvMaxY.value = m_mapViewer.getExtent().getTop();	
}

function showExtents() {
	alert('xMin: ' + m_mapViewer.getExtent().getLeft() + ' yMin: ' + m_mapViewer.getExtent().getTop() + ' xMax: ' + m_mapViewer.getExtent().getRight() + ' yMax: ' + m_mapViewer.getExtent().getBottom());
}

function posBorder() {

    if (m_sClientBrowserType == 'Netscape') { 
      m_divMapBorder.style.left = GetImageLeft();
      m_divMapBorder.style.top = GetImageTop();
    } else { // browser must be IE
        m_divMapBorder.style.left = GetImageLeft(); 
        m_divMapBorder.style.top = GetImageTop(); 
    }
	
    m_divMapBorder.style.width = m_imgMapCanvas.width;
    m_divMapBorder.style.height = m_imgMapCanvas.height;
    m_divMapBorder.style.visibility = "visible";
}

function setMarkerLayerUp()
{
	m_markerLayer.style.left = m_BorderOffset; //GetImageLeft();	
	m_markerLayer.style.top = m_BorderOffset; //GetImageTop(); 

  m_markerLayer.style.width = m_imgMapCanvas.width;
  m_markerLayer.style.height = m_imgMapCanvas.height;
  m_markerLayer.style.visibility = "visible";
}

function posLoadingImage(startUp) { 
	//m_imgLoading.style.top = (GetImageTop() + (m_imgMapCanvas.height / 2) - (m_imgLoading.height / 2) );
	//m_imgLoading.style.left = (GetImageLeft() + (m_imgMapCanvas.width / 2) - (m_imgLoading.width / 2) );
	
	if (startUp != null && startUp == true)
	{
		//alert ('set!');
		m_mainLoadingTop = (GetImageTop() + (m_imgMapCanvas.height / 2) - (m_imgLoading.height / 2) );
		m_mainLoadingLeft = (GetImageLeft() + (m_imgMapCanvas.width / 2) - (m_imgLoading.width / 2) );
	}
		
	m_imgLoading.style.top = m_mainLoadingTop;
	m_imgLoading.style.left = m_mainLoadingLeft;
}

function setLoadingImagePosition(imageCanvas)
{
	m_imgLoading.style.top = (GetImageTop(imageCanvas) + (imageCanvas.height / 2) - (m_imgLoading.height / 2) );
	m_imgLoading.style.left = (GetImageLeft(imageCanvas) + (imageCanvas.width / 2) - (m_imgLoading.width / 2) );
}

function checkIt(string)
{
	var detect = navigator.userAgent.toLowerCase();
	//alert(detect);
	var place = detect.indexOf(string) + 1;
	var thestring = string;
	return place;
}

function performIdentify(eventX, eventY, minX, minY, maxX, maxY)
{
  var mapPoint = m_mapViewer.toMapPoint(eventX, eventY);

  var identifyMarker = new mapMarker('identifyTool', mapPoint.x, mapPoint.y, '/aspnet_client/system_web/CoEGenericGIS/v3/images/arrow_green.png');
  
  _mapMarkerTracker.removeMarkerById('identifyTool');
  
  _mapMarkerTracker.AddMarker(identifyMarker);
  
  identifyRequest(minX, minY, maxX, maxY);
}

/*function addMarker(markerId, mapX, mapY, imgUrl)
{
  _mapMarkerTracker.AddMarker(new mapMarker(markerId, mapX, mapY, imgUrl));
}*/

function addMarker(mapMarker)
{
  _mapMarkerTracker.AddMarker(mapMarker);
}

function removeMarker(markerId)
{
  _mapMarkerTracker.removeMarkerById(markerId);
}

function hideBubbleWindow()
{
  _mapBubblemanager.hideMapBubble();
}

function GetImageTop(el)
{
	var y = 0;
	if (el==null)
		el = m_imgMapCanvas;
		
	//var el = m_imgMapCanvas;
  
	while (el != null) {
		//alert('y: ' + el.id + '-' + el.offsetTop);
		y += el.offsetTop;
		el = el.offsetParent;
	}
	
	return y;
}

function GetImageLeft(el)
{
	var x = 0;
	if (el==null)
		el = m_imgMapCanvas;
		
	//var el = m_imgMapCanvas;
  
	while (el != null) {
		//alert('x: ' + el.id + '-' + el.offsetLeft);
		x += el.offsetLeft;		
		el = el.offsetParent;
	}
	
	return x;	
}

function posTools() {
    m_divMapTools.style.top = parseInt(m_divSouth.style.top.replace('px','')) + parseInt(m_divSouth.style.height.replace('px',''));
    m_divMapTools.style.width = m_imgMapCanvas.width;
}

function reportCoords(ptReport) {
	// Note: Use round() instead of toFixed(), since the latter isn't supported
  //       in IE Mac.
	//m_txtXCoord.value = "X: "+(Math.round(ptReport.x*10000.0)/10000.0).toString();
	//m_txtYCoord.value = "Y: "+(Math.round(ptReport.y*10000.0)/10000.0).toString();
}

function returnActiveTool() {
	/*if (m_radZoomIn.checked) {
		return 1;
	} else if(m_radRecenter.checked) {
		return 2;
	}*/
	return 1;
}

function showWaitImage(imageCanvas) {
	
	if (imageCanvas == null)
		posLoadingImage();
	else	
		setLoadingImagePosition(imageCanvas);	
		
	m_imgLoading.style.visibility = 'visible';
	
	// Hide the map bubble
	_mapBubbleManager.hideMapBubble();
}

function Timeout()
{
	//alert('Session has timed out.');
	m_PageTimedOut = true;
}

function SetTimeout()
{
	ResetTimeout();
	m_TheTimeout = setTimeout("Timeout();", m_SessionTimeout);
}

function ResetTimeout()
{
	if (m_TheTimeout!=null)
		clearTimeout(m_TheTimeout);
		
	m_PageTimedOut = false;
}

function submit() {

	actualSubmit("false");
}

function AddOnResizeDelegate(delegate)
{
	m_onResizeDelegate = delegate;
}

function actualSubmit(forceInPage)
{
	if (m_PageTimedOut)
	{
		alert('Your session has expired. Click OK to restart the map service.');
		SetTimeout();
		PortalSubmit();
	}
	else
	{
		SetTimeout();
		
		//alert ('Actual Submit!!');
		
		showWaitImage();
	
		if (navigator.userAgent.indexOf('Netscape6/6') > -1) {
			m_lTimerID = setInterval("hideWaitImageForNetscape6();",100);
		}
	
		//Persist extent in Hidden variables
		persistExtent();
	
	
		if (m_ForcePostBack=="true" && forceInPage=="false")
		{
			var actionString = m_mapViewer.getExtent().getLeft() + '~' + m_mapViewer.getExtent().getBottom() + '~' + m_mapViewer.getExtent().getRight() + '~' + m_mapViewer.getExtent().getTop();
			
			customActionSubmit('zoompan', actionString);
		}
		else
		{
			var sURL = m_hvMapPage.value+
					 "?XMIN="+m_mapViewer.getExtent().getLeft()+
						 "&YMIN="+m_mapViewer.getExtent().getBottom()+
							 "&XMAX="+m_mapViewer.getExtent().getRight()+
							 "&YMAX="+m_mapViewer.getExtent().getTop()+
							 "&WIDTH="+m_mapViewer.getTagWidth()+
							 "&HEIGHT="+m_mapViewer.getTagHeight()+
							 "&SessionName="+m_SessionName.value;
	
			m_imgMapCanvas.src = sURL;
		}
	}	
}
	
function UpdateStaticMapImage(mapId)
{
	var imgObject = document.getElementById(mapId);
	
	showWaitImage(imgObject);
	
	var sURL = m_hvMapPage.value+
	 "?XMIN="+m_mapViewer.getExtent().getLeft()+
		 "&YMIN="+m_mapViewer.getExtent().getBottom()+
			 "&XMAX="+m_mapViewer.getExtent().getRight()+
			 "&YMAX="+m_mapViewer.getExtent().getTop()+
			 "&WIDTH="+m_mapViewer.getTagWidth()+
			 "&HEIGHT="+m_mapViewer.getTagHeight()+
			 "&SessionName="+mapId+
			 "&CustomAction=NoSessionSave";
	
	
	if (imgObject.onload == null)
	{
		//alert('Set onload on ' + mapId);
		imgObject.onload = hideWaitImageNoInline;
	}
	
	imgObject.src = sURL;
}
	
function processIdentifyresult()
{
    // only if req shows "complete"
    if (req.readyState == 4) 
    {	
        // only if "OK"
        if (req.status == 200) 
        {		
            var xmlDoc = req.responseXML.documentElement;
	            
            //alert (xmlDoc.childNodes.length);         
            if (identifyProcessor != null && identifyProcessor != "undefined")
              identifyProcessor(xmlDoc);
        } 
        else 
        {
            alert("There was a problem retrieving the XML data:\n" + req.statusText);
        }
    }	
}
	
function processReqChange()
{
    // only if req shows "complete"
    if (req.readyState == 4) 
    {	
        // only if "OK"
        if (req.status == 200) 
        {		
			var xmlDoc = req.responseXML.documentElement;
	            
            var sURL = xmlDoc.getElementsByTagName('url')[0].firstChild.data;
            var xMin = xmlDoc.getElementsByTagName('xmin')[0].firstChild.data;
            var yMin = xmlDoc.getElementsByTagName('ymin')[0].firstChild.data;
            var xMax = xmlDoc.getElementsByTagName('xmax')[0].firstChild.data;
            var yMax = xmlDoc.getElementsByTagName('ymax')[0].firstChild.data;
			
			
			// Set the extent of the mapviewer object with the new coordinates
			m_mapViewer.setExtent(new rect(xMin,yMin,xMax,yMax));
			
			// Persist the extent to the form for giggles
			persistExtent();
	
			// Set the URL on the image
            m_imgMapCanvas.src = sURL;
        } 
        else 
        {
            alert("There was a problem retrieving the XML data:\n" + req.statusText);
        }
    }	
}	
	
function getImageUrl(url)
{
	 // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        req.open("GET", url, true);
        
        // IE 7 Did not add this to the XMLHttpRequest object so this fails 
        // without a check. Grrrr...
        if (req.overrideMimeType)
            req.overrideMimeType("text/xml"); 
        
        req.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) 
    {
		req = new ActiveXObject("Microsoft.XMLHTTP");
                
        if (req) {
            req.onreadystatechange = processReqChange;
            //req.setRequestHeader("content-type", "application/x-www-form-urlencoded");

            req.open("GET", url, true);
            req.send();
        }
    }
    else
    {
		sURL = sURL + "&useAjax=false";
		m_imgMapCanvas.src = sURL;
    }
}

function primeAjaxRequest(url, processFunciton)
{
   if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processFunciton;
        req.open("GET", url, true);
        
        // IE 7 Did not add this to the XMLHttpRequest object so this fails 
        // without a check. Grrrr...
        if (req.overrideMimeType)
            req.overrideMimeType("text/xml"); 
        
        req.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) 
    {
		req = new ActiveXObject("Microsoft.XMLHTTP");
                
        if (req) {
            req.onreadystatechange = processFunciton;
            //req.setRequestHeader("content-type", "application/x-www-form-urlencoded");

            req.open("GET", url, true);
            req.send();
        }
    }
}

function screenResize()
{
	if (m_onResizeDelegate != null)
		m_onResizeDelegate();

//begin change 12/5/7 blb/jsn/jbw
//	var actionString = m_mapViewer.getExtent().getLeft() + '~' + m_mapViewer.getExtent().getBottom() + '~' + m_mapViewer.getExtent().getRight() + '~' + m_mapViewer.getExtent().getTop();
			
//	customActionSubmit('donothing', actionString);

	posBorder();
//end change 12/5/7 blb/jsn/jbw

}
	
function centerQuery2(layerId, columnName, columnValue, backoutAmount, selectAttribute)
{
	SetTimeout();
		
	showWaitImage();
		
	var sURL = m_hvMapPage.value+
					 "?XMIN="+m_mapViewer.getExtent().getLeft()+
						 "&YMIN="+m_mapViewer.getExtent().getBottom()+
							 "&XMAX="+m_mapViewer.getExtent().getRight()+
							 "&YMAX="+m_mapViewer.getExtent().getTop()+
							 "&WIDTH="+m_mapViewer.getTagWidth()+
							 "&HEIGHT="+m_mapViewer.getTagHeight()+
							 "&SessionName="+m_SessionName.value+
							 "&CenterQuery=true"+
							 "&LayerID="+layerId+
							 "&ColumnName="+columnName+
							 "&ColumnValue="+columnValue+
							 "&BackoutAmount="+backoutAmount+
							 "&SelectAttribute="+selectAttribute;
	
	getImageUrl(sURL);
}
	
function identifyRequest(xMin, yMin, xMax, yMax)
{
  var sURL = m_hvMapPage.value+
					 "?XMIN="+xMin+
						 "&YMIN="+yMin+
							 "&XMAX="+xMax+
							 "&YMAX="+yMax+
							 "&SessionName="+m_SessionName.value+
							 "&IdentifyRequest=true";
	
	primeAjaxRequest(sURL, processIdentifyresult);	
}
	
function centerQuery(layerId, columnName, columnValue, backoutAmount)
{
	centerQuery2(layerId, columnName, columnValue, backoutAmount, false)
}


function customActionSubmit(customAction, customQueryString) {

	var sURL = m_hvPageName.value;
	
	// Persist the current extent to the form...
	persistExtent();
				 
	showWaitImage();
	
	// Save a couple of values, the custom action - the parameter info and the tool mode.
	m_CustomAction.value = customAction;
	m_ActionParams.value = customQueryString;	
	
	try { m_hCurrentTool.value = m_iToolMode; } catch(exception) {}		
					
	if (m_OriginalQueryString.value!="")
		sURL += "&" + m_OriginalQueryString.value;
	
	// Full submit - call out map post back function.
	__doMapPostBack();
}

function PortalSubmit()
{
	var sURL = m_hvPageName.value;
	
	// Persist the current extent to the form...
	persistExtent();
				 
	showWaitImage();	
	
	//alert ('Portal Submit!!');
	
	try { m_hCurrentTool.value = m_iToolMode; } catch(exception) {}	
	
	__doMapPostBack();				
}

function DisplayDebug(text)
{
	if (m_debug)
	{
		document.getElementById("hDebug").value = text;
	}
}
