//==================
// Mouse down event.
//==================
function mapMouseDown(e) {
   // Wait until ready
   if (!e) e = window.event;
   if (!e) return;
   if (!top.WebSiteInitialized || !top.PostBackDone || (e.button == 2) || PzActive) return;

   // Flag the mouse down event
   MouseDown.is = true;
   MouseUp.is = false;
   
   // Save mouse coordinates
   MouseDown.xPix = e.clientX;
   MouseDown.yPix = e.clientY;
   
   getXyMap(MouseDown.xPix, MouseDown.yPix);
   MouseDown.xMap = XMap;
   MouseDown.yMap = YMap;

   // Process tool commands
   if (ActiveTool.id == "pan" || e.button == 4) {
      if (top.IeFilters) {
         clearVML();
      }
      clearMeasureVar();

   // Place acetate circle
   } else if (ActiveTool.id == "addCircle") {
      if (ACircleCount == MaxACircle) {
         MouseDown.is = false;
         MouseUp.is = true;
         alert("Please refresh the drawing before adding more circle elements.");
      }
      if (ACircleCount < MaxACircle) {
         var circleRad = top.data_frame.document.getElementById("circleRad_textBox");

         var wStr = parseFloat(circleRad.value) + "";
         if (isNaN(wStr)) {
            circleRad.value = top.CircleRadius;
         }
         var wRad = parseFloat(circleRad.value);
         if (wRad < 1) {
            wRad = top.CircleRadius;
         }
         var radInPix = Math.round(wRad / top.ScalePixelToFeet);
         if (radInPix < 1 || radInPix > 4096) {
            radInPix = 1;
         }
         ACircleCount += 1;
         FullExtentImage = "";
         ACircleX[ACircleCount] = Math.round(XMap);
         ACircleY[ACircleCount] = Math.round(YMap);
         ACircleRad[ACircleCount] = wRad;

         top.CircleRadius = wRad;
         
         if (top.IeFilters) {
            if (ACircleCount == 1) {
               ACircle1_vml.style.width  = (radInPix * 2) + "px";
               ACircle1_vml.style.height = (radInPix * 2) + "px";
               ACircle1_vml.style.left = (MouseDown.xPix - radInPix) + "px";
               ACircle1_vml.style.top = (MouseDown.yPix - radInPix) + "px";
               ACircle1_vml.style.visibility = "visible";

            } else if (ACircleCount == 2) {
               ACircle2_vml.style.width  = (radInPix * 2) + "px";
               ACircle2_vml.style.height = (radInPix * 2) + "px";
               ACircle2_vml.style.left = (MouseDown.xPix - radInPix) + "px";
               ACircle2_vml.style.top = (MouseDown.yPix - radInPix) + "px";
               ACircle2_vml.style.visibility = "visible";

            } else if (ACircleCount == 3) {
               ACircle3_vml.style.width  = (radInPix * 2) + "px";
               ACircle3_vml.style.height = (radInPix * 2) + "px";
               ACircle3_vml.style.left = (MouseDown.xPix - radInPix) + "px";
               ACircle3_vml.style.top = (MouseDown.yPix - radInPix) + "px";
               ACircle3_vml.style.visibility = "visible";

            } else if (ACircleCount == 4) {
               ACircle4_vml.style.width  = (radInPix * 2) + "px";
               ACircle4_vml.style.height = (radInPix * 2) + "px";
               ACircle4_vml.style.left = (MouseDown.xPix - radInPix) + "px";
               ACircle4_vml.style.top = (MouseDown.yPix - radInPix) + "px";
               ACircle4_vml.style.visibility = "visible";

            } else {
               ACircle5_vml.style.width  = (radInPix * 2) + "px";
               ACircle5_vml.style.height = (radInPix * 2) + "px";
               ACircle5_vml.style.left = (MouseDown.xPix - radInPix) + "px";
               ACircle5_vml.style.top = (MouseDown.yPix - radInPix) + "px";
               ACircle5_vml.style.visibility = "visible";
            }
         }
         enableRow("editDelete");
      }
   // Place acetate text
   } else if (ActiveTool.id == "addText") {
      if (ATextAndXYCount == MaxAText) {
         MouseDown.is = false;
         MouseUp.is = true;
         alert("Please refresh the drawing before adding more text elements.");
      }
      if (ATextAndXYCount < MaxAText) {
         ATextCount += 1;
         ATextAndXYCount += 1;
         FullExtentImage = "";

         ATextX[ATextCount] = XMap;
         ATextY[ATextCount] = YMap;
         ATextXPrev = MouseDown.xPix
         ATextYPrev = MouseDown.yPix
         if (!top.IsNN) {
            AText.select();
         }         
         if (ATextAndXYCount < MaxAText) {
            addText();
         }
         enableRow("editDelete");
      }
   // Place acetate XY
   } else if (ActiveTool.id == "addXY") {
      if (ATextAndXYCount == MaxAText) {
         MouseDown.is = false;
         MouseUp.is = true;
         alert("Please refresh the drawing before adding more XY elements.");
      }
      if (ATextAndXYCount < MaxAText) {
         AXYCount += 1;
         ATextAndXYCount += 1;
         FullExtentImage = "";

         AXYX[AXYCount] = XMap;
         AXYY[AXYCount] = YMap;
         AXYXPrev = MouseDown.xPix
         AXYYPrev = MouseDown.yPix
         if (ATextAndXYCount < MaxAText) {
            addXY();
         }
         APointCount += 1;
         APointX[APointCount] = Math.round(XMap);
         APointY[APointCount] = Math.round(YMap);

         // Form VML path
         if (top.IeFilters) {
            APoint_vml.path += "m " + (MouseDown.xPix - 3) + "," + MouseDown.yPix + " l " + 
            (MouseDown.xPix + 3) + "," + MouseDown.yPix + " e ";
         }
         enableRow("editDelete");
      }
   // Place acetate points
   } else if (ActiveTool.id == "addPoint") {
      if (APointCount == MaxXY) {
         MouseDown.is = false;
         MouseUp.is = true;
         alert("Please refresh the drawing before adding more point elements.");
      }
      if (APointCount < MaxXY) {
         APointCount += 1;
         FullExtentImage = "";
         APointX[APointCount] = Math.round(XMap);
         APointY[APointCount] = Math.round(YMap);

         // Form VML path
         if (top.IeFilters) {
            APoint_vml.path += "m " + (MouseDown.xPix - 3) + "," + MouseDown.yPix + " l " + 
            (MouseDown.xPix + 3) + "," + MouseDown.yPix + " e ";
         }
         enableRow("editDelete");
      }

   // Place acetate linework
   } else if ( (ActiveTool.id == "addPoly") || (ActiveTool.id == "addLine") || (ActiveTool.id == "selectByPoly") ) {
      XyCount += 1;
      Xarray[XyCount] = Math.round(XMap);
      Yarray[XyCount] = Math.round(YMap);

      // Form VML paths
      if (top.IeFilters) {
         if (XyCount == 1) {
            XfirstPix = MouseDown.xPix;
            YfirstPix = MouseDown.yPix;

            XyFirstPntVML = "m " + MouseDown.xPix + "," + MouseDown.yPix + " l ";
            XyVML = XyFirstPntVML;
         } else {
            XyVML += MouseDown.xPix + "," + MouseDown.yPix + " ";
         }
      }
      if (ActiveTool.id != "selectByPoly") {
         enableRow("editDelete");
      }
      
   // Measure dist/area
   } else if (ActiveTool.id == "measure") {
      XyCount += 1;
      Xarray[XyCount] = MouseDown.xMap;
      Yarray[XyCount] = MouseDown.yMap;

      // Form VML paths
      if (top.IeFilters) {
         if (XyCount == 1) {
            XyFirstPntVML = "m " + MouseDown.xPix + "," + MouseDown.yPix + " l ";
            XyVML = XyFirstPntVML;
         } else {
            XyVML += MouseDown.xPix + "," + MouseDown.yPix + " ";
         }
      }

      // Update measure form
         var wForm = top.data_frame.document.getElementById("findResults_form");

      if (top.data_frame.document.getElementById("measure_form")) {
         if (XyCount == 1) {
            top.data_frame.clearMeasureForm();
         } else {
            top.data_frame.updateMeasureForm();
         }
      } else {
         top.data_frame.location.href = "measure.aspx";
      }
   }
}
//================
// Mouse up event.
//================
function mapMouseUp(e) {
   // Wait until ready
   if (!e) e = window.event;
   if (!e) return;

   if (!top.WebSiteInitialized || (e.button == 2) || PzActive) return;
   var areaPix;

   // Flag the mouse up event
   MouseUp.is = true;
   MouseDown.is = false;

   // Save mouse coordinates
   MouseUp.xPix = e.clientX;
   MouseUp.yPix = e.clientY;
   
   getXyMap(MouseUp.xPix, MouseUp.yPix);
   MouseUp.xMap = XMap;
   MouseUp.yMap = YMap;

   // Clear the zoom box
   if (top.IeFilters) {
      ZoomBox_vml.path = "m 0 0 l 0,0 0,0 0,0 0,0 e";
   }

   // Wait until ready
   if (!top.PostBackDone) {
      return;
   }
   // Process Pan
   if (ActiveTool.id == "pan" || e.button == 4) {
      areaPix = getAreaPix();

      if (areaPix > 2) {
         top.pan(MouseDown.xMap, MouseDown.yMap, MouseUp.xMap, MouseUp.yMap);
      } else {
         top.panFixed(MouseUp.xMap, MouseUp.yMap);
         dynZoom("panFixed");
      }

   // Process Identify
   } else if (ActiveTool.id == "identify") {
      if (top.IeFilters) {
         clearVML();
      }
      top.vmlObjectId = "0";
      top.identify(MouseUp.xMap, MouseUp.yMap);
       
   // Process Zoom In
   } else if (ActiveTool.id == "zoomIn") {
      areaPix = getAreaPix();
      if (areaPix > 10) {
         top.zoomInBox(MouseDown.xMap, MouseDown.yMap, MouseUp.xMap, MouseUp.yMap);
         dynZoom("zoomInBox");
      } else {
         top.zoomInFixed(MouseUp.xMap, MouseUp.yMap);
         dynZoom("zoomInFixed");
      }

   // Process Zoom Out
   } else if (ActiveTool.id == "zoomOut") {
      areaPix = getAreaPix();

      if (areaPix > 10) {
         top.zoomOutBox(MouseDown.xMap, MouseDown.yMap, MouseUp.xMap, MouseUp.yMap);
         dynZoom("zoomOutBox");
      } else {
         top.zoomOutFixed(MouseUp.xMap, MouseUp.yMap);
         dynZoom("zoomOutFixed");
      }

   // Process Select Feature
   } else if (ActiveTool.id == "selectFeature") {

      if (!top.data_frame.document.getElementById("selectByGraphics_form")) {
         top.selectByGraphics();
      }

      areaPix = getAreaPix();
      if (areaPix > 10) {
         SQuery = top.ActiveLayerId + "^box" + "^" + Math.round(MouseDown.xMap) + "," + Math.round(MouseDown.yMap) + "," + 
          Math.round(MouseUp.xMap) + "," + Math.round(MouseUp.yMap);

      } else {
         var xMin = MouseUp.xPix - top.SearchTolerance;
         var yMin = MouseUp.yPix - top.SearchTolerance;
         getXyMap(xMin, yMin);
         xMin = XMap;
         yMin = YMap;
  
         var xMax = MouseUp.xPix + top.SearchTolerance;
         var yMax = MouseUp.yPix + top.SearchTolerance;
         getXyMap(xMax, yMax);
         xMax = XMap;
         yMax = YMap;
         
         SQuery = top.ActiveLayerId + "^box" + "^" + Math.round(xMin) + "," + Math.round(yMin) + "," + 
          Math.round(xMax) + "," + Math.round(yMax);
      }
      top.refreshMap();
   }
}
//==================
// Mouse move event.
//==================
function mapMouseMove(e) {
   // Wait until initialized
   if (!e) e = window.event;
   if (!e) return;
   if (!top.WebSiteInitialized || PzActive) return;

   var xPix, yPix;
   var statusBar;
   var dist;

   // Wait until ready
   if (top.PostBackDone) {
      xPix = e.clientX;
      yPix = e.clientY;

      getXyMap(xPix, yPix);
      Panning = false;

      // Move the drag cursor
      if (ActiveDragCursor != null) {
         ActiveDragCursor.style.visibility = "visible";
         ActiveDragCursor.style.left = (xPix + CursorOffsetX) + "px";
         ActiveDragCursor.style.top  = (yPix + CursorOffsetY) + "px";
      }
      // Process mouse down while moving cursor
      if (MouseDown.is) {

         // Pan the map
         if (ActiveTool.id == "pan" || e.button == 4) {
            if (!Panning) {
               Panning = true;
               if (e.button == 4) { //Finish mouse wheel pan
                  if ( (xPix < 13) || (xPix > MapImageWidth - 16) || (yPix < MainMenuHeight + 20) || (yPix > MapImageHeight + MainMenuHeight - 13) ) {
                     resetMap();
                  }
               }
               top.AnimateMap = true;
               Dyn_img.src = Map_img.src;
               Dyn_img.style.width = MapImageWidth + "px";
               Dyn_img.style.height = MapImageHeight + "px";
               Dyn_img.style.visibility = "visible";
               Map_img.style.visibility = "hidden";
            }
            Dyn_img.style.left = (xPix - MouseDown.xPix) + "px";
            Dyn_img.style.top  = (yPix - MouseDown.yPix + MainMenuHeight + 1) + "px";
            //Poly_vml.coordOrigin = (MouseDown.xPix - xPix) + "," + (MouseDown.yPix - yPix);
      
         //Display the zoom box
         } else if (ActiveTool.id == "zoomIn" || ActiveTool.id == "zoomOut" || ActiveTool.id == "selectFeature") {
            var wPath = "m " + MouseDown.xPix + "," + MouseDown.yPix + " l ";
            wPath += xPix + "," + MouseDown.yPix + " ";
            wPath += xPix + "," + yPix + " ";
            wPath += MouseDown.xPix + "," + yPix + " ";
            wPath += MouseDown.xPix + "," + MouseDown.yPix + " e";

            if (top.IeFilters) {
               ZoomBox_vml.path = wPath;
            }
         }

      // Process mouse up while moving cursor
      } else {
         // Drag acetate text
         if (ActiveTool.id == "addText") {
            if (ATextAndXYCount == MaxAText) {
               return;
            }
            dist = twoPntDistance (xPix, yPix, ATextXPrev, ATextYPrev);
            if (dist > 6) {
               AText.style.visibility = "visible";
               AText.style.left = (xPix + CursorOffsetX) + "px";
               AText.style.top  = (yPix + CursorOffsetY) + "px";
            } else {
               if (ATextAndXYCount < MaxAText) {
                  AText.style.visibility = "hidden";
               }
            }

         // Drag acetate XY
         } else if (ActiveTool.id == "addXY") {
            if (ATextAndXYCount == MaxAText) {
               return;
            }
            dist = twoPntDistance (xPix, yPix, AXYXPrev, AXYYPrev);
            if (dist > 6) {
               AXY.style.visibility = "visible";
               AXY.style.left = (xPix + CursorOffsetX) + "px";
               AXY.style.top  = (yPix + CursorOffsetY) + "px";
               
            if (top.CoordFeet) {
               var u = Math.pow(10, top.NumXYDecimals);
	            var uX = parseInt(XMap * u + (5/10)) / u;
	            var uY = parseInt(YMap * u + (5/10)) / u;
	            AXY.value = uX + ",  " + uY;
               } else {
               AXY.value = LatDMS + " N,  " + LonDMS + " W";
               }
               
               AXY.innerHTML = AXY.value;
               
            } else {
               if (ATextAndXYCount < MaxAText) {
                  AXY.style.visibility = "hidden";
               }
            }

         } else if ( (ActiveTool.id == "measure") ||
                     (ActiveTool.id == "addLine") ||
                     (ActiveTool.id == "addPoly") ||
                     (ActiveTool.id == "selectByPoly") ) {
            // Draw rubber bands
            if (XyCount > 0) {

               if (top.data_frame.document.getElementById("measure_form") ||
                   top.data_frame.document.getElementById("insert_form")) {
                  top.data_frame.updateSegDist(XMap,YMap);
               }
               if (top.IeFilters) {
                  XyVML_vml.path = XyVML + xPix + "," + yPix + " e";
                  if ( (XyCount > 2) && (ActiveTool.id != "addLine") ) {
                     XyClose_vml.path = XyFirstPntVML + xPix + "," + yPix + " e";
                  }
               }
            }
         }
      }
      // Show map coordinates in status bar
      if (!Panning) {
	      if (top.CoordFeet) {
            var u = Math.pow(10, top.NumXYDecimals);
	         var uX = parseInt(XMap * u + (5/10)) / u;
	         var uY = parseInt(YMap * u + (5/10)) / u;
	         statusBar = "State Plane X, Y: " + uX + ",  " + uY + " " + top.MapUnits;	
	      } else {
            statusBar = getLatLon(XMap, YMap);
	      }
         window.status = statusBar;
      }

   // Update the busy cursor
   } else {
      Map_img.style.cursor = "wait";
      if (ActiveDragCursor != null) {
         ActiveDragCursor.style.visibility = "hidden";
      }
   }
}
//==================
// Mouse out event.
//==================
function mapMouseOut(e) {
   if (!top.WebSiteInitialized) return;

   ZoomInCursor_img.style.visibility = "hidden";
   ZoomOutCursor_img.style.visibility = "hidden";
   IdentifyCursor_img.style.visibility = "hidden";
   MeasureCursor_img.style.visibility = "hidden";

   if (ActiveTool.id == "addText") {
      if (ATextAndXYCount < MaxAText) {
         AText.style.visibility = "hidden";
      }
   }
   if (ActiveTool.id == "addXY") {
      if (ATextAndXYCount < MaxAText) {
         AXY.style.visibility = "hidden";
      }
   }
}
//==========================
// Mouse double click event.
//==========================
function mapMouseDblClick(e) {
   var i;
   var wStr;

   // Save line
   if (ActiveTool.id == "addLine") {
      if (XyCount > 1) {
         if ((ALineXYCount + XyCount) > MaxXY) {
            if (ALineCount == 0) {
               alert("You may enter a maximum of " + MaxXY + " points.");
               clearMeasureVar();
            } else {
               alert("Please refresh the drawing before adding more line elements.");
            }
            return;
         }
         ALineXYCount += XyCount;
         ALineCount += 1;
         FullExtentImage = "";

         if (ALineCount == 1) {
            if (top.IeFilters) {
               ALine_vml.path = "";
            }
            ALineList = "";
         }
         
         // Set vml
         if (top.IeFilters) {
            wStr = XyVML_vml.path + "";
            ALine_vml.path = wStr + ALine_vml.path;
         }

         // Build list for server
         if (ALineCount > 1) {
            ALineList += "|";
         }
         for (i=1; i<=XyCount; i++) {
            if (i > 1) {
               ALineList += "^";
            }
            ALineList += Xarray[i] + "," + Yarray[i];
         }
      }

   // Save polygon
   } else if (ActiveTool.id == "addPoly") {

      if (XyCount > 2) {
         if ((APolyXYCount + XyCount) > MaxXY) {
            if (APolyCount == 0) {
               alert("You may enter a maximum of " + MaxXY + " points.");
               clearMeasureVar();
            } else {
               alert("Please refresh the drawing before adding more polygon elements.");
            }
            return;
         }
         APolyXYCount += XyCount;
         APolyCount += 1;
         FullExtentImage = "";

         if (APolyCount == 1) {
            if (top.IeFilters) {
               APoly_vml.path = "";
            }
            APolyList = "";
         }
         
         // Set vml
         if (top.IeFilters) {
            wStr = XyVML_vml.path + "";
            wStr = wStr.replace("e", "");
            wStr += XfirstPix + "," + YfirstPix + " e ";
            APoly_vml.path = wStr + APoly_vml.path;
         }

         // Build list for server
         if (APolyCount > 1) {
            APolyList += "|";
         }
         for (i=1; i<=XyCount; i++) {
            if (i > 1) {
               APolyList += "^";
            }
            APolyList += Xarray[i] + "," + Yarray[i];
         }
         APolyList += "^" + Xarray[1] + "," + Yarray[1];
      }
   // Save select polygon
   } else if (ActiveTool.id == "selectByPoly") {

      if (XyCount > 2) {
         if (XyCount > MaxXY) {
            alert("You may enter a maximum of " + MaxXY + " points.");
            clearMeasureVar();
            return;
         }
         // Build list for server
         SQuery = top.ActiveLayerId + "^poly";
         for (i=1; i<=XyCount; i++) {
            SQuery += "^";
            SQuery += Xarray[i] + "," + Yarray[i];
         }
         SQuery += "^" + Xarray[1] + "," + Yarray[1];
         top.refreshMap();
      }
   }

   // Reset drawing
   if ( (ActiveTool.id == "measure") ||
        (ActiveTool.id == "addLine") ||
        (ActiveTool.id == "addPoly") ||
        (ActiveTool.id == "selectByPoly") ) {
      clearMeasureVar();
   }
}
//==============================
// Dynamic zoom by scale factor.
//==============================
function dynZoomSF(sf,numStep) {
   if (sf > 1) {
      if (DynWidth > (MapImageWidth * 30)) return; //Zoom limit
   }
   if (top.IeFilters) {
      clearVML();
   }
   var endWidth = DynWidth * sf;
   var endHeight = DynHeight * sf;

   var endLeft = -(endWidth - DynWidth) / 2;
   var endTop = -((endHeight - DynHeight) / 2) + MainMenuHeight + 1;
   
   DynNumStep = numStep;
   
   DynWidthInc = (endWidth - DynWidth) / DynNumStep;
   DynHeightInc = (endHeight - DynHeight) / DynNumStep;
   DynLeftInc = endLeft / DynNumStep;
   DynTopInc = (endTop - (MainMenuHeight + 1)) / DynNumStep;

//alert(
//  "  MapImageWidth=" + MapImageWidth + 
//  "  endWidth=" + parseInt(endWidth) + 
//  "  endLeft=" + parseInt(endLeft) + 
//  "  DynLeft=" + parseInt(DynLeft) + 
//  "  DynLeftPrev=" + parseInt(DynLeftPrev) + 
//  "  DynWidth=" + parseInt(DynWidth) + 
//  "  Scale Factor=" + sf +
//  "  DynNumStep=" + parseInt(DynNumStep) + 
//  "  DynWidthInc=" + parseInt(DynWidthInc) + 
//  "  DynLeftInc=" + parseInt(DynLeftInc)
//);

   DynStep = 0;
   showDynImg();
   rasterZoom();
}
//=============
// Raster zoom.
//=============
function rasterZoom() {
   DynStep += 1;

   if (DynStep <= DynNumStep) {
      DynWidth += DynWidthInc;
      DynHeight += DynHeightInc;
      DynLeft += DynLeftInc;
      DynTop += DynTopInc;

      Dyn_img.style.width = Math.round(DynWidth) + "px";
      Dyn_img.style.height = Math.round(DynHeight) + "px";
      Dyn_img.style.left = Math.round(DynLeft) + "px";
      Dyn_img.style.top = Math.round(DynTop) + "px";

      window.setTimeout("rasterZoom()", 70);
   }
}
//=============================
// Compute dynMap pixel extent.
//=============================
function getDynExtent() {
   DynSF = MapImageWidth / DynWidth;

   XPixLeft = -DynLeft * DynSF;
   XPixRight = XPixLeft + (MapImageWidth * DynSF);

   var temp = (-DynTop + MainMenuHeight + 1) * DynSF;
   YPixTop = temp + MainMenuHeight + 0;
   YPixBot = YPixTop + (MapImageHeight * DynSF);
}
//=============
// Dynamic pan.
//=============
function dynPan(dist,angRad) {
   getDynExtent();
   var dx = -Math.round(Math.cos(angRad) * dist);
   var dy = -Math.round(Math.sin(angRad) * dist);

   //Pan limits
   if (dx < 0) {
      if (XPixLeft + dx > MapImageWidth - PzMargin) {
         dx = 0;
      }
   } else if (dx > 0) {
      if (XPixRight + dx < PzMargin) {
         dx = 0;
      }
   }
   if (dy < 0) {
      if (YPixTop + dy > (MapImageHeight + MainMenuHeight) - PzMargin) {
         dy = 0;
      }
   } else if (dy > 0) {
      if (YPixBot + dy < MainMenuHeight + PzMargin) {
         dy = 0;
      }
   }
   if (top.IeFilters) {
      clearVML();
   }
   DynNumStep = 1;
   
   DynWidthInc = 0;
   DynHeightInc = 0;
   DynLeftInc = dx;
   DynTopInc = dy;

   DynStep = 0;
   showDynImg();
   rasterZoom();
}
//==================
// Dynamic pan/zoom.
//==================
function panZoom() {
   PzTime = top.now(); // Set dyn pan in use time
   var dist;

   if (!PzActive) {
      PzActive = true;
      DynWidth = MapImageWidth;
      DynHeight = MapImageHeight;
      DynLeft = 0;
      DynTop = MainMenuHeight + 1;
   }
   //Find center of panzoom tool
   var hS = PanZoomImg.width / 2; 
   var xCen = parseInt(PanZoomImg.style.left) + hS;
   var yCen = parseInt(PanZoomImg.style.top) + hS;

   //Pan
   if (PzPan) {
      //Compute pan angle
      var dx = PzX - xCen;
      var dy = PzY - yCen;
      var angRad=Math.atan2(dy,dx);
      dist = Math.sqrt(dx*dx + dy*dy);
      dist = Math.min(dist,100);
      dynPan(dist,angRad);

   //Zoom In/Out
   } else {
      //Compute scale factor
      dist = Math.abs(PzY - yCen);
      var weight = dist / (hS / 2);
      var sf = 1 + (.05 * weight);
      sf = Math.min(sf,1.2);

      if (PzIn) {
         dynZoomSF(sf,1);
      } else {
         dynZoomSF(1/sf,1);
      }
   }
   window.setTimeout("checkPzDone()", PzRefreshTime);
}
//===================
// Set pan-zoom mode.
//===================
function setPzMode() {
   if (PzPan) return;
   var x = PzX;
   var y = PzY;
   var lp = parseInt(PanZoomImg.style.left);
   var tp = parseInt(PanZoomImg.style.top);
   var x1 = lp + 22;
   var x2 = lp + 42;
   var y1 = tp + 12;
   var y2 = tp + 55;
   var y3 = (y1 + y2) / 2;

   if ((x > x1 && x < x2 && y > y1 && y < y2) || PzIn || PzOut)  {
      if (y > y3) {
         PzIn = true;
         PzOut = false;
      } else {
         PzOut = true;
         PzIn = false;
      }
   } else {
      if (!PzIn && !PzOut) {
         PzPan = true;
      }
   }
}
//=======================
// Done with mouse wheel.
//=======================
function checkPzDone() {
   var x1,y1,x2,y2;

   if (PzActive) {
      var ct = top.now();
      if ((ct - PzTime) > (PzRefreshTime - 100)) { 
         PzActive = false;
         getDynExtent();

         getXyMap(XPixLeft, YPixBot);
         x1 = XMap;
         y1 = YMap;

         getXyMap(XPixRight, YPixTop);
         x2 = XMap;
         y2 = YMap;

         top.zoomInBox(x1, y1, x2, y2);
      }
   }
}
//==========================
// Fire off pan/zoom events.
//==========================
function doPzEvents() {
   if (MouseDown.is) {
      panZoom();
      window.setTimeout("doPzEvents()", 70);
   }
}
//=====================
// Pan-Zoom down event.
//=====================
function pzDown(e) {
   if (!e) e = window.event;
   if (!e) return;
   if (!top.WebSiteInitialized || !top.PostBackDone || ((e.button != 0) && (e.button != 1)) ) return;
   if ((e.button == 1) && top.IsNN) return;
   
   MouseDown.is = true;
   MouseUp.is = false;

   PzX = e.clientX;
   PzY = e.clientY;
   setPzMode();

   doPzEvents();
}
//===================
// Pan-Zoom up event.
//===================
function pzUp(e) {
   if (!e) e = window.event;
   if (!e) return;
   if (!top.WebSiteInitialized || !top.PostBackDone) return;

   MouseUp.is = true;
   MouseDown.is = false;
   clearPz();
   clearMeasureVar();

   //Finish pan
   if ( (e.button == 4) || ((e.button == 1) && top.IsNN) ) {
      if (Panning) {
         resetMap();
      }
   }
}
//=====================
// Pan-Zoom move event.
//=====================
function pzMove(e) {
   if (!e) e = window.event;
   if (!e) return;
   if (!top.WebSiteInitialized) return;
   top.setBusy(PanZoomImg,true);
   if (!top.PostBackDone) return;

   if (MouseDown.is) {
      PzX = e.clientX;
      PzY = e.clientY;
      setPzMode();
   }
}
//================
// Clear pan-zoom.
//================
function clearPz() {
   PzPan = false;
   PzIn = false;
   PzOut = false;
}
//===========
// Reset map.
//===========
function resetMap() {
   if (ActiveDragCursor != null) {
      ActiveDragCursor.style.visibility = "hidden";
   }
   top.pan(MouseDown.xMap, MouseDown.yMap, XMap, YMap);

   MouseUp.is = true;
   MouseDown.is = false;
}
//====================
// PanZoom over event.
//====================
function pzOver() {
   window.status = "Pan/Zoom";
}
//===================
// PanZoom out event.
//===================
function pzOut() {
   if (top.IsNN) {
      MouseUp.is = true;
      MouseDown.is = false;
      clearPz();
   }
   window.status = "";
}
//===================
// Mouse wheel event.
//===================
function mapMouseWheel(e) {
   // Wait until ready
   if (!e) e = window.event;
   if (!e) return false;
   if (!top.WebSiteInitialized || !top.PostBackDone) return false;
   if ((e.button != 0 && e.button != 65535) || MouseDown.is) return false;

   // Set wheel in use time
   PzTime = top.now();
   
   //Get wheel direction   
   var wd = 0;
   if (e.wheelDelta) {
      wd = -e.wheelDelta;
   } else if (e.detail) {
      wd = e.detail;
   }
   if (!PzActive) {
      PzActive = true;
      DynWidth = MapImageWidth;
      DynHeight = MapImageHeight;
      DynLeft = 0;
      DynTop = MainMenuHeight + 1;
   }
   //Zoom In/Out
   var sf = 1.1;

   if (wd > 0) {
      dynZoomSF(sf,3);
   } else if (wd < 0) {
      dynZoomSF(1/sf,3);
   }
   window.setTimeout("checkPzDone()", PzRefreshTime);
   e.cancelBubble = true;
   return false;
}
//==============
// Dynamic zoom.
//==============
function dynZoom(command) {
   var zoomOutFactor;
   var x,y;
   var x1,y1,x2,y2;
   var dx,dy;
   var fX,fY;
   var temp;

   x1 = MouseDown.xPix;
   y1 = MouseDown.yPix - MainMenuHeight;
   x2 = MouseUp.xPix;
   y2 = MouseUp.yPix - MainMenuHeight;

   dx = MapImageWidth * top.PanFactor;
   dy = MapImageHeight * top.PanFactor;
   
   //Flip extent.
   if (x1 > x2) {
      temp = x1;
      x1 = x2;
      x2 = temp;
   }
   if (y1 > y2) {
      temp = y1;
      y1 = y2;
      y2 = temp;
   }
   if (command == "zoomInBox") {
      dx = x2 - x1;
      dy = y2 - y1;
      x = (x1 + x2) / 2; 
      y = (y1 + y2) / 2; 
      fX = MapImageWidth / (top.ZoomFactor * 2.5);  //Zoom limit
      fY = MapImageHeight / (top.ZoomFactor * 2.5);

      temp = MapImageWidth / dx;
      if (temp > top.ZoomFactor) {
         x1 = x - fX;
         x2 = x + fX;
      }
      temp = MapImageHeight / dy;
      if (temp > top.ZoomFactor) {
         y1 = y - fY;
         y2 = y + fY;
      }
      dynZoomExtent(x1, y1, x2, y2);

   } else if (command == "zoomOutBox") {
      if (x1 == x2) {
         x2 += 1;
      }
      zoomOutFactor = MapImageWidth / (x2 - x1);
      dx = (MapImageWidth * zoomOutFactor) / 2;
      dy = (MapImageHeight * zoomOutFactor) / 2;
      x = (x1 + x2) / 2;
      y = (y1 + y2) / 2;
      dynZoomExtent(x - dx, y - dy, x + dx, y + dy);

   } else if (command == "zoomInFixed") {
      dx = (MapImageWidth / top.ZoomFactor) / 2;
      dy = (MapImageHeight / top.ZoomFactor) / 2;
      dynZoomExtent(x2 - dx, y2 - dy, x2 + dx, y2 + dy);

   } else if (command == "zoomOutFixed") {
      dx = (MapImageWidth * top.ZoomFactor) / 2;
      dy = (MapImageHeight * top.ZoomFactor) / 2;
      dynZoomExtent(x2 - dx, y2 - dy, x2 + dx, y2 + dy);

   } else if (command == "panFixed") {
      dx = MapImageWidth / 2;
      dy = MapImageHeight / 2;
      dynZoomExtent(x2 - dx, y2 - dy, x2 + dx, y2 + dy);
   }
}
//===========================
// Dynamic zoom pixel extent.
//===========================
function dynZoomExtent(x1,y1,x2,y2) {
   var temp;
   var dx,dy;
   var ratioMap,ratioPix;
   var sf;
   //alert(x1 + ", " + y1 + ", " + x2 + ", " + y2);
   
   //Dont zoom in too far.
   if (((y2 - y1) < 2) || ((x2 - x1) < 2)) {
      return;
   }
   //Correct pixel aspect ratio.
   dx = x2 - x1;
   dy = y2 - y1;

   ratioMap = dx / dy;
   ratioPix = MapImageWidth / MapImageHeight;

   if (ratioMap > ratioPix) {
      temp = (dx / ratioPix) - dy;
      y1 = y1 - (temp / 2);
      y2 = y2 + (temp / 2);
      sf = MapImageWidth / dx;
   } else {
      temp = (dy * ratioPix) - dx;
      x1 = x1 - (temp / 2);
      x2 = x2 + (temp / 2);
      sf = MapImageHeight / dy;
   }
   var endWidth = MapImageWidth * sf;
   var endHeight = MapImageHeight * sf;
   var endLeft = -x1 * sf;
   var endTop = -(y1 * sf) + MainMenuHeight + 1;

   dynZoomImg(endWidth, endHeight, endLeft, endTop);
}
//===========================
// Dynamic zoom image extent.
//===========================
function dynZoomImg(endWidth,endHeight,endLeft,endTop) {
   var stepSize = 200;
   if (top.IeFilters) {
      clearVML();
   }
   DynNumStep = Math.round(Math.abs(endWidth - MapImageWidth) / stepSize);
   if (DynNumStep < 5) {
      DynNumStep = 5;
   }
   if (DynNumStep > 15) {
      DynNumStep = 15;
   }
   DynWidthInc = (endWidth - MapImageWidth) / DynNumStep;
   DynHeightInc = (endHeight - MapImageHeight) / DynNumStep;
   DynLeftInc = endLeft / DynNumStep;
   DynTopInc = (endTop - (MainMenuHeight + 1)) / DynNumStep;

   DynWidth = MapImageWidth;
   DynHeight = MapImageHeight;
   DynLeft = 0;
   DynTop = MainMenuHeight + 1;

   DynStep = 0;
   showDynImg();
   rasterZoom();
}
//==========
// Show map.
//==========
function showMap(obj) {
   if (Map_img) {
      top.checkMap();
      Overview_img.style.visibility = "hidden";

      if (top.PostBackBeg) {
         top.hideHourglass();
      }

      if (!top.AnimateMap) {
         Map_img.style.zIndex = 2;
         Dyn_img.style.zIndex = 1;

         if (obj.id == "map_img") { //Pan,zoom animation
            top.fadeTran(Map_img,top.IeFilters,25,100,4);
         
         } else { //All other animation
            top.doBlendTran(Dyn_img.src);
         }
         window.setTimeout("hideDynImg()", 300);
      }
   }
}
//=======================
// Show & hide Dyn Image.
//=======================
function showDynImg() {
   top.AnimateMap = true;
   Dyn_img.src = Map_img.src;
   Dyn_img.style.visibility = "visible";
   Dyn_img.style.zIndex = 2;
   Map_img.style.visibility = "hidden";
   Map_img.style.zIndex = 1;
}
function hideDynImg() {
   Dyn_img.style.visibility = "hidden";
   Dyn_img.style.width = Map_img.style.width;
   Dyn_img.style.height = Map_img.style.height;
   Dyn_img.style.left = Map_img.style.left;
   Dyn_img.style.top = Map_img.style.top;
}
//=====================
// Add acetate text.
//=====================
function addText() {
   if (ATextAndXYCount == MaxAText) {
      alert("Please refresh the drawing before adding more text elements");
      return;
   }
   if (ATextCount == 0) {
      AText = top.main_frame.AText1;

   } else if (ATextCount == 1) {
      AText = top.main_frame.AText2;

   } else if (ATextCount == 2) {
      AText = top.main_frame.AText3;

   } else if (ATextCount == 3) {
      AText = top.main_frame.AText4;

   } else if (ATextCount == 4) {
      AText = top.main_frame.AText5;
   }
   AText.value = "Text";
   AText.size = 4;
}
//==================
// Add acetate text.
//==================
function addXY() {
   if (ATextAndXYCount == MaxAText) {
      alert("Please refresh the drawing before adding more XY elements");
      return;
   }
   if (AXYCount == 0) {
      AXY = top.main_frame.AXY1;

   } else if (AXYCount == 1) {
      AXY = top.main_frame.AXY2;

   } else if (AXYCount == 2) {
      AXY = top.main_frame.AXY3;

   } else if (AXYCount == 3) {
      AXY = top.main_frame.AXY4;

   } else if (AXYCount == 4) {
      AXY = top.main_frame.AXY5;
   }
}
//======================
// Text move over event.
//======================
function aTextMove() {
   if (ActiveTool.id == "addText") {
      if (ATextAndXYCount < MaxAText) {
         AText.style.visibility = "hidden";
      }
   }
   if (ActiveTool.id == "addXY") {
      if (ATextAndXYCount < MaxAText) {
         AXY.style.visibility = "hidden";
      }
   }
}
//=====================
// AText keydown event.
//=====================
function aTextChange(element) {
   var numChar = element.value.length;
   var pos = parseInt(element.style.left) + (numChar * 10)
   if (pos < MapImageWidth) {
      if (numChar > 0) {
         element.size = numChar;
      }
   }
}
//==========================
// Compute 2 point distance.
//==========================
function twoPntDistance(x1,y1,x2,y2) {
   var dist;
   var xD = Math.abs(x1 - x2);
   var yD = Math.abs(y1 - y2);
   dist = Math.sqrt(Math.pow(xD,2) + Math.pow(yD,2));
   return dist;  
}
//===================
// Stretch map image.
//===================
function stretchMap() {
   var reloadTimer=1; 
   window.clearTimeout(reloadTimer); 
   reloadTimer = window.setTimeout("setMapImageElementSize()", 1000);
}
//====================================
// Display vml for identified feature.
//====================================
function displayVML(featureClass, vmlGeometry) {
   clearVML();

   if (vmlGeometry != "") {
      if (featureClass == "point") {
         Point_vml.path = vmlGeometry;

      } else if (featureClass == "line") {
         Line_vml.path = vmlGeometry;

      } else {
         Poly_vml.path = vmlGeometry;
      }
      saveVML();
   }
}
//=======================
// Save highlighting VML.
//=======================
function saveVML() {
   PointSave_vml = Point_vml.path + "";
   LineSave_vml = Line_vml.path + "";
   PolySave_vml = Poly_vml.path + "";
}
//==========================
// Restore highlighting VML.
//==========================
function restoreVML() {
   Point_vml.path = PointSave_vml;
   Line_vml.path = LineSave_vml;
   Poly_vml.path = PolySave_vml;
}
//========================
// Clear highlighting VML.
//========================
function clearVML() {
   Point_vml.path = "m 0 0 l 0,0 0,0 0,0 0,0 e";
   Line_vml.path = "m 0 0 l 0,0 0,0 0,0 0,0 e";
   Poly_vml.path = "m 0 0 l 0,0 0,0 0,0 0,0 e";
}
//=========================
// Clear measure variables.
//=========================
function clearMeasureVar() {
   XyCount = 0;
   
   if (top.IeFilters) {
      XyVML = "";
      XyFirstPntVML = "";
      XyVML_vml.path = "m 0 0 l 0,0 0,0 0,0 0,0 e";
      XyClose_vml.path = "m 0 0 l 0,0 0,0 0,0 0,0 e";
   }
}
//==================================
// Set the map image size in pixels.
//==================================
function setMapImageElementSize() {
   var mapFrameHeight;
   var mapFrameWidth;
   var mapImageHeight;
   var mapImageWidth;
   var menuHeadingHeight;
   var toolbarHeight;

   if (top.WebSiteInitialized) {
      FullExtentImage = "";
   }
   //mapFrameHeight = top.main_frame.document.body.clientHeight; //IE only
   mapFrameHeight = (top.main_frame.document.body.clientHeight || top.main_frame.window.innerHeight);
   mapFrameWidth  = top.main_frame.document.body.clientWidth;
   //alert ("main_frame height & width=" + mapFrameHeight + ", " + mapFrameWidth);

   menuHeadingHeight = document.getElementById("menuHeading_div").clientHeight;
   toolbarHeight = document.getElementById("toolbar_div").clientHeight;
   MapImageHeight = mapFrameHeight - (menuHeadingHeight + toolbarHeight);
   MapImageWidth = mapFrameWidth;
   //alert ("menuHeadingHeight, toolbarHeight=" + menuHeadingHeight + ", " + toolbarHeight);

   Map_img = document.getElementById("map_img");
   Map_img.height = MapImageHeight;
   Map_img.width = MapImageWidth;

   //Position panZoom icon
   var panZoom_img = document.getElementById("panZoom_img");
   panZoom_img.style.left = "1px";
   panZoom_img.style.top  = (menuHeadingHeight + toolbarHeight + 42) + "px";
   panZoom_img.style.visibility = "visible";

   //Position hourglass image
   var hg = document.getElementById("hourglass");
   hg.style.left = (mapFrameWidth - 30) + "px";
   hg.style.top = "4px";

   if (top.IeFilters) {
      clearVML();
   }
   clearMeasureVar();

   if (top.AutoRefresh) {
      top.refreshMap();
   }
}
//==================================
// Convert pixel to map coordinates.
//==================================
function getXyMap(x,y) {
	var pixelX = (XMaxMap - XMinMap) / MapImageWidth;
	XMap = pixelX * x + XMinMap;

	var yTemp = (MapImageHeight + MainMenuHeight) - y;
	var pixelY = (YMaxMap - YMinMap) / MapImageHeight;
	YMap = pixelY * yTemp + YMinMap;
}
//====================
// Get area in pixels.
//====================
function getAreaPix() {
   var dx = Math.abs(MouseUp.xPix - MouseDown.xPix) + 1;
   var dy = Math.abs(MouseUp.yPix - MouseDown.yPix) + 1;
   var areaPix = dx * dy;
   return areaPix;  
}
//=============
// Get lat/lon.
//=============
function getLatLon(uX,uY) {
   var a = 20925604.48;   		//major radius of ellipsoid, map units (NAD 83)
   var ec = 0.08181905782;  	//eccentricity of ellipsoid (NAD 83)
   var angRad = 0.01745329252; //number of radians in a degree
   var pi4 = Math.PI / 4;     //Pi / 4

   var p0 = top.LatOrigin * angRad;
   var p1 = top.Lat1stParallel * angRad;
   var p2 = top.Lat2ndParallel * angRad;
   var m0 = top.CentralMeridian * angRad;
   var x0 = top.CentralMeridianEasting;
   var y0 = top.FalseNorthing;

   // Calculate the coordinate system constants.
   with (Math) {
      var m1 = cos(p1) / sqrt(1 - (pow(ec,2)) * pow(sin(p1),2));  
      var m2 = cos(p2) / sqrt(1 - (pow(ec,2)) * pow(sin(p2),2));
      var t0 = tan(pi4 - (p0 / 2));
      var t1 = tan(pi4 - (p1 / 2));
      var t2 = tan(pi4 - (p2 / 2));
      t0 = t0 / pow(((1 - (ec * (sin(p0)))) / (1 + (ec * (sin(p0))))),ec/2);  
      t1 = t1 / pow(((1 - (ec * (sin(p1)))) / (1 + (ec * (sin(p1))))),ec/2);
      t2 = t2 / pow(((1 - (ec * (sin(p2)))) / (1 + (ec * (sin(p2))))),ec/2);
      var n = log(m1 / m2) / log(t1 / t2);
      var f = m1 / (n * pow(t1,n)); 
      var rho0 = a * f * pow(t0,n);

      // Calculate the Longitude.
      var uX = uX - x0;
      var uY = uY - y0;
      var pi2 = pi4 * 2;

      var rho = sqrt(pow(uX,2) + pow((rho0 - uY),2));  
      var theta = atan(uX / (rho0 - uY));
      var txy = pow((rho / (a * f)),(1 / n));
      var lon = (theta / n) + m0;
      uX = uX + x0;

      // Estimate the Latitude
      var lat0 = pi2 - (2 * atan(txy));

      // Substitute the estimate into the iterative calculation that
      // converges on the correct Latitude value.
      var part1 = (1 - (ec * sin(lat0))) / (1 + (ec * sin(lat0)));
      var lat1 = pi2 - (2 * atan(txy * pow(part1,(ec/2))));

      while ((abs(lat1 - lat0)) > 0.000000002) {
         lat0 = lat1;
         part1 = (1 - (ec * sin(lat0))) / (1 + (ec * sin(lat0)));
         lat1 = pi2 - (2 * atan(txy * pow(part1,(ec/2))));
      }
   }
   // Convert from radians to degrees.
   var lat = lat1 / angRad;
   lon = lon / angRad;

   // Format output.
   LatDMS = top.DDToDMS(lat,false,true);
   LonDMS = top.DDToDMS(-lon,false,true);
   var u = 100000
	lat = parseInt(lat * u + (5/10)) / u;
	lon = parseInt(lon * u + (5/10)) / u;
   return "Lat, Lon  DD: " + lat + "\xB0 N,  " + -lon + "\xB0 W" + "     DMS: " + LatDMS + " N,  " + LonDMS + " W";
}
