function falsefunc() { return false; } // used to block cascading events


//---------------------------
function selectTool(toolNumber)
//---------------------------
{
	// Remove any current event handlers
	glassSheetLayer.onmousedown = glassSheet_onMouseDown;
	glassSheetLayer.ondblclick = falsefunc;
//	glassSheetLayer.onmousemove = falsefunc;
//	glassSheetLayer.onmouseup = falsefunc;
//	document.onmousemove = falsefunc;
//	document.onmouseup = falsefunc;
//	glassSheetLayer.onselectstart = falsefunc;
//	document.onselectstart = falsefunc;
//	window.onselectstart = falsefunc;
	
	// First check to see if this is one of the 'one click' buttons
	// if it is, then we will call the function for that icon,
	// but we will reset the selected tool to the tool being used before this single click button was selected
	switch(toolArray[toolNumber])
	{
		case "toolPrevZoom":
			// call ajax function
			hideIdentify();
			setWaitCursor();
			AjaxTimeStampMap = new Date().getTime();
			Tracker.NHTMap.PrevZoom(pv_callback, AjaxTimeStampMap);
			// now reset to the old tool
			if (toolArray[selectedTool] != "toolAddObs") { toolNumber = selectedTool; }
			break;
		case "toolFullExtent":
			// call ajax function
			hideIdentify();
			setWaitCursor();
			AjaxTimeStampMap = new Date().getTime();
			Tracker.NHTMap.ResetFullExtent(pv_callback, AjaxTimeStampMap);
			// now reset to the old tool
			if (toolArray[selectedTool] != "toolAddObs") { toolNumber = selectedTool; }
			break;
	}
	
	// Set the cursor for this tool
	switch(toolArray[toolNumber])
	{
		case "toolZoomIn":
			mapCursor = "url(images/zoomIn.cur),crosshair";
			break;
			
		case "toolZoomOut":
			mapCursor = "url(images/zoomOut.cur),crosshair";
			break;
			
		case "toolPan":
			mapCursor = "url(images/pan.cur),move";
			break;
			
		case "toolPanZoomCombo":
			mapCursor = "url(images/zoomCombo.cur),crosshair";
			break;
			
		case "toolMeasure":
			mapCursor = "crosshair";
			break;
			
		case "toolIdentify": // identifyTool
			hideIdentify();
			mapCursor = "help";
			break;
			
		case "11": // gpsTool
			mapCursor = "crosshair";
			break;
			
		case "12": // helpTool
//			mapCursor = "default";
			// popup the help window
			var testpopup = window.open('/Help/Tracker/','','width=778,height=600,status=no, toolbar=yes, resizable=yes, scrollbars=yes');
			if (testpopup == null)
			{
				alert("Unable to open window. Please be sure to adjust your popup blockers to allow popups from this site.");
			}
			else
			{
				testpopup.focus();
			}
			break;
		
		default:  // catch the icons that are Zoom related
			if (amIZoomedInFarEnough)
			{
				switch(toolArray[toolNumber])
				{
					case "toolAddObs":
						mapCursor = "url(./images/AddObs.cur),crosshair";
						break;
				}
			}
			else
			{
				// We're not in close enough, just ignore and switch back to previous tool
				toolNumber = selectedTool;
			}
			break;	
	}
	// set the global var for other functions to know which tool is being used
	selectedTool = toolNumber;
	// save the current tool to the pv
	setTimeout("Tracker.NHTMap.SetSelectedTool(selectedTool, ajax_callback_dummy);",500);

	resetDrawingTool();
	// Set the map cursor
	setMapCursor();


	// change the image for the currently selected tool
	hiliteActiveToolIcon(selectedTool);
//	glassSheetLayer.focus;
	glassSheetLayer.style.zIndex = 1000;
}

//function($e)
//{
   // If $e evaluates to false, assign it window.event.
//   ($e = ($e || window.event));
//}




//document.oncontextmenu = function($e)
//{
//   if (window.event)
//    {
//        window.event.returnValue = false;
//    }
//    else
//    {
//        $e.preventDefault();
//    }
//};




//-------------------------------
function glassSheet_onMouseDown()
//-------------------------------
{
	// User clicked down on the glassSheet layer,
	// which means they are probably using some sort of tool.
	// Check to see which tool is being used and set the proper "events" to be tracked on the glassSheet (mousemove, mouseup, etc)
	// ...if zoom, then starts drawing zoom box
	// ...if pan, then starts to move background
	// ...if AddNew, then records single click and runs the add routine

	// in NS this prevents cascading events, allowing user to drag the mouse during pan/zoom without hilighting text on other parts of the page.
	//document.onmousedown = falsefunc;
	//document.onmouseup = falsefunc;

	document.oncontextmenu = falsefunc;
	glassSheetLayer.oncontextmenu = falsefunc;

	// Next steps depend on what tool is being used.
	switch(toolArray[selectedTool])
	{
		case "toolZoomIn":
	        resetDrawingTool();
			hideIdentify();
			// show the zoom box
			showZoomInBox();
			// set event handlers
			glassSheetLayer.onmousedown = null;		// turn off the current mousedown to keep from repeating through this function
			glassSheetLayer.onmousemove = drawZoomInBox;
			glassSheetLayer.onmouseup = zoomIn;
			document.onmouseup = zoomIn;
			window.onmouseup = zoomIn;
			glassSheetLayer.onselectstart = falsefunc;
			document.onselectstart = falsefunc;
			break;
			
		case "toolZoomOut":
	        resetDrawingTool();
			hideIdentify();
			// show the zoom box
			showZoomOutBox();
			// set event handlers
			glassSheetLayer.onmousedown = null;		// turn off the current mousedown to keep from repeating through this function
			//glassSheetLayer.onmousemove = drawZoomOutBox;
			glassSheetLayer.onmousemove = ShowActiveLocation;
			glassSheetLayer.onmouseup = zoomOutAni;
			document.onmouseup = zoomOutAni;
			break;
			
		case "toolPan":
	        resetDrawingTool();
			hideIdentify();
			// grab the initial pan clicks
			grabPanStartLocation();
			// set event handlers
			glassSheetLayer.onmousedown = falsefunc;		// turn off the current mousedown to keep from repeating through this function
			glassSheetLayer.onmousemove = panMove;
			glassSheetLayer.onmouseup = panRedraw;
			document.onmousemove = panMove;
			document.onmouseup = panRedraw;
			glassSheetLayer.onselectstart = falsefunc;
			document.onselectstart = falsefunc;
			window.onselectstart = falsefunc;
			break;

		case "toolPanZoomCombo":
	        resetDrawingTool();
			hideIdentify();
			// set event handlers
			glassSheetLayer.onmousedown = null;		// turn off the current mousedown to keep from repeating through this function
			glassSheetLayer.oncontextmenu = null;
			//alert(event.button);

			if (event.button==1) 
			{
				showZoomOutBox();
				// start timer to zoom in
				clearTimeout(myTimeOut);  myTimeOut = null;
				zoomInFactor = 100;
				myTimeOut = setTimeout('timerZoomIn()',10);

				glassSheetLayer.onmousemove = ShowActiveLocation;
				glassSheetLayer.onmouseup = zoomOut;
				document.onmouseup = zoomOut;
			}

			if (event.button==2) 
			{
				showZoomOutBox();
				// start timer to zoom out
				clearTimeout(myTimeOut);  myTimeOut = null;
				zoomOutFactor = 100;
				myTimeOut = setTimeout('timerZoomOut()',10);

				glassSheetLayer.onmousemove = ShowActiveLocation;
				glassSheetLayer.onmouseup = zoomOut;
				document.onmouseup = zoomOut;
			}
			break;
		
		case "toolMeasure":
			hideIdentify();
//			alert('measure');
			// set event handlers
			glassSheetLayer.onmousedown = measureMouseDown;		// turn off the current mousedown to keep from repeating through this function
			glassSheetLayer.onmousemove = measureMouseMove;
			glassSheetLayer.onmouseup = measureMouseUp;
			glassSheetLayer.ondblclick = resetDrawingTool;
//			document.onmousemove = panMove;
//			document.onmouseup = panRedraw;
			glassSheetLayer.onselectstart = falsefunc;
			document.onselectstart = falsefunc;
			window.onselectstart = falsefunc;
			measureMouseDown();
			break;

		case "toolAddObs":
	        resetDrawingTool();
			hideIdentify();
			showEntryForm();
			break;

		case "toolIdentify":
			identify();
			break;
	}
	return false;		// keep mousedown from acting on it's own
}


//=================================================
//   ZOOM IN FUNCTIONS
//=================================================
//----------------------
function showZoomInBox(e)
//----------------------
{
	// Update the global vars on where the mouse was clicked
	getMouseXY(e);

    // Now adjust the coords for the offset of our drawing space.
    mouseX -= drawingSpaceLeft;
    mouseY -= drawingSpaceTop;

	// set the start of our box (minus the offset of the outside div) to where the mouse was first clicked
	mouseDownX = mouseX;
	mouseDownY = mouseY;
	zoomInBox.style.left = mouseDownX;
	zoomInBox.style.top = mouseDownY;
	zoomInBox.style.height = 1;
	zoomInBox.style.width = 1;
	// Make the zoom box visible
	zoomInBox.style.visibility = "visible";
}

//----------------------
function drawZoomInBox(e)
//----------------------
{
	// Called as user drags mouse to select size of zoom area
	// Draw the zoom div using the original MouseDown points as either top/left or bottom/right corners of the box 
	//   (depending on if user is above or below starting point)

	// Find the current location of the mouse and update the global vars
	getMouseXY(e);
    // Now adjust the coords for the offset of our drawing space.
    mouseX -= drawingSpaceLeft;
    mouseY -= drawingSpaceTop;
	
	// Set the Left and Width, drawing either from mousedown point to current...or current to mousedown
	if ( mouseX > mouseDownX )
	{
		zoomBoxLeft = mouseDownX;
		zoomBoxWidth = mouseX - mouseDownX;
	}
	else
	{
		zoomBoxLeft = mouseX;
		zoomBoxWidth = mouseDownX - mouseX;
	}

	// Set the Top and Height, drawing either from mousedown point to current...or current to mousedown
	if ( mouseY > mouseDownY )
	{
		zoomBoxTop = mouseDownY;
		zoomBoxHeight = mouseY - mouseDownY;
	}
	else
	{
		zoomBoxTop = mouseY;
		zoomBoxHeight = mouseDownY - mouseY;
	}

	zoomInBox.style.left = zoomBoxLeft;
	zoomInBox.style.width = zoomBoxWidth;
	zoomInBox.style.top = zoomBoxTop;
	zoomInBox.style.height = zoomBoxHeight;

	// Show the new scale popup	
	updateNewScale();
	//window.status = 'YDown=' + mouseDownY + ' YCurrent=' + mouseY + ' ZBHeight=' + zoomInBox.style.height + ' ZBTop=' + zoomInBox.style.top;
}

//---------------
function zoomIn()
//---------------
{
	// Called when the user lets go of the mousebutton after dragging to select their zoom area, or if they click on a single point.
	// Calculate the sizes and call the resize function to get a new image

	// Hide the zoom rectangle
	zoomInBox.style.visibility = "hidden";

	// turn off the event handlers and reset for the next mousedown
	glassSheetLayer.onmousedown = glassSheet_onMouseDown;
	glassSheetLayer.onmousemove = ShowActiveLocation;
	document.onmousemove = null;
	glassSheetLayer.onmouseup = null;
	//glassSheetLayer.oncontextmenu = null;
	glassSheetLayer.onselectstart = null;
	document.onmouseup = null;
	document.onmousedown = null;
	document.oncontextmenu = null;
	document.onselectstart = null;

	// get the top, left, height, and width of the zoom rectangle
	zoomBoxLeft = zoomInBox.style.left.replace("px", "");
	zoomBoxTop = zoomInBox.style.top.replace("px", "");
	zoomBoxWidth = zoomInBox.style.width.replace("px", "");
	zoomBoxHeight = zoomInBox.style.height.replace("px", "");
	
	// if the zoom rect is very small then they probably clicked to zoom on that point,
	// so just zoom in by a factor of 1.5, centered on the mousedown point
	if ( (zoomBoxWidth < 10) && (zoomBoxHeight < 10 ) )
	{
		var zoomFactor = 1.5	// I'll divide the height and width of the original image by this number to fake a zoom box
		zoomBoxWidth = Math.round(drawingSpaceWidth / zoomFactor);
		zoomBoxHeight = Math.round(drawingSpaceHeight / zoomFactor);
		zoomBoxLeft = Math.round(mouseDownX - (zoomBoxWidth / 2));
		zoomBoxTop = Math.round(mouseDownY - (zoomBoxHeight / 2));
	}

	// Now, see if the zoombox needs to be artifically extended either wider or taller
	// to try to keep the upper/left of the zoom box to be the upper/left of the returned image.  
	var widthAspectCanvas = drawingSpaceWidth / drawingSpaceHeight;
	var widthAspectZoom = zoomBoxWidth / zoomBoxHeight;
	var widthAspect = widthAspectCanvas / widthAspectZoom;
	if (widthAspect>1)
	{
		zoomBoxWidth *= widthAspect;
	}
	var heightAspectCanvas = drawingSpaceHeight / drawingSpaceWidth;
	var heightAspectZoom = zoomBoxHeight / zoomBoxWidth;
	var heightAspect = heightAspectCanvas / heightAspectZoom;
	if (heightAspect>1)
	{
		zoomBoxHeight *= heightAspect;
	}

	// Start the timer to zoom into zoomInBox		
	var scrMax = Math.max(drawingSpaceWidth, drawingSpaceHeight);	// Gets the larger of the Width or Height of the drawing space
	var numSteps = Math.max((900-scrMax)/50,1);	// Sets number of steps based on size of image.  Sizes > 900px will result in only 1 step
//	clearTimeout(myTimeOut);  myTimeOut = null;
//	myTimeOut = setTimeout('timerZoomInToBox(' + drawingSpaceWidth + ',' + drawingSpaceHeight + ',' + zoomBoxLeft + ',' + zoomBoxTop + ',' + zoomBoxWidth + ',' + zoomBoxHeight + ',' + numSteps + ')',10);
// just jump in one step, this was causing a problem with my other timers
	timerZoomInToBox(drawingSpaceWidth, drawingSpaceHeight, zoomBoxLeft, zoomBoxTop, zoomBoxWidth, zoomBoxHeight, 1);

	// Call the ajax function to get a new image
	//NHTMap.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, zoomBoxLeft, zoomBoxTop, zoomBoxWidth, zoomBoxHeight, changeMapImage_callback);
//	NHTMap.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, zoomBoxLeft, zoomBoxTop, zoomBoxWidth, zoomBoxHeight, pv_callback);
	getNewImage();
}

//=================================================
//   TIMER FUNCTIONS
//=================================================
//----------------------
function timerZoomIn(e)
//----------------------
{
	// Called as user holds mouse button down
	// Shrink the zoom box from the edges of the drawing space to show how far out they are zooming
	//   (depending on how long the user holds the button down)
	zoomInFactor *= 1.06;
	if (zoomInFactor > 3100) { zoomInFactor = 3100; }
	
	getMouseXY(e);
	// Now figure a way to zoom/shrink the image by percent, while keeping it centered on the original spot
	var newLeft = mouseX-((zoomInFactor/100)*mouseX);
	var newTop = mouseY-((zoomInFactor/100)*mouseY);
	actualMapImage.style.width = zoomInFactor.toString(10) + "%";
	actualMapImage.style.height = zoomInFactor.toString(10) + "%";
	actualMapImage.style.left = newLeft.toString(10) + "px";
	actualMapImage.style.top = newTop.toString(10) + "px";

	// make it run again until the user lets go of the button
	myTimeOut = setTimeout('timerZoomIn()',10);
}

//----------------------
function timerZoomOut()
//----------------------
{
	// Called as user holds mouse button down
	// Shrink the zoom box from the edges of the drawing space to show how far out they are zooming
	//   (depending on how long the user holds the button down)
	zoomOutFactor *= .96;
	if (zoomOutFactor < 3) { zoomOutFactor = 3; }
	
	// Now figure a way to zoom/shrink the image by percent, while keeping it centered on the original spot
	var newLeft = mouseDownX-((zoomOutFactor/100)*mouseDownX);
	var newTop = mouseDownY-((zoomOutFactor/100)*mouseDownY);
	newLeft = (drawingSpaceWidth/2) - (drawingSpaceWidth/2*(zoomOutFactor/100));
	newTop = (drawingSpaceHeight/2) - (drawingSpaceHeight/2*(zoomOutFactor/100));
	actualMapImage.style.width = zoomOutFactor.toString(10) + "%";
	actualMapImage.style.height = zoomOutFactor.toString(10) + "%";
	actualMapImage.style.left = newLeft.toString(10) + "px";
	actualMapImage.style.top = newTop.toString(10) + "px";

	// make it run again until the user lets go of the button
	myTimeOut = setTimeout('timerZoomOut()',10);
}

//----------------------
function timerZoomInToBox(dw, dh, zl, zt, zw, zh, numSteps, curStep)
//----------------------
{
	// Called to give a visual effect while the server is building the next map
	// Resizes and Moves the image to make the selected area fill the drawing space
	// --- Parameters ---
	// dw       = drawingSpaceWidth
	// dh       = drawingSpaceHeight
	// zl       = zoomboxLeft
	// zt       = zoomboxTop
	// zw       = zoomboxWidth
	// zh       = zoomboxHeight
	// numSteps = how many steps to take to get there
	// curStep  = which step am I on this time? (usually not passed in to the original function call, but is used when the function calls itself)
	
//	alert(dw + ',' + dh + ',' + zl + ',' + zt + ',' + zw + ',' + zh + ',' + numSteps + ',' + curStep );

	// Set the default values
	if (numSteps == '' || numSteps < 1) { numSteps = 1; }
	if (curStep == undefined) { curStep = 1; }

//	alert(dw + ',' + dh + ',' + zl + ',' + zt + ',' + zw + ',' + zh + ',' + numSteps + ',' + curStep );

	var pctDone = curStep / numSteps;
	if (pctDone > 1) { pctDone = 1; }
	var zoomPct = (((dw/zw)-1) * pctDone) + 1;	// This takes the ratio of the old image to new (dw/zw) (ie:4, our total multiplier when we finish the steps) subtracts 1 to give us a zero-base multiplier that works for each of the steps, multiplies that against the pctDone and then adds back in the original 1 to give us the base step plus the portion of the current step
	var newLeft = 0 - (zoomPct*zl*pctDone);
	var newTop = 0 - (zoomPct*zt*pctDone);
	
//	alert(pctDone + ',' + zoomPct + ',' + dw + ',' + zw + ',' + newLeft + ',' + newTop);
	
	// Move and zoom the image
	actualMapImage.style.width = (zoomPct*100).toString(10) + "%";
	actualMapImage.style.height = (zoomPct*100).toString(10) + "%";
	actualMapImage.style.left = newLeft.toString(10) + "px";
	actualMapImage.style.top = newTop.toString(10) + "px";

	// make it run again until we are at our desired size
	if (curStep < numSteps) 
	{ 
		curStep++;
//	alert(s + ',' + e + ',' + mouseDownX + ',' + newLeft + ',' + newTop );
		//myTimeOut = setTimeout('timerZoomInToBox(' + dw + ',' + dh + ',' + zl + ',' + zt + ',' + zw + ',' + zh + ',' + numSteps + ',' + curStep + ')',10);
		timerZoomInToBox(dw, dh, zl, zt, zw, zh, numSteps, curStep);
	}
}

//----------------------
function timerZoomOutToBox(w,h,l,t)
//----------------------
{
	// Called when the user does a single click zoom.
	// Expands/Shrinks the image to match the calculated pseudo zoom box
	zoomFactor *= 0.86;
	
	// Now figure a way to zoom/shrink the image by percent, while keeping it centered on the original spot
	var newLeft = mouseDownX-((zoomFactor/100)*mouseDownX);
	var newTop = mouseDownY-((zoomFactor/100)*mouseDownY);
	actualMapImage.style.width = zoomFactor.toString(10) + "%";
	actualMapImage.style.height = zoomFactor.toString(10) + "%";
	actualMapImage.style.left = newLeft.toString(10) + "px";
	actualMapImage.style.top = newTop.toString(10) + "px";

	// make it run again until we are at our desired size
	if (w < actualMapImage.offsetWidth)
	myTimeOut = setTimeout('timerZoomToBox(' + w + ',' + h + ',' + l + ',' + t + ')',10);
}



//=================================================
//   ZOOM OUT FUNCTIONS
//=================================================
//----------------------
function showZoomOutBox(e)
//----------------------
{
	// Update the global vars on where the mouse was clicked
	getMouseXY(e);

    // Now adjust the coords for the offset of our drawing space.
    mouseX -= drawingSpaceLeft;
    mouseY -= drawingSpaceTop;
	mouseDownX = mouseX;
	mouseDownY = mouseY;
}

//----------------------
function drawZoomOutBox(e)
//----------------------
{
	// Called as user drags mouse to select how far to zoom out
	// Shrink the zoom box from the edges of the drawing space to show how far out they are zooming
	//   (depending on how far the user moves the mouse from the original mousedown position)

	// Find the current location of the mouse and update the global vars
	getMouseXY(e);
    // Now adjust the coords for the offset of our drawing space.
    mouseX -= drawingSpaceLeft;
    mouseY -= drawingSpaceTop;
	
	// Find how far they are from the original point
	var totDistance = 100 + (((mouseX - mouseDownX) + (mouseY - mouseDownY)) / 3);
	// This should give us a number resembling a percent that we can use to resize the image
	if (totDistance < 10) { totDistance = 10; }
	//if (totDistance > 100) { totDistance = 100; }
	
	// Now figure a way to zoom/shrink the image by percent, while keeping it centered on the original spot
	var newLeft = mouseDownX-((totDistance/100)*mouseDownX);
	var newTop = mouseDownY-((totDistance/100)*mouseDownY);
	actualMapImage.style.width = totDistance.toString(10) + "%";
	actualMapImage.style.height = totDistance.toString(10) + "%";
	actualMapImage.style.left = newLeft.toString(10) + "px";
	actualMapImage.style.top = newTop.toString(10) + "px";

	// Show the new scale popup	
	updateNewScale();
}

//----------------------
function drawZoomOutBoxORIG(e)
//----------------------
{
	// Called as user drags mouse to select how far to zoom out
	// Shrink the zoom box from the edges of the drawing space to show how far out they are zooming
	//   (depending on how far the user moves the mouse from the original mousedown position)

	// Find the current location of the mouse and update the global vars
	getMouseXY(e);
    // Now adjust the coords for the offset of our drawing space.
    mouseX -= drawingSpaceLeft;
    mouseY -= drawingSpaceTop;
	
	// Find how far they are from the original point
	var totDistance = 100 + (((mouseX - mouseDownX) + (mouseY - mouseDownY)) / 3);
	// This should give us a number resembling a percent that we can use to resize the image
	if (totDistance < 10) { totDistance = 10; }
	//if (totDistance > 100) { totDistance = 100; }
	
	actualMapImage.style.width = totDistance.toString(10) + "%";
	actualMapImage.style.height = totDistance.toString(10) + "%";
}

//---------------
function zoomOut()
//---------------
{
	clearTimeout(myTimeOut);  myTimeOut = null;

	// Called when the user lets go of the mousebutton after dragging to select their zoom area.
	// calculate the sizes and call the resize function to get a new image

	// turn off the event handlers and reset for the next mousedown
	glassSheetLayer.onmousedown = glassSheet_onMouseDown;
	glassSheetLayer.onmousemove = ShowActiveLocation;
	document.onmousemove = null;
	glassSheetLayer.onmouseup = null;
	//glassSheetLayer.oncontextmenu = null;
	glassSheetLayer.onselectstart = null;
	document.onmouseup = null;
	document.onmouseup = null;
	document.onmousedown = null;
	document.oncontextmenu = null;
	document.onselectstart = null;

	// get the actual pixel size of the percentage resized image.  This will give us essentially a zoom in/out box for our redraw
	var newWidth = actualMapImage.offsetWidth;
	var newHeight = actualMapImage.offsetHeight;
	// Find how far the image was moved from the original location
	var panLeft = actualMapImage.style.left.replace("px", "");
	var panTop = actualMapImage.style.top.replace("px", "");
	// now compare the resized image to the actual viewport and create a 'fake' zoombox to show what the viewport looks like compared to the resized image
	var zoomRatio = newWidth / drawingSpaceWidth;
	// see if the zoomRatio is very close to 1, if so it means they clicked and released quickly...so do a simple zoom out on the point
	if (zoomRatio>.999 && zoomRatio<1.001) { zoomRatio = .5; }
	zoomBoxWidth = Math.round(drawingSpaceWidth / zoomRatio);
	zoomBoxHeight = Math.round(drawingSpaceHeight / zoomRatio);
	zoomBoxLeft = Math.round(panLeft / zoomRatio * -1);
	zoomBoxTop = Math.round(panTop / zoomRatio * -1);

	// Call the ajax function to get a new image
//	NHTMap.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, zoomBoxLeft, zoomBoxTop, (zoomBoxWidth), (zoomBoxHeight), pv_callback);

	// prevent the context menu from showing
	document.oncontextmenu = falsefunc;

	getNewImage();
}


//---------------
function zoomOutAni()
//---------------
{
	clearTimeout(myTimeOut);  myTimeOut = null;

	// Called when the user lets go of the mousebutton after clicking on a spot to center their zoom out.

	// turn off the event handlers and reset for the next mousedown
	glassSheetLayer.onmousedown = glassSheet_onMouseDown;
	glassSheetLayer.onmousemove = ShowActiveLocation;
	glassSheetLayer.onmouseup = null;
	//glassSheetLayer.oncontextmenu = null;
	glassSheetLayer.onselectstart = null;
	document.onmouseup = null;
	document.onmouseup = null;
	document.onmousedown = null;
	document.oncontextmenu = falsefunc;
	document.onselectstart = null;

	// do a simple zoom out, centering the point they clicked
	var zoomRatio = .5;
	zoomBoxWidth = Math.round(drawingSpaceWidth / zoomRatio);
	zoomBoxHeight = Math.round(drawingSpaceHeight / zoomRatio);
	zoomBoxLeft = Math.round(mouseDownX - (zoomBoxWidth / 2));
	zoomBoxTop = Math.round(mouseDownY - (zoomBoxHeight / 2));

	// Start the timer to zoom into zoomInBox		
	var scrMax = Math.max(drawingSpaceWidth, drawingSpaceHeight);	// Gets the larger of the Width or Height of the drawing space
	var numSteps = Math.max((900-scrMax)/50,1);	// Sets number of steps based on size of image.  Sizes > 900px will result in only 1 step
//	clearTimeout(myTimeOut);  myTimeOut = null;
//	myTimeOut = setTimeout('timerZoomInToBox(' + drawingSpaceWidth + ',' + drawingSpaceHeight + ',' + zoomBoxLeft + ',' + zoomBoxTop + ',' + zoomBoxWidth + ',' + zoomBoxHeight + ',' + numSteps + ')',10);
// just jump in one step, this was causing a problem with my other timers
	timerZoomInToBox(drawingSpaceWidth, drawingSpaceHeight, zoomBoxLeft, zoomBoxTop, zoomBoxWidth, zoomBoxHeight, 1);

	// Call the ajax function to get a new image
	//NHTMap.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, zoomBoxLeft, zoomBoxTop, zoomBoxWidth, zoomBoxHeight, pv_callback);
	getNewImage();
}


//=================================================
//   PAN FUNCTIONS
//=================================================
//----------------------
function grabPanStartLocation(e)
//----------------------
{
	// Update the global vars on where the mouse was clicked
	getMouseXY(e);

    // Now adjust the coords for the offset of our drawing space.
    //mouseX -= drawingSpaceLeft;
    //mouseY -= drawingSpaceTop;
	
	// set the point at which our pan started (minus the offset of the outside div) to where the mouse was first clicked
	mouseDownX = mouseX;
	mouseDownY = mouseY;
}

//----------------
function panMove(e)
//----------------
{
	// Called as user drags mouse to move the image
	// Track the offset from the starting point and eventually request a map with those offsets

	// Find the current location of the mouse and update the global vars
	getMouseXY(e);
	
	// Move the image based on the offset the mouse has moved since it first was clicked and dragged
	actualMapImage.style.position = "absolute";
	actualMapImage.style.left = (mouseX - mouseDownX ).toString(10) + "px";
	actualMapImage.style.top = (mouseY - mouseDownY ).toString(10) + "px";
}

//------------------
function panRedraw()
//------------------
{
	// Called when the user lets go of the mousebutton after dragging to select their zoom area.
	// calculate the sizes and call the resize function to get a new image

	// turn off the event handlers and reset for the next mousedown
	glassSheetLayer.onmousedown = glassSheet_onMouseDown;
	glassSheetLayer.onmousemove = ShowActiveLocation;
	document.onmousemove = null;
	glassSheetLayer.onmouseup = null;
	//glassSheetLayer.oncontextmenu = null;
	glassSheetLayer.onselectstart = null;
	document.onmouseup = null;
	document.onmousedown = null;
	document.oncontextmenu = null;
	document.onselectstart = null;

	// Find how far the image was moved from the original location
	zoomBoxLeft = actualMapImage.style.left.replace("px", "");
	zoomBoxTop = actualMapImage.style.top.replace("px", "");
	
	// Now reverse the pan values since we want to redraw the map the opposite distance we panned
	zoomBoxLeft *= -1;
	zoomBoxTop *= -1;
	
	getNewImage();
}



//=================================================
//	BEGIN: MEASURE FUNCTIONS
//=================================================
var measureStartX = 0;          // x point on map to begin drawing
var measureStartY = 0;          // y point on map to begin drawing
var initMapCX;          // initial x location in meters
var initMapCY;          // initial y location in meters
var xLength;            // distance travelled north/south
var yLength;            // distance travelled east/west
var dx;                 
var dy;
var z = 0;              // current distance travelled: x squared + y squared = z squared
var tz = 0;             // total distance
var mX;
var mY;
var jgd;                // this is the dotted line drawn when user moves mouse
var jgs;                // this is the solid line drawn after the user clicks on the second point
var jgstr;              // this location object gets drawn on mousemove
var jgstrs;             // this is the location object that gets drawn at each click except the first
var jgimg;              // this is the transparent image behind the distance indicators
var firstClick = true;
var hasClicked = false;
var gslObj;
function measureMouseDown(e)
{
	// Check to see if the user is holding down the control key
	if (!event.ctrlKey)
	{
		// Now we know they have clicked at least once. Now when they move the mouse, we will draw a dotted line.
		hasClicked = true;

		// If we drew a dotted line, remove it and replace it with a solid one.
		if (jgd)
			jgd.clear();

		// Don't do anything on the first click. After that, replace the dotted line with a solid one.
		if (!firstClick)
		{
			jgs = new jsGraphics("glassSheetLayer");
			jgs.setColor("#ff6600");
			jgs.setStroke(2);
			jgs.drawLine(measureStartX, measureStartY, dx, dy);
			jgs.paint();
		}    

		// Where did the user click?
		getMouseXY(e);
		mouseX -= drawingSpaceLeft - leftOffset;
		mouseY -= drawingSpaceTop - topOffset;

		// Set the initial x,y location based on the click
/*
		if (IE)
		{
			measureStartX = mouseX + leftOffset;
			measureStartY = mouseY + topOffset;
		}
		else
		{
*/
			measureStartX = mouseX;
			measureStartY = mouseY;
//		}

        // This is the start mouse location
        mX = parseInt(mouseX) - parseInt(drawingSpaceLeft);
        mY = drawingSpaceHeight - (parseInt(mouseY) - parseInt(drawingSpaceTop));
            
        // This is the start state plane location in meters
        initMapCX = (mX/drawingSpaceWidth*envWidth) + envMinX;
        initMapCY = (mY/drawingSpaceHeight*envHeight) + envMinY;    
        	
	    // Create the dotted line object
	    jgd = new jsGraphics("glassSheetLayer");
	    jgd.setColor("#ff6600"); // red
	    jgd.setStroke(Stroke.DOTTED);
    	
		// set font colors and css classes
		var measureClass;
		var measureColor;
		if (pv.chkColor05 || pv.chkHiRes04 || pv.chkCIR) 
		{ 
			measureClass = 'measureStatsL'; 
			measureColor = "#ffffff";
		}
		else
		{
			measureClass = 'measureStatsD'; 
			measureColor = "#000000";
		}

	    // Clear out the remnant location data from the onmousemove event.
	    if(jgstr)
	        jgstr.clear();
	    // Create the moving distance display object
	    jgstr = new jsGraphics("glassSheetLayer");
	    jgstr.setColor(measureColor);
	    jgstr.setFont("arial","10px",Font.Plain);
	    
	    // Clear out the remnant location marker or screen becomes too cluttered.
//	    if(jgstrs)
//	        jgstrs.clear();
	    jgstrs = new jsGraphics("glassSheetLayer");
	    jgstrs.setColor(measureColor);
	    jgstrs.setFont("arial","10px",Font.Plain);
	    
	    // Clear out the remnant img marker or screen becomes too cluttered.
	    //if(jgimg)
	    //    jgimg.clear();
	    //jgimg = new jsGraphics("glassSheetLayer");
    	
	    // If this is not the first click, paint a location marker on the page.
//	    if(!firstClick || 1==1)
//	    {
	        tz += z;
	        // Draw a faint background image behind the location marker
            //jgimg.drawImage("images/draw.png", dx + 10, dy - 20, 120, 35);
            //jgimg.paint();
            
            // Create the distance display object for each point
			//jgstrs.drawString("<table id='" + measureClass + "'><tr><td><b>Segment</b></td><td>" + z.toFixed(2) + "&nbsp;km</td><td>" + (z*0.6214).toFixed(2) + "&nbsp;mi</td></tr><tr><td><b>Total</b></td><td>" + tz.toFixed(2) + "&nbsp;km</td><td>" + (tz*0.6214).toFixed(2) + "&nbsp;mi</td></tr></table>",dx + 10, dy - 20);
			jgstrs.drawString(z.toFixed(3) + " km<br />" + (z*0.6214).toFixed(2) + " mi",dx + 10, dy - 20);
            //jgstrs.drawString(z.toFixed(2) + " km, " + tz.toFixed(2) + " km<br />" + (z*0.6214).toFixed(2) + " mi," + (tz*0.6214).toFixed(2) + " mi",dx + 10, dy - 20);
            jgstrs.paint();
            
//        }
        
        // The user has clicked at least once on the map interface now.
        firstClick = false;
    }
    else
    {
        resetDrawingTool();
        // Clear out the glassSheetLayer of all child nodes
        /*gslObj = document.getElementById("glassSheetLayer");
        gslObj.innerHTML = "";
        
        measureStartX = 0;
        measureStartY = 0;
        dx = 0;
        dy = 0;
        firstClick = true;
        hasClicked = false;
        tz = 0;
        z = 0;*/
    }
}


// Returns the square of the number passed in. Used in measureMouseMove.
function square(x)
{
    return x*x;
}

function measureMouseMove(e)
{
    // If they have already clicked once, it means they have selected a start location.
    if(hasClicked)
    {
        // As the mouse moves we want to clear the previous dotted line drawing and text and start a new one.
        jgd.clear();
        jgstr.clear();        
        
        getMouseXY(e);
		mouseX -= drawingSpaceLeft - leftOffset;
		mouseY -= drawingSpaceTop - topOffset;
        
/*
        if (IE)
        {
            //document.getElementById("x").innerHTML = mouseX + leftOffset;
            dx = mouseX + leftOffset;
            //document.getElementById("y").innerHTML = mouseY + topOffset;
            dy = mouseY + topOffset;
        }
        else
        {
*/
            //document.getElementById("x").innerHTML = mouseX;
            dx = mouseX;
            //document.getElementById("y").innerHTML = mouseY;
            dy = mouseY;
//        }
        
        // This is the current mouse location
        mX = parseInt(mouseX) - parseInt(drawingSpaceLeft);
        mY = drawingSpaceHeight - (parseInt(mouseY) - parseInt(drawingSpaceTop));
        
        // This is the current state plane location in meters
        newMapCX = (mX/drawingSpaceWidth*envWidth) + envMinX;
        newMapCY = (mY/drawingSpaceHeight*envHeight) + envMinY;
        
        // These are the two sides of our triangle. Using these we can calculate the distance between our clicks.
        // x squared + y squared = z squared
        xLength = newMapCX - initMapCX;
        yLength = newMapCY - initMapCY;
        
        var xLengthSquared = square(xLength);
        var yLengthSquared = square(yLength);
        // current distance
        z = (Math.sqrt(xLengthSquared + yLengthSquared))/1000;
            	
        //document.getElementById("km").innerHTML = Math.round(z);
        
        // Give the initial x/y and the new x/y to the drawing object, then paint it on the screen
        jgd.drawLine(measureStartX, measureStartY, dx, dy); // co-ordinates related to "myCanvas"
        jgd.paint();
//        jgstr.drawString("<table id='measureStats'><tr><td><b>Segment</b></td><td>" + z.toFixed(2) + "&nbsp;km</td><td>" + (z*0.6214).toFixed(2) + "&nbsp;mi</td></tr><tr><td><b>Total</b></td><td>" + tz.toFixed(2) + "&nbsp;km</td><td>" + (tz*0.6214).toFixed(2) + "&nbsp;mi</td></tr></table>",dx + 10, dy - 20);
//        jgstr.drawString("<table id='measureStats'><tr><td><b>Segment</b></td><td>" + z.toFixed(2) + "&nbsp;km</td><td>" + (z*0.6214).toFixed(2) + "&nbsp;mi</td></tr><tr><td><b>Total</b></td><td>" + (tz+z).toFixed(2) + "&nbsp;km</td><td>" + ((tz*0.6214)+(z*0.6214)).toFixed(2) + "&nbsp;mi</td></tr></table>",dx + 10, dy - 20);
        jgstr.drawString("<table id='measureStats'><tr><th>Total</th></tr><tr><td>" + (tz+z).toFixed(3) + "&nbsp;km</td></tr><tr><td>" + ((tz*0.6214)+(z*0.6214)).toFixed(2) + "&nbsp;mi</td></tr></table>",dx + 10, dy - 20);
        jgstr.paint();
    }
}

function measureMouseUp(e)
{    
    // This func doesn't do anything for now. May need it later.
}

/* The user clicked on the tool again in the toolbar to reset the tool
*/
function resetDrawingTool()
{
    // Clear out all the drawing objects
    gslObj = document.getElementById("glassSheetLayer");
    gslObj.innerHTML = "";
    // Reinitialize all the variables
    measureStartX = 0;
    measureStartY = 0;
    newX = 0;
    newY = 0;
    z = 0;
    tz = 0;
    firstClick = true;
    hasClicked = false;
    x = new Array();
    y = new Array();
    xpx = new Array();
    ypx = new Array();
    vertices = 0;
    area = 0;
    dx = 0;
    dy = 0;
}

//=================================================
//	END: MEASURE FUNCTIONS
//=================================================



//=================================================
//   ShowActiveLocation - calculates and displays 
//                        realtime mouse location
//=================================================
function ShowActiveLocation(e)
{
	// Grabs the xy position of the mouseclick, 
	// calls the conversion routines to get the lat/long, trs, etc.

	// Find the current location of the mouse and update the global vars
	var e = e || window.event;
	//if (!e) e = window.event; // works on IE, but not NS (we rely on NS passing us the event)

	if (e)
	{ 
		if (e.pageX || e.pageY)
		{ // this doesn't work on IE6!! (works on FF,Moz,Opera7)
		mouseX = e.pageX  - drawingSpaceLeft;
		mouseY = e.pageY  - drawingSpaceTop;
		//alert("e.page " + mouseX + " " + mouseY);
		}
		else if (e.clientX || e.clientY)
		{ // works on IE6,FF,Moz,Opera7
		// Note: I am adding together both the "body" and "documentElement" scroll positions
		//       this lets me cover for the quirks that happen based on the "doctype" of the html page.
		//         (example: IE6 in compatibility mode or strict)
		//       Based on the different ways that IE,FF,Moz,Opera use these ScrollValues for body and documentElement
		//       it looks like they will fill EITHER ONE SCROLL VALUE OR THE OTHER, NOT BOTH 
		//         (from info at http://www.quirksmode.org/js/doctypes.html)
		mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		//alert("e.client " + mouseX + " " + mouseY);
		}
	}

	// Now adjust the coords for the offset of our drawing space.
	mouseX -= drawingSpaceLeft;
	mouseY -= drawingSpaceTop;
	
	// convert the pixel x,y into StatePlane (envelope) x,y
	var myX = (mouseX/drawingSpaceWidth*envWidth) + envMinX;
	var myY = envMaxY - (mouseY/drawingSpaceHeight*envHeight);
	
	// calculate the Lat/Long for this location
	convertSP2LL(myX,myY)
	mylat = mapLocation.lat;
	mylon = mapLocation.lon;
	
	document.getElementById("LocLat").innerHTML = mylat.toFixed(5); // + '<br />' + myY.toFixed(0);
	document.getElementById("LocLon").innerHTML = mylon.toFixed(5); // + '<br />' + myX.toFixed(0);

//	document.getElementById("LocLat").innerHTML = mylat.toFixed(5) + ' ' + myY.toFixed(0);
//	document.getElementById("LocLon").innerHTML = mylon.toFixed(5) + ' ' + myX.toFixed(0);
}



function showEntryForm(e)
{
	setWaitCursor();

	// Grabs the xy position of the mouseclick, 
	// calls the conversion routines to get the lat/long, trs, etc.
	// then popups a form for the user to enter their sighting data.

	// Find the current location of the mouse and update the global vars
	getMouseXY(e);
	
	// Show indicator on map where they clicked
	showClickPop();
	
	// Now adjust the coords for the offset of our drawing space.
	mouseX -= drawingSpaceLeft;
	mouseY -= drawingSpaceTop;
	
	// convert the pixel x,y into StatePlane (envelope) x,y
	spX = (mouseX/drawingSpaceWidth*envWidth) + envMinX;
	spY = envMaxY - (mouseY/drawingSpaceHeight*envHeight);
	
	// Call the Ajax function to get the county, qll, trs for this location
	// Also checks to see if the person is still logged in with a session variable
	// If they have timed out, run the Logout Command and alert them that their session has timed out
	Tracker.NHTMap.GetMapLocations(spX, spY, showEntryForm2);

	// While the Ajax is running, calculate the Lat/Long for this location
	convertSP2LL(spX,spY)
}

function showEntryForm2(response) 
{
	setNormalCursor();

	//alert("Returned from MapConversions and now in showEntryForm2");
	// This runs at the end of the Ajax call and grabs the converted location variables for use in the popup form
	var ajaxLocation = response.value;

	if (response != null && response.value != null)
	{
		var ajaxLocation = response.value;
		
		if (ajaxLocation.SPX == "timed out")
		{
			Logout();
			alert('Your session has timed out.  Please Sign In again if you wish to enter sightings');
		}
		else
		{
//alert('lat=' + mapLocation.lat + ' lon=' + mapLocation.lon + ' spx=' + mapLocation.spx + ' spy=' + mapLocation.spy);
			var url = "";
			url += "SPX=" + ajaxLocation.SPX + "&";
			url += "SPY=" + ajaxLocation.SPY + "&";
			url += "Lat=" + (Math.round(mapLocation.lat*100000)/100000) + "&";
			url += "Long=" + (Math.round(mapLocation.lon*100000)/100000) + "&";
			url += "County=" + ajaxLocation.County + "&";
			url += "LL=" + ajaxLocation.LL + "&";
			url += "QLL=" + ajaxLocation.QLL + "&";
			url += "QQLL=" + ajaxLocation.QQLL + "&";
			url += "T=" + ajaxLocation.Town + "&";
			url += "N=" + ajaxLocation.N + "&";
			url += "R=" + ajaxLocation.Range + "&";
			url += "E=" + ajaxLocation.E + "&";
			url += "S=" + ajaxLocation.Section + "&";
			url += "Elev=" + ajaxLocation.Elevation + "&";
			// Figure out how Fuzzy this pixel point is based on the current zoom level
			var SpPerPixWide = envWidth / drawingSpaceWidth;
			var SpPerPixHigh = envHeight / drawingSpaceHeight;
			var FuzzyMeters = Math.round(((SpPerPixWide + SpPerPixHigh) / 2) * 5);
			url += "Fuzzy=" + String(FuzzyMeters) + "&";
			// Popup the form window
			//url = escape(url);
			var testpopup = window.open("NHTEntryForm.aspx?" + url, "entryForm", "width=770, height=600, status=0, toolbar=0, location=0, menubar=0, directories=0, resizable=1, scrollbars=1");
			if (testpopup == null)
			{
				alert("Unable to open window. Please be sure to adjust your popup blockers to allow popups from this site.");
			}
			else
			{
				testpopup.focus();
			}
		}
	}
	else
	{
		//alert("Ajax Location returned NULL");
		showMapError();
	}
}


function showFileSaveAs(type) 
{
	var testpopup = window.open("FileSaveAs.aspx?type=" + type, "fileSaveAs", "width=500, height=600, status=0, toolbar=0, location=0, menubar=0, directories=0, resizable=1, scrollbars=1");
	if (testpopup == null)
	{
		alert("Unable to open window. Please be sure to adjust your popup blockers to allow popups from this site.");
	}
	else
	{
		testpopup.focus();
	}
}


//#*#*#*#*#*#*#*Map conversion functions#*#*#*#*#*#*#*#*#*
// Look for some good formulas at http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.HTM
// And view the source on http://pages.globetrotter.net/roule/utmgoogle.htm

var lat;
var lon;
var dNorthing;
var dEasting;


function convertSP2LL(x,y) // where x,y are StatePlane coordinates
{    
	// Set up the coordinate system parameters.
	A = 6378137;               // major radius of ellipsoid, map units
	E = 0.08181922146 ;         // eccentricity of ellipsoid
	AngRad = 0.01745329252 ;    // number of radians in a degree
	Pi4 = 3.141592653589793238 / 4 ;  // Pi / 4
	P1 = 45 * AngRad ;         // latitude of first standard parallel
	P2 = 49 * AngRad ;         // latitude of second standard parallel
	P0 = 44.25 * AngRad ;      // latitude of origin
	M0 = -109.5 * AngRad ;     // central meridian
	X0 = 600000 ;               // False easting of central meridian, map units

	// Calculate the coordinate system constants.
	m1 = Math.cos(P1) / Math.sqrt(1 - ( Math.pow(E,2) * Math.pow(Math.sin(P1),2) ) );
	m2 = Math.cos(P2) / Math.sqrt(1 - ( Math.pow(E,2) * Math.pow(Math.sin(P2),2) ) ) ;
	t1 = Math.sin(Pi4 - (P1 / 2)) / Math.cos(Pi4 - (P1 / 2)) ;
	t1 = t1 / Math.pow(   ( (1 - (E * (Math.sin(P1)))) / (1 + (E * (Math.sin(P1)))) ), (E/2) ) ;
	t2 = Math.sin(Pi4 - (P2 / 2)) / Math.cos(Pi4 - (P2 / 2)) ;
	t2 = t2 /  Math.pow( ( (1 - (E * (Math.sin(P2)))) / (1 + (E * (Math.sin(P2)))) )   ,(E/2)) ;
	t0 = Math.sin(Pi4 - (P0 / 2)) / Math.cos(Pi4 - (P0 / 2)) ;
	t0 = t0 / Math.pow(    (  (1 - (E * (Math.sin(P0))))   / (1 + (E * (Math.sin(P0))))  )   ,(E/2)) ;
	n = Math.log(m1 / m2) / Math.log(t1 / t2) ;
	F = m1 / (n *   Math.pow(t1,n) ) ;
	rho0 = A * F * Math.pow(t0,n) ;


// Convert the coordinate to Latitude/Longitude.

	// Calculate the Longitude.
	x = x - X0 ;
	Pi2 = Pi4 * 2 ;
	rho = Math.sqrt( Math.pow(x,2) + Math.pow((rho0 - y),2) ) ;
	theta = Math.atan2(x,(rho0 - y)) ;
	t = Math.pow( (rho / (A * F)), (1 / n) ) ;
	Lon = theta / n + M0 ;
	x = x + X0 ;


	// Estimate the Latitude
	Lat0 = Pi2 - (2 * Math.atan2(t,1)) ;


	// Substitute the estimate into the iterative calculation that
	// converges on the correct Latitude value.
	part1 = (1 - (E * Math.sin(Lat0))) / (1 + (E * Math.sin(Lat0))) ;
	Lat1 = Pi2 - (2 * Math.atan2( (t * Math.pow(part1,(E/2)) ) ,1) ) ;

	do 
	{
		Lat0 = Lat1 ;	    
		part1 = (1 - (E * Math.sin(Lat0))) / (1 + (E * Math.sin(Lat0))) ;	    
		Lat1 = Pi2 - (2 * Math.atan2(  (t * Math.pow(part1, (E/2)))  ,1)) ;
	}
	while (Math.abs(Lat1 - Lat0) < 0.000000002)

	// Convert from radians to degrees.
	Lat1 = Lat1 / AngRad ;
	Lon = Lon / AngRad ;

	lat = Lat1; // clean these up and reconcile code with UTM function
	lon = Lon;
	
	// Copy the values to the mapLocation Object
	mapLocation.spx = x;
	mapLocation.spy = y;
	mapLocation.lat = lat;
	mapLocation.lon = lon;

	
	//location.replace('./downloadpoint.aspx?px=' + Lon.toFixed(4) + '&py=' + Lat1.toFixed(4)); //,'',370,440,'no');

	//window.status = 'lat: ' + Lat1.toFixed(4) + ' lon: ' + Math.abs(Lon.toFixed(4));
}


function convertLatLong(lt,ln)
{
	// Might be able to make these global vars if I can be sure the names aren't used elsewhere.
	// So for now, I'll just paste them inside these functions.  A little redundant, but can be cleaned up later.

	mapLocation.lat = lt;
	mapLocation.lon = ln;

	// Set up the coordinate system parameters.
	var a = 6378137               //major radius of ellipsoid, map units (NAD 83)
	var e = 0.08181922146         //eccentricity of ellipsoid (NAD 83)
	var angRad = 0.01745329252    //number of radians in a degree
	var pi4 = 0.7853981633955     //Pi / 4
	var p0 = 0.77230819401        //latitude of origin
	var p1 = 0.7853981634         //latitude of first standard parallel
	var p2 = 0.85521133348        //latitude of second standard parallel
	var m0 = -1.91113553094       //central meridian
	var X0 = 600000               //False easting of central meridian, map units

	// check if longitude is negative
	if (ln > 0)
	{
		ln = -ln;
	}

	var m1, m2;
	var t0, t1, t2;
	var n, f;
	var rho0;
	var t, x, y;
	var rho, theta;


	//calculated constants
	m1 = Math.cos(p1) / Math.sqrt( 1 - ( Math.pow(e,2) * Math.pow(Math.sin(p1),2) ) ); //ok
	m2 = Math.cos(p2) / Math.sqrt( 1 - ( Math.pow(e,2) * Math.pow(Math.sin(p2),2) ) ); //ok
	t0 = (Math.tan(pi4 - (p0 / 2)))    /    Math.pow( ( 1 - (e * Math.sin(p0)) ) / ( 1 + (e * Math.sin(p0)) ), (e / 2) )   ;
	t1 = (Math.tan(pi4 - (p1 / 2)))    /    Math.pow( ( 1 - (e * Math.sin(p1)) ) / ( 1 + (e * Math.sin(p1)) ), (e / 2) )   ;
	t2 = (Math.tan(pi4 - (p2 / 2)))    /    Math.pow( ( 1 - (e * Math.sin(p2)) ) / ( 1 + (e * Math.sin(p2)) ), (e / 2) )   ;
	n = Math.log(m1 / m2) / Math.log(t1 / t2);
	f = m1 / (n * Math.pow(t1,n));
	rho0 = a * f * Math.pow(t0,n);

	//Convert the latitude/longitude to a coordinate.
	lt = lt * angRad;
	ln = ln * angRad;
	t = Math.tan(pi4 - (lt / 2));

	t = t / Math.pow(( 1 - ( e * Math.sin(lt) ) )  /   (1 + (e * Math.sin(lt))), (e / 2) );

	rho = a * f * Math.pow(t,n);
	theta = n * (ln - m0);
	x = (rho * Math.sin(theta)) + X0;
	y = rho0 - (rho * Math.cos(theta));

	dEasting = Math.round(x,2);
	dNorthing = Math.round(y,2);

	// Copy the values to the mapLocation Object
	mapLocation.spx = dEasting;
	mapLocation.spy = dNorthing;
}

function convertDDM2LL(latDeg, latMinSec, lonDeg, lonMinSec)
{
	var latDecimal = latMinSec/60;
	latDecimal = latDecimal*1000;
	latDecimal = Math.round(latDecimal)/1000;
	lat = parseFloat(latDeg) + latDecimal

	var lonDecimal = lonMinSec/60;
	lonDecimal = lonDecimal*1000;
	lonDecimal = Math.round(lonDecimal)/1000;
	lon = parseFloat(lonDeg) + lonDecimal;
	convertLatLong(lat,lon);
	//alert('lat = ' + lat + '  long = ' + lon);
}

function convertDMS2LL(latDeg, latMin, latSec, lonDeg, lonMin, lonSec)
{
	var latMinutes = parseFloat(latMin) + parseFloat(latSec/60);
	var latMinutesDec = latMinutes/60;
	latMinutesDec = latMinutesDec*1000;
	latMinutesDec = Math.round(latMinutesDec)/1000;
	lat = parseFloat(latDeg) + latMinutesDec;

	var lonMinutes = parseFloat(lonMin) + parseFloat(lonSec/60);
	var lonMinutesDec = lonMinutes/60;
	lonMinutesDec = lonMinutesDec*1000;
	lonMinutesDec = Math.round(lonMinutesDec)/1000;
	lon = parseFloat(lonDeg) + lonMinutesDec;

	convertLatLong(lat,lon);
}

function convertUTM2LL(zone, northing, easting, isNAD27)
{
	// Converts z/n/e to LL and calls convertLatLong which stores the new LL and also SP
	var deg2rad = Math.PI / 180;
	var rad2deg = 180.0 / Math.PI;
	var pi = Math.PI;


	var axis = 6378137;
	var eccent = 0.00669438;
	var scaleTm = 0.9996;
	var eastingOrg = 500000;
	var k0 = scaleTm;

	if (isNAD27) 
	{
		axis = 6378206.4;
		eccent = 0.006768658;
	}

	var e1 = (1 - Math.sqrt(1 - eccent)) / (1 + Math.sqrt(1 - eccent));
	var x = easting - eastingOrg; //remove 500,000 meter offset for longitude
	var y = northing;

	var nhemisphere = 1;

	var longorig = (zone - 1) * 6 - 180 + 3;  //+3 puts origin in middle of zone

	// alert("zone = " + (zone*1 + 76));
	// alert("longorig = " + longorig);

	var eccPrimeSquared = (eccent) / (1-eccent);
	var M = y / k0;
	var mu = M / (axis * (1 - eccent / 4 - 3 * eccent * eccent / 64 - 5 * eccent * eccent * eccent / 256));
	var phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu);
	var phi1 = phi1Rad * rad2deg;
	var N1 = axis / Math.sqrt(1 - eccent * Math.sin(phi1Rad) * Math.sin(phi1Rad));

	var T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad);
	var C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad);
	var R1 = axis * (1 - eccent) / Math.pow(1-eccent * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5);
	var D = x / (N1 * k0);
	var lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720);
	lat = lat * rad2deg;
	var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad);
	lon = longorig + lon * rad2deg;

	convertLatLong(lat,lon);
}




//============================================================================================================================
//============================================================================================================================
//============================================================================================================================
// SAMPLE FOR DRAG DIVS BY MOUSE
// USE FOR MOUSEDOWN MOUSEMOVE MOUSEUP ROUTINES
//============================================================================================================================
//============================================================================================================================
//============================================================================================================================

var origx = 0;
var origy = 0;
var orix = 0;
var oriy = 0;
var elex = 0;
var eley = 0;

var dragobj = null;
var containerobj = null;

function getMouseXY(e) // works on IE6,FF,Moz,Opera7
{ 
  var e = e || window.event;
  //if (!e) e = window.event; // works on IE, but not NS (we rely on NS passing us the event)

  if (e)
  { 
    if (e.pageX || e.pageY)
    { // this doesn't work on IE6!! (works on FF,Moz,Opera7)
      mouseX = e.pageX  - drawingSpaceLeft;
      mouseY = e.pageY  - drawingSpaceTop;
	  //alert("e.page " + mouseX + " " + mouseY);
    }
    else if (e.clientX || e.clientY)
    { // works on IE6,FF,Moz,Opera7
      // Note: I am adding together both the "body" and "documentElement" scroll positions
      //       this lets me cover for the quirks that happen based on the "doctype" of the html page.
      //         (example: IE6 in compatibility mode or strict)
      //       Based on the different ways that IE,FF,Moz,Opera use these ScrollValues for body and documentElement
      //       it looks like they will fill EITHER ONE SCROLL VALUE OR THE OTHER, NOT BOTH 
      //         (from info at http://www.quirksmode.org/js/doctypes.html)
      mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
      mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	  //alert("e.client " + mouseX + " " + mouseY);
    }
  }
  window.status = mouseX + " " + mouseY;
}

function update(e)
{
  getMouseXY(e); // NS is passing (event), while IE is passing (null)

  document.getElementById('span_browser').innerHTML = navigator.appName;
  document.getElementById('span_winevent').innerHTML = window.event ? window.event.type : '(na)';
  document.getElementById('span_autevent').innerHTML = e ? e.type : '(na)';
  document.getElementById('span_mousex').innerHTML = mousex;
  document.getElementById('span_mousey').innerHTML = mousey;
  document.getElementById('span_origx').innerHTML = origx;
  document.getElementById('span_origy').innerHTML = origy;
  document.getElementById('span_orix').innerHTML = orix;
  document.getElementById('span_oriy').innerHTML = oriy;
  document.getElementById('span_elex').innerHTML = elex;
  document.getElementById('span_eley').innerHTML = eley;
  document.getElementById('span_dragobj').innerHTML = dragobj ? (dragobj.id ? dragobj.id : 'unnamed object') : '(null)';
}

function grab(context)
{
  document.onmousedown = falsefunc; // in NS this prevents cascading of events, thus disabling text selection
  dragobj = context;
  dragobj.style.zIndex = 10; // move it to the top
  document.onmousemove = drag;
  document.onmouseup = drop;
  origx = mousex;
  origy = mousey;
  elex = orix = dragobj.offsetLeft;
  eley = oriy = dragobj.offsetTop;
  update();
}

function drag(e) // parameter passing is important for NS family 
{
  if (dragobj)
  {
    elex = orix + (mousex-origx);
    eley = oriy + (mousey-origy);
    dragobj.style.position = "absolute";
    dragobj.style.left = (elex).toString(10) + 'px';
    dragobj.style.top  = (eley).toString(10) + 'px';
  }
  update(e);
  return false; // in IE this prevents cascading of events, thus text selection is disabled
}

function drop()
{
  if (dragobj)
  {
    dragobj.style.zIndex = 0;
    dragobj = null;
  }
  update();
//  document.onmousemove = update; // this allows the mouse to be tracked at all times
  document.onmousemove = null;
  document.onmouseup = null;
  document.onmousedown = null;   // re-enables text selection on NS
	//document.oncontextmenu = null;
	document.onselectstart = null;
}




function ratz() // where x,y are StatePlane coordinates
{    
	var x = 878893.463132054;
	var y = 115127.556339745;
	
	// Set up the coordinate system parameters.
	A = 6378137;               // major radius of ellipsoid, map units
	E = 0.08181922146 ;         // eccentricity of ellipsoid
	AngRad = 0.01745329252 ;    // number of radians in a degree
	Pi4 = 3.141592653589793238 / 4 ;  // Pi / 4
	P1 = 45 * AngRad ;         // latitude of first standard parallel
	P2 = 49 * AngRad ;         // latitude of second standard parallel
	P0 = 44.25 * AngRad ;      // latitude of origin
	M0 = -109.5 * AngRad ;     // central meridian
	X0 = 600000 ;               // False easting of central meridian, map units

	// Calculate the coordinate system constants.
	m1 = Math.cos(P1) / Math.sqrt(1 - ( Math.pow(E,2) * Math.pow(Math.sin(P1),2) ) );
	m2 = Math.cos(P2) / Math.sqrt(1 - ( Math.pow(E,2) * Math.pow(Math.sin(P2),2) ) ) ;
	t1 = Math.sin(Pi4 - (P1 / 2)) / Math.cos(Pi4 - (P1 / 2)) ;
	t1 = t1 / Math.pow(   ( (1 - (E * (Math.sin(P1)))) / (1 + (E * (Math.sin(P1)))) ), (E/2) ) ;
	t2 = Math.sin(Pi4 - (P2 / 2)) / Math.cos(Pi4 - (P2 / 2)) ;
	t2 = t2 /  Math.pow( ( (1 - (E * (Math.sin(P2)))) / (1 + (E * (Math.sin(P2)))) )   ,(E/2)) ;
	t0 = Math.sin(Pi4 - (P0 / 2)) / Math.cos(Pi4 - (P0 / 2)) ;
	t0 = t0 / Math.pow(    (  (1 - (E * (Math.sin(P0))))   / (1 + (E * (Math.sin(P0))))  )   ,(E/2)) ;
	n = Math.log(m1 / m2) / Math.log(t1 / t2) ;
	F = m1 / (n *   Math.pow(t1,n) ) ;
	rho0 = A * F * Math.pow(t0,n) ;


// Convert the coordinate to Latitude/Longitude.

	// Calculate the Longitude.
	x = x - X0 ;
	Pi2 = Pi4 * 2 ;
	rho = Math.sqrt( Math.pow(x,2) + Math.pow((rho0 - y),2) ) ;
	theta = Math.atan2(x,(rho0 - y)) ;
	t = Math.pow( (rho / (A * F)), (1 / n) ) ;
	Lon = theta / n + M0 ;
	x = x + X0 ;


	// Estimate the Latitude
	Lat0 = Pi2 - (2 * Math.atan2(t,1)) ;


	// Substitute the estimate into the iterative calculation that
	// converges on the correct Latitude value.
	part1 = (1 - (E * Math.sin(Lat0))) / (1 + (E * Math.sin(Lat0))) ;
	Lat1 = Pi2 - (2 * Math.atan2( (t * Math.pow(part1,(E/2)) ) ,1) ) ;

	do 
	{
		Lat0 = Lat1 ;	    
		part1 = (1 - (E * Math.sin(Lat0))) / (1 + (E * Math.sin(Lat0))) ;	    
		Lat1 = Pi2 - (2 * Math.atan2(  (t * Math.pow(part1, (E/2)))  ,1)) ;
	}
	while (Math.abs(Lat1 - Lat0) < 0.000000002)

	// Convert from radians to degrees.
	Lat1 = Lat1 / AngRad ;
	Lon = Lon / AngRad ;

	lat = Lat1; // clean these up and reconcile code with UTM function
	lon = Lon;
	
	// Copy the values to the mapLocation Object
	alert('x=' + x + '\ny=' + y + '\nLat=' + lat + '\nLon=' + lon);

	
	//location.replace('./downloadpoint.aspx?px=' + Lon.toFixed(4) + '&py=' + Lat1.toFixed(4)); //,'',370,440,'no');

	//window.status = 'lat: ' + Lat1.toFixed(4) + ' lon: ' + Math.abs(Lon.toFixed(4));
}


