function falsefunc() { return false; } // used to block cascading events


/*	Leftover remnant from the bird map. Don't think I need it but not sure yet.
*/
function glassSheet_onMouseDown()
{
	// 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;
	
	// keep mousedown from acting on it's own
	return false;
}


//=================================================
//   BEGIN: ZOOM IN FUNCTIONS
//=================================================
/*	The user clicked and held the left mouse button on the map surface. This is the starting point
	of the zoom box.
*/
function zoomInMouseDown(eventObj)
{	
    // Update the global vars on where the mouse was clicked
	getMouseXY(eventObj);
	
	// 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 - accordionWidth - 10) + "px";
	zoomInBox.style.top = (mouseDownY - headerHeight - toolBarHeight) + "px";
	zoomInBox.style.height = 1 + "px";
	zoomInBox.style.width = 1 + "px";
	//alert(zoomInBox.style.left + "," + zoomInBox.style.top + "," + zoomInBox.style.height + "," + zoomInBox.style.width);
			
	// Set the mousebutton's status to true
	mouseButtonDown = true;
}


/*	The user is now dragging the mouse across the map surface to draw the zoom box.
*/
function zoomInMouseMove(eventObj)
{	
	// 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)

	if (mouseButtonDown == true){
		// Find the current location of the mouse and update the global vars
		getMouseXY(eventObj);
		
		// Make the zoom box visible
		zoomInBox.style.visibility = "visible";
		
		// Set the Left and Width, drawing either from mousedown point to current...or current to mousedown
		//alert(mouseX + ":" + mouseDownX + ":" + rightOffset);
		if ( mouseX > mouseDownX )
		{
		    if(IE) {
			    zoomInBox.style.left = (mouseDownX - accordionWidth) + "px";
			    if ((mouseX - mouseDownX + rightOffset) < 0)
			    {
			        zoomInBox.style.width = 2 + "px";
			    }
			    else
			    {
			        zoomInBox.style.width = (mouseX - mouseDownX + rightOffset) + "px";
			    }
			}
			else {
			    zoomInBox.style.left = (mouseDownX - accordionWidth) + "px";
			    zoomInBox.style.width = (mouseX - mouseDownX + rightOffset) + "px";
			}
			
		}
		else
		{
		    if (IE) {
			    zoomInBox.style.left = (mouseX + leftOffset - accordionWidth) + "px";
			    zoomInBox.style.width = (mouseDownX - mouseX) + "px";
			}
			else {
			    zoomInBox.style.left = (mouseX - accordionWidth) + "px";
			    zoomInBox.style.width = (mouseDownX - mouseX) + "px";
			}
		}

		// Set the Top and Height, drawing either from mousedown point to current...or current to mousedown
		if ( mouseY > mouseDownY )
		{
		    if (IE) {
			    zoomInBox.style.top = (mouseDownY + topOffset - headerHeight - toolBarHeight) + "px";
			    zoomInBox.style.height = (mouseY - mouseDownY + bottomOffset) + "px";
			}
		    else {
		        zoomInBox.style.top = (mouseDownY - headerHeight - toolBarHeight) + "px";
			    zoomInBox.style.height = (mouseY - mouseDownY + bottomOffset) + "px";
		    }
		}
		else
		{
		    if (IE) {
			    zoomInBox.style.top = (mouseY + topOffset - headerHeight - toolBarHeight) + "px";
			    zoomInBox.style.height = (mouseDownY - mouseY) + "px";
			}
			else {
			    zoomInBox.style.top = (mouseY - headerHeight - toolBarHeight) + "px";
			    zoomInBox.style.height = (mouseDownY - mouseY) + "px";
			}
		}
	}
}


/*	The user is done drawing the zoom in box and the mouse up event is now being called.
*/
function zoomInMouseUp()
{
	// Set this to false - no more drawing will occur
	mouseButtonDown = false;
	
	// Let the user know we are waiting for a new image.
	setWaitCursor();

	// Hide the zoom rectangle
	zoomInBox.style.visibility = "hidden";
	
	document.onmouseup = null;

	// get the top, left, height, and width of the zoom rectangle
	var zoomInBoxLeft = zoomInBox.style.left.replace("px", "");
	var zoomInBoxTop = zoomInBox.style.top.replace("px", "");
	var zoomInBoxWidth = zoomInBox.style.width.replace("px", "");
	var zoomInBoxHeight = zoomInBox.style.height.replace("px", "");
	//mydebug += "zoombox before adjust (LTWH) (" + zoomInBoxLeft + "," + zoomInBoxTop + "," + zoomInBoxWidth + "," + zoomInBoxHeight + ")\n";
	//adjust for the offset of the drawingspace
	//zoomInBoxLeft -= drawingSpaceLeft;
	//zoomInBoxTop -= drawingSpaceTop;
	
	//alert(zoomInBox.style.left + "," + zoomInBox.style.top + "," + zoomInBox.style.height + "," + zoomInBox.style.width);
	
	// if the zoom rect is very small then they probably clicked to zoom on that point,
	// so just zoom in by a factor of 2, centered on the mousedown point
	if ((zoomInBoxWidth < 10) && (zoomInBoxHeight < 10 )){
		var zoomFactor = 2	// I'll divide the height and width of the original image by this number to fake a zoom box
		zoomInBoxWidth = Math.round(drawingSpaceWidth / zoomFactor);
		zoomInBoxHeight = Math.round(drawingSpaceHeight / zoomFactor);
		zoomInBoxLeft = Math.round(mouseDownX - accordionWidth - (zoomInBoxWidth / 2));
		zoomInBoxTop = Math.round(mouseDownY - headerHeight - toolBarHeight - (zoomInBoxHeight / 2));
	}
		
	// debugText += "mouseDownX: " + mouseDownX + "\n";
	// debugText += "mouseDownY: " + mouseDownY + "\n";
	// debugText += "drawingSpaceWidth: " + drawingSpaceWidth + "\n";
	// debugText += "drawingSpaceHeight: " + drawingSpaceHeight + "\n";
	// debugText += "zoomInBoxTop: " + zoomInBoxTop + "\n";
	// debugText += "zoomInBoxLeft: " + zoomInBoxLeft + "\n" + "zoomInBoxWidth: " + zoomInBoxWidth + "\n" + 
	// 	"zoomInBoxHeight: " + zoomInBoxHeight + ")\n";
	// document.getElementById('textArea').value = debugText;

	// Call the ajax function to get a new image
	BigHole.Map.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, zoomInBoxTop, zoomInBoxLeft, zoomInBoxWidth, 
		zoomInBoxHeight, changeMapImage_callback);
}
//=================================================
//   END: ZOOM IN FUNCTIONS
//=================================================


//=================================================
//   BEGIN: ZOOM OUT FUNCTIONS
//=================================================
/*	Currently zoom out is just a button click on the map surface. A zoom out box is not drawn.
	This function gets the x/y location of the mouse down event.
*/
function zoomOutMouseDown(eventObj)
{
	// document.getElementById('textArea').value = "";
	mydebug = "";
	// Get the current mouse coords. objCoords will be populated with an xyObj constructor
	//var objCoords = getMouseXY(eventObj);
	getMouseXY(eventObj);

	zoomoutX = parseInt(mouseX) - parseInt(drawingSpaceLeft);
	zoomoutY = drawingSpaceHeight - parseInt(mouseY) + parseInt(drawingSpaceTop);
}
 

/*	Handles mouse up
*/
function zoomOutMouseUp()
{
	//eventCalled = "getZoomOutCoords";
	
	setWaitCursor();
	
	zoomFactor = .5;
	zoomOut(zoomFactor);
}


/*	Called from zoomOutMouseUp. Go get the new map.
*/
function zoomOut(zoomFactor)
{
	var zoomOutWidth = Math.round(drawingSpaceWidth/zoomFactor);
	var zoomOutHeight = Math.round(drawingSpaceHeight/zoomFactor);
	var zoomOutLeft = Math.round(zoomoutX - (zoomOutWidth/2));
	var zoomOutTop = Math.round(zoomoutY - (zoomOutHeight/2));
	//var zoomOutLeft = Math.round(mouseX - (zoomOutWidth/2));
	//var zoomOutTop = Math.round(mouseY - (zoomOutHeight/2));
	
	// Call the ajax function to get a new image
	BigHole.Map.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, zoomOutTop, zoomOutLeft, zoomOutWidth, 
		zoomOutHeight, changeMapImage_callback);
}
//=================================================
//   END: ZOOM OUT FUNCTIONS
//=================================================


//=================================================
//   BEGIN: PAN FUNCTIONS
//=================================================
/*	Called when user has selected the pan tool and has now clicked down on the mapsurface.
*/
function panMouseDown(eventObj)
{
	// document.getElementById("textArea").value = "";
	// Update the global vars on where the mouse was clicked
	getMouseXY(eventObj);
	// mydebug += "********** PAN ************\n";
	// mydebug += " - mouseDownXY = " + mouseX + "/" + mouseY + "\n";

    // Now adjust the coords for the offset of our drawing space.
    //mouseX -= drawingSpaceLeft;
    //mouseY -= drawingSpaceTop;
	// mydebug += " - mouseXY = " + mouseX + "/" + mouseY + "\n";
	// document.getElementById('textArea').value = mydebug;

	// 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;
	
	mouseButtonDown = true;
}


/*	The user is now dragging the mouse across the map surface and dragging the map image with it.
*/
function panMouseMove(eventObj)
{
	// Find the current location of the mouse and update the global vars
	getMouseXY(eventObj);
	
	// Move the image based on the offset the mouse has moved since it first was clicked and dragged
	if (mouseButtonDown == true){
		// Find the current location of the mouse and update the global vars
		getMouseXY(eventObj);
		
		actualMapImage.style.position = "absolute";
		actualMapImage.style.left = (mouseX - mouseDownX ).toString(10) + "px";
		actualMapImage.style.top = (mouseY - mouseDownY ).toString(10) + "px";
		tempPanMapImage.style.position = "absolute";
		tempPanMapImage.style.left = (mouseX - mouseDownX ).toString(10) + "px";
		tempPanMapImage.style.top = (mouseY - mouseDownY ).toString(10) + "px";
	}
}


/*	User is done dragging the image and has released the mouse button.
*/
function panMouseUp()
{		
	setWaitCursor();

	document.onmouseup = null;

	// 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 reverse the pan values since we want to redraw the map the opposite distance we panned
	panLeft *= -1;
	panTop *= -1;
	
	// mydebug += "Calling PanZoomMap (" + drawingSpaceWidth + ", " + drawingSpaceHeight + ", " + panTop + ", " + panLeft + ", " + drawingSpaceWidth + ", " + drawingSpaceHeight + ")\n";
	// document.getElementById('textArea').value = mydebug;
	
	mouseButtonDown = false;

	// Call the ajax function to get a new image
	BigHole.Map.PanZoomMap(drawingSpaceWidth, drawingSpaceHeight, panTop, panLeft, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
	
}
//=================================================
//   END: PAN FUNCTIONS
//=================================================


//=================================================
//   BEGIN: FULL EXTENT FUNCTIONS
//=================================================
/*	This function is called when the user clicks on the full extent map tool button.
*/
function GoToFullExtent()
{
	BigHole.Map.GoToFullExtent(drawingSpaceWidth, drawingSpaceHeight, fullExtent_callback);
}
//=================================================
//   END: FULL EXTENT FUNCTIONS
//=================================================


//=================================================
//   BEGIN: RESET LAYERS FUNCTIONS
//=================================================
/*	This function is called when the user clicks on the full extent map tool button.
*/
function ResetLayers()
{
	setWaitCursor();
	
	for (i=0;(rad = document.getElementsByName("rad")[i]);i++)
	{
	    switch (rad.id)
	    {
	        case "dem":
	            rad.checked = true;
	            break;
	        default:
	            rad.checked = false
	            break;
	    }
	}
	
	for (i=0;(chk = document.getElementsByName("chk")[i]);i++)
	{
	    switch (chk.id)
	    {
	        case "town":
	        case "dem":
	        case "hillshade":
	        case "stream":
	            chk.checked = true;
	            break;
	        default:
	            chk.checked = false;
	    }
	}
	
	for (i=0;(labelChk = document.getElementsByName("labelChk")[i]);i++)
	{
	    switch (labelChk.id)
	    {
	        case "labels":
	            labelChk.checked = true;
	            break;
	        default:
	            labelChk.checked = false;
	    }
	}
	
	for (i=0;(ddl = document.getElementsByName("ddl")[i]);i++)
	{
	    ddl.options.length = 0;
    }
	
	// String variable to hold layers
	var layerList = "";
	
	// Create the layerList from the chkBoxes and chkLayers arrays
	for (i=0;i<chkBoxes.length;i++)
    {
        switch (chkBoxes[i])
        {
            case "town":
                layerList += "town,true|";
                break;
            case "dem":
                layerList += "dem,true|";
                break;
            case "hillshade":
                layerList += "hillshade,true|";
                break;
            case "stream":
                layerList += "stream,true|";
                break;
            default:
                layerList += getResetLayerList(i);
                break;
        }
        
    }
    	
    BigHole.Map.ToggleLayers(layerList, changeMapImage_callback);
	
	// Populate the identify drop down list with active vector layers
	filterIdentifyList();
}


/*  Called from ResetLayers to parse layers and create the layers list
*/
function getResetLayerList(index)
    {
        // String variable to hold layers
	    var layers = "";
    	
        var aLayer = chkLayers[index].split(",");
        
        for (t=0;t<aLayer.length;t++)
        {
            layers += aLayer[t] + ",false|";
        }
        
        return layers;
    }
//=================================================
//   END: RESET LAYERS FUNCTIONS
//=================================================


//=================================================
//   BEGIN: IDENTIFY FUNCTIONS
//=================================================
var identifyX = 0;
var identifyY = 0;

function identifyMouseDown(eventObj)
{
	// Check to see that the left mouse button is down
	if ( eventObj.button == 1 || eventObj.which == 1)
	{
		// Get the current mouse coords. objCoords will be populated with an xyObj constructor
		getMouseXY(eventObj);

		identifyX = parseInt(mouseX) - parseInt(drawingSpaceLeft);
		identifyY = drawingSpaceHeight - (parseInt(mouseY) - parseInt(drawingSpaceTop));
	}
	
	//alert("dsh:" + drawingSpaceHeight + " mouseY:" + mouseY + " identifyY:" + identifyY);
	//alert("dsw:" + drawingSpaceWidth + " mouseX:" + mouseX + " identifyX:" + identifyX);
}

function identifyMouseUp()
{
	setWaitCursor();
	
	// calculate the real world coordinates of the origin point
	var mapCX = (identifyX/drawingSpaceWidth*envWidth) + envMinX;
	var mapCY = (identifyY/drawingSpaceHeight*envHeight) + envMinY;
	
	convertSP2LL(mapCX, mapCY);
	
	var layerID;
	
	layerID = document.getElementById("selectIdentify").options[document.getElementById("selectIdentify").selectedIndex].value;
	
	if(layerID != "No Layers Available" && layerID != "")
	{
	    document.getElementById("identifyDivHeaderText").innerHTML = "Identify Results for: " + document.getElementById("selectIdentify").options[document.getElementById("selectIdentify").selectedIndex].text;
	    BigHole.Map.Identify(mapCX, mapCY, layerID, drawingSpaceWidth, drawingSpaceHeight, identify_callback);
	}
	else
	{
	    document.getElementById("identifyDivBody").innerHTML = "<p>There are no identifiable layers active. Please turn on a identifiable layer and try again.</p>";
	    if (document.getElementById("identifyDiv").style.display == "none" || document.getElementById("identifyDiv").style.display == "")
	        showBox('identify');
	    setNormalCursor();
	}
}

//=================================================
//   END: IDENTIFY FUNCTIONS
//=================================================


//=================================================
//	BEGIN: QUERY FUNCTIONS
//=================================================

function findCity(){
    setWaitCursor();
    
    var cityName = document.getElementById('citySelect').value;
    
    // I am using an already written method of finding a city so we just set this variable
    var featureType = "ppl";
    
    BigHole.Map.FindCity(featureType,cityName,drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
}


/*  Called when the user hits the Search button for a parcel owner search
*/
function processParcelOwner(){
    
    setWaitCursor();
    
    var ownerName = document.getElementById('parcelOwnerName').value;
    var countyCD = document.getElementById('countySelect').value;
    
    BigHole.Map.GetParcelOwnerList(countyCD, ownerName, getParcelOwnerList_callback);
//     showBox('identify');
//     setNormalCursor();
}


/*  Called when the user selects a location to find in the named features list from the query box
*/
function findParcelOwner(objectID){
    setWaitCursor();
    BigHole.Map.DisplaySearchResults(objectID, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
}


/*  Called when the user hits the Search button for a named features search
*/
function processNamedFeatures(){
    
    setWaitCursor();
    
    var featureName = document.getElementById('featureName').value;
    // Get a comma seperated list of featureTypes
    var featureTypes = document.getElementById('featureTypes');
    var featureTypesList = "'";
    for (var i=0;i<featureTypes.options.length;i++){
        if (featureTypes.options[i].selected){
            featureTypesList += featureTypes.options[i].value + "', '";
        }
    }
    featureTypesList = featureTypesList.substring(0,featureTypesList.length - 3);
    
    //document.getElementById('textArea').value = featureTypesList;
    //document.getElementById('textArea').value += featureName;
    
    BigHole.Map.GNISQuery(featureTypesList, featureName, GNISQuery_callback);

}

/*  Called when the user selects a location to find in the named features list from the query box
*/
function findLocation(x, y){
    setWaitCursor();
    BigHole.Map.FindLocation(x, y, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
}


/*  Called when the user clicks the Locate TRS button.
*/
function findTRS(){
    setWaitCursor();
    
    var township = document.getElementById("townshipDDL").value;
    var td = null;
    if (document.getElementById("TN").checked)
        td = "N";
    else
        td = "S";
    
    var range = document.getElementById("range").value;
    var rd = null;
    if (document.getElementById("RE").checked)
        rd = "E";
    else
        rd = "W";

    // Sec will hold each html section control    
    var sec;
    // sections will hold the list of sections to zoom to
	var sections = '';

	for (i=1; i<37; i++)
	{
		sec = document.getElementById('sec' + i);

		if (sec.colorChanged == true)
		{
			sections += sec.innerHTML + ',';
		}
	}
	// The TRS layer is going to be turned on so make sure the checkbox is checked for that layer in 
	// the legend.
	document.getElementById("plss").checked = true;
	document.getElementById("plsslabels").checked = true;
	document.getElementById("township").checked = true;
	document.getElementById("townshiplabels").checked = true;
	
	BigHole.Map.FindTRS(township, td, range, rd, sections, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
}


function findLatLong(){
    setWaitCursor();

    // Check the topo layer checkbox as we will turn on this layer
    document.getElementById("topo").checked = true;
    
    // Get the lat and lon
    var lat = document.getElementById("latDegrees").value + "." + document.getElementById("latDecimal").value;
    var lon = document.getElementById("lonDegrees").value + "." + document.getElementById("lonDecimal").value;
    
    // Convert to state plane
    var spCoords = convertLL2SP(lat, lon);
    
    BigHole.Map.FindLocation(spCoords.x, spCoords.y, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
}


function findWRByNumber(){
    setWaitCursor();
    
    if(document.getElementById('waterRightNumber').value != "")
    {
        document.getElementById("placeofuse").checked = true;
        BigHole.Map.FindWaterRightByNumber(document.getElementById('waterRightNumber').value, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
    }
    else
        setNormalCursor();
}

function findWROwner(){
    setWaitCursor();
    if(document.getElementById('waterRightOwner').value != "")
    {
        BigHole.Map.FindWaterRightOwner(document.getElementById('waterRightOwner').value, findWROwner_callback);
    }
    else
        setNormalCursor();
}

function findOwnerByWRNumber(wrNumber){
    setWaitCursor();
    
    document.getElementById("placeofuse").checked = true;
    BigHole.Map.FindWaterRightByNumber(wrNumber, drawingSpaceWidth, drawingSpaceHeight, changeMapImage_callback);
}


function findSHPO(){
    var SHPOSiteID = document.getElementById('ddlSHPOSiteID').value;
    
    if (SHPOSiteID != "")
    {
	    setWaitCursor();
	    BigHole.Map.FindSHPO(SHPOSiteID, changeMapImage_callback);
    }
}



//=================================================
//	END: QUERY FUNCTIONS
//=================================================


//=================================================
//   BEGIN: GPS FUNCTIONS
//=================================================
/*	This function is called when the user has selected the GPS tool and has clicked on a 
	point on the map.
*/
function gpsMouseUp(eventObj)
{
	setWaitCursor();
	
	// Check to see that the left mouse button is down
	if ( eventObj.button == 1 || eventObj.which == 1)
	{
		// Get the current mouse coords. objCoords will be populated with an xyObj constructor
		//var objCoords = getMouseCoords(eventObj);
		getMouseXY(eventObj);

		identifyX = parseInt(mouseX) - parseInt(drawingSpaceLeft);
		identifyY = drawingSpaceHeight - (parseInt(mouseY) - parseInt(drawingSpaceTop));
		
		// calculate the real world coordinates of the origin point in state plane
		var mapCX = (identifyX/drawingSpaceWidth*envWidth) + envMinX;
		var mapCY = (identifyY/drawingSpaceHeight*envHeight) + envMinY;
		
		convertSP2LL(mapCX,mapCY);
		
		gpsLatList += lat + "|";
		gpsLonList += lon + "|";
		
		// contains the code to call gps.aspx which asks the user to save a loc file to their computer.
		//convertSP2LLGPS(mapCX,mapCY);
		
		// Each time the use clicks on the map, mark the point where they just clicked with a dot.
		markPoint();
		
		setNormalCursor();
	}
}


function markPoint()
{
    var jgPt = new jsGraphics("glassSheetLayer");
    jgPt.setColor("#ff0000");
    jgPt.fillEllipse((mouseX - drawingSpaceLeft) - 5, (mouseY - drawingSpaceTop) - 5, 7, 7);
    jgPt.paint();
}


/*  User clicked on the Upload GPS Points link. Get the points lists and a name if they entered one.
*/
function uploadGPSPoints()
{
    gpsLonList = gpsLonList.substring(0, gpsLonList.lastIndexOf("|"));
    gpsLatList = gpsLatList.substring(0, gpsLatList.lastIndexOf("|"));
    location.replace('./gpx.ashx?px=' + gpsLonList + '&py=' + gpsLatList + '&name=');

    gpsLonList = "";
    gpsLatList = "";
    
	setNormalCursor();
}
//=================================================
//   END: GPS FUNCTIONS
//=================================================

//=================================================
//	BEGIN: MAP FUNCTIONS
//=================================================
function xyCoords(x,y) // Object constructor for XY coordinates
{ 
	this.x = x 
	this.y = y 
} 
function convertLL2SP(lat, lon)
{	
	// 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 sMath.standard parallel
	var p2 = 0.85521133348;        //latitude of second sMath.standard parallel
	var m0 = -1.91113553094;       //central meridian
	var X0 = 600000;               //False easting of central meridian, map units
	
	//calculated constants
	var m1 = Math.cos(p1) / Math.sqrt( 1 - ( Math.pow(e,2) * Math.pow(Math.sin(p1),2) ) ); //ok
	var m2 = Math.cos(p2) / Math.sqrt( 1 - ( Math.pow(e,2) * Math.pow(Math.sin(p2),2) ) ); //ok
	var t0 = (Math.tan(pi4 - (p0 / 2)))    /    Math.pow( ( 1 - (e * Math.sin(p0)) ) / ( 1 + (e * Math.sin(p0)) ), (e / 2) )   ;
	var t1 = (Math.tan(pi4 - (p1 / 2)))    /    Math.pow( ( 1 - (e * Math.sin(p1)) ) / ( 1 + (e * Math.sin(p1)) ), (e / 2) )   ;
	var t2 = (Math.tan(pi4 - (p2 / 2)))    /    Math.pow( ( 1 - (e * Math.sin(p2)) ) / ( 1 + (e * Math.sin(p2)) ), (e / 2) )   ; 
	var n = Math.log(m1 / m2) / Math.log(t1 / t2);
	var f = m1 / (n * Math.pow(t1,n));
	var rho0 = a * f * Math.pow(t0,n);
	
	// check if longitude is negative
	if (lon > 0)
	{
		lon = -lon;
	}
    
    //Convert the latitude/longitude to a coordinate.
    lat = lat * angRad;
    lon = lon * angRad;
    t = Math.tan(pi4 - (lat / 2));
    
    t = t / Math.pow(( 1 - ( e * Math.sin(lat) ) )  /   (1 + (e * Math.sin(lat))), (e / 2) );

    rho = a * f * Math.pow(t,n);
     theta = n * (lon - m0);
    x = (rho * Math.sin(theta)) + X0;
    y = rho0 - (rho * Math.cos(theta));
    
    dEasting = Math.round(x,2);
    dNorthing = Math.round(y,2);

	var coordPair = new xyCoords(dEasting, dNorthing);
	return coordPair;
}


var lat;
var lon;

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;
}


/*	Functions to convert lat/lon to UTM
*/
var pi = 3.141592653589793238;

var sm_a;
var sm_b;
var sm_EccSquared;

var UTMScaleFactor = 0.9996;


var nad27 = false;

function setDatum() // Ellipsoid model constants
{
	if (nad27 == false) // use NAD83 (WGS84)
	{	
		sm_a = 6378137.0;
		sm_b = 6356752.314;
		sm_EccSquared = 6.69437999013e-03;
	}
	else   // use NAD27 - Clarke 1866
	{
		sm_a = 6378206.4;
		sm_b = 6356583.8;
		sm_EccSquared = .006768658;
	}
} 



function DegToRad (deg) // Converts degrees to radians
{
    return (deg / 180.0 * pi)
}



function ArcLengthOfMeridian (phi)
{
    var alpha, beta, gamma, delta, epsilon, n;
    var result;

    /* Precalculate n */
    n = (sm_a - sm_b) / (sm_a + sm_b);

    /* Precalculate alpha */
    alpha = ((sm_a + sm_b) / 2.0)
        * (1.0 + (Math.pow (n, 2.0) / 4.0) + (Math.pow (n, 4.0) / 64.0));

    /* Precalculate beta */
    beta = (-3.0 * n / 2.0) + (9.0 * Math.pow (n, 3.0) / 16.0)
        + (-3.0 * Math.pow (n, 5.0) / 32.0);

    /* Precalculate gamma */
    gamma = (15.0 * Math.pow (n, 2.0) / 16.0)
        + (-15.0 * Math.pow (n, 4.0) / 32.0);

    /* Precalculate delta */
    delta = (-35.0 * Math.pow (n, 3.0) / 48.0)
        + (105.0 * Math.pow (n, 5.0) / 256.0);

    /* Precalculate epsilon */
    epsilon = (315.0 * Math.pow (n, 4.0) / 512.0);

/* Now calculate the sum of the series and return */
result = alpha
    * (phi + (beta * Math.sin (2.0 * phi))
        + (gamma * Math.sin (4.0 * phi))
        + (delta * Math.sin (6.0 * phi))
        + (epsilon * Math.sin (8.0 * phi)));

return result;
}



function UTMCentralMeridian (zone)
{
    var cmeridian;

    cmeridian = DegToRad (-183.0 + (zone * 6.0));

    return cmeridian;
}




function MapLatLonToXY (phi, lambda, lambda0, utmXY)
{
    var N, nu2, ep2, t, t2, l;
    var l3coef, l4coef, l5coef, l6coef, l7coef, l8coef;
    var tmp;

    /* Precalculate ep2 */
    ep2 = (Math.pow (sm_a, 2.0) - Math.pow (sm_b, 2.0)) / Math.pow (sm_b, 2.0);

    /* Precalculate nu2 */
    nu2 = ep2 * Math.pow (Math.cos (phi), 2.0);

    /* Precalculate N */
    N = Math.pow (sm_a, 2.0) / (sm_b * Math.sqrt (1 + nu2));

    /* Precalculate t */
    t = Math.tan (phi);
    t2 = t * t;
    tmp = (t2 * t2 * t2) - Math.pow (t, 6.0);

    /* Precalculate l */
    l = lambda - lambda0;

    /* Precalculate coefficients for l**n in the equations below
        so a normal human being can read the expressions for easting
        and northing
        -- l**1 and l**2 have coefficients of 1.0 */
    l3coef = 1.0 - t2 + nu2;

    l4coef = 5.0 - t2 + 9 * nu2 + 4.0 * (nu2 * nu2);

    l5coef = 5.0 - 18.0 * t2 + (t2 * t2) + 14.0 * nu2
        - 58.0 * t2 * nu2;

    l6coef = 61.0 - 58.0 * t2 + (t2 * t2) + 270.0 * nu2
        - 330.0 * t2 * nu2;

    l7coef = 61.0 - 479.0 * t2 + 179.0 * (t2 * t2) - (t2 * t2 * t2);

    l8coef = 1385.0 - 3111.0 * t2 + 543.0 * (t2 * t2) - (t2 * t2 * t2);

    /* Calculate easting (x) */
    utmXY[0] = N * Math.cos (phi) * l
        + (N / 6.0 * Math.pow (Math.cos (phi), 3.0) * l3coef * Math.pow (l, 3.0))
        + (N / 120.0 * Math.pow (Math.cos (phi), 5.0) * l5coef * Math.pow (l, 5.0))
        + (N / 5040.0 * Math.pow (Math.cos (phi), 7.0) * l7coef * Math.pow (l, 7.0));

    /* Calculate northing (y) */
    utmXY[1] = ArcLengthOfMeridian (phi)
        + (t / 2.0 * N * Math.pow (Math.cos (phi), 2.0) * Math.pow (l, 2.0))
        + (t / 24.0 * N * Math.pow (Math.cos (phi), 4.0) * l4coef * Math.pow (l, 4.0))
        + (t / 720.0 * N * Math.pow (Math.cos (phi), 6.0) * l6coef * Math.pow (l, 6.0))
        + (t / 40320.0 * N * Math.pow (Math.cos (phi), 8.0) * l8coef * Math.pow (l, 8.0));

    return;
}



function LatLonToUTMXY (lat, lon, zone, utmXY)
{
    MapLatLonToXY (lat, lon, UTMCentralMeridian (zone), utmXY);

    /* Adjust easting and northing for UTM system. */
    utmXY[0] = utmXY[0] * UTMScaleFactor + 500000.0;
    utmXY[1] = utmXY[1] * UTMScaleFactor;
    if (utmXY[1] < 0.0)
        utmXY[1] = utmXY[1] + 10000000.0;

    return zone;
}




function LLtoUTM(lat, lon) // convert Lat/Lon to UTM northing, easting and zone
{
    
    lat = lat;
        
	lon = lon;

    // Compute the UTM zone.
    zone = Math.floor ((lon + 180.0) / 6) + 1

    zone = LatLonToUTMXY (DegToRad (lat), DegToRad (lon), zone, utmXY);

    return 'UTM:<br />&nbsp;&nbsp;N: ' + Math.round( utmXY[1] ) + '<br />&nbsp;&nbsp;E: ' + Math.round( utmXY[0] ) + '<br />&nbsp;&nbsp;Z: ' + zone;
}


var utmXY = new Array(2);


setDatum();

/*
	This function is called anytime we need to determine x/y location of the mouse on the map surface.
*/
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
{ 
  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;
      mouseY = e.pageY;
    }
    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;
    }
  }
}

/*	Called when user clicked on the Print Map button. Generates the print map query string 
	and opens a new window with the url	of the print map service.
*/
function printMap() {
	var sessionId = document.getElementById("sessionIdControl").value;
   	
	// launch the window
	var oWin = window.open('','print','left=0,top=0,width=600,height=400,scrollbars=no,resizable=no,location=no,directories=no,status=no');
	var fFailed = false;
	// Check for failed attempt to open the popup window.
	try {
		oWin.focus();
	} catch (ex) {
		fFailed = true;
	}
	if (oWin==null || typeof(oWin)=="undefined" || fFailed==true)
		alert("Popup blocking software has blocked the file download from opening.\r\n Please disable your popup blocking software for this site.");

    // write the window document and onload download.
    oWin.document.write('<html><head><title>Big Hole Watershed Print Map Download</title></head><body style="font-family:Verdana;font-size:75%;background:#b3b3a1;"><p style="background:#fff;padding:3px;"><strong>Print Map Download</strong><br/><br/>Click <a href="/pdfcreator/default.aspx?n=bighole&sid=' + sessionId + '" onclick="this.innerHTML=\'<em> please wait </em>\';return true;this.href=\'javascript:void()\';">here to download your map.</a> (PDF ~ 1Mb)<br/><br/>Print maps may take upto 30 seconds to generate, please be patient while waiting for file download box.<br/><br/>Printable maps are large and take time to download.  Please choose "Save As" to save the map to your hard disk.</p></body></html>');
	oWin.document.close();
}


/*  Called when user is interacting with the map (zoom, pan). This allows user to draw zoom rectangle
    where the accordion or tools are located.
*/
function hideMapControls(){
    //document.getElementById("helpDiv").style.display = "none";
    document.getElementById("tools").style.display = "none";
    document.getElementById("accordionDiv").style.display = "none";
    document.getElementById("panel1ContentOverlay").style.display = "none";
    document.getElementById("panel2ContentOverlay").style.display = "none";
    document.getElementById("panel3ContentOverlay").style.display = "none";
}


/*  Called when user is done interacting with the map (zoom, pan)
*/
function showMapControls(){
    /*if (document.getElementById("helpDiv").style.display == "block"){
        document.getElementById("helpDiv").style.display = "block";
    }
    else{
        document.getElementById("helpDiv").style.display = "none";
    }*/
    document.getElementById("tools").style.display = "block";
    document.getElementById("accordionDiv").style.display = "block";
    document.getElementById("panel1ContentOverlay").style.display = "block";
    document.getElementById("panel2ContentOverlay").style.display = "block";
    document.getElementById("panel3ContentOverlay").style.display = "block";
}


//=================================================
//	END: MAP FUNCTIONS
//=================================================

