﻿//alert(CrimeIdPrefix);
if (typeof(ie6) == "undefined")
  ie6 = false;
  
var perfTimer = new PerformanceTimer("debug", false);
var currentCrimeCount = 0;
var map = null;
var crimeLayer = null;
function printVE_Exception(e)
{
  alert("Name: " + e.name + "\nMessage: " + e.message + "\nSource: " + e.source);
}

//Add ServerSideIndex property to the VEShape object
VEShape.prototype.ServerSideIndex = 0;
VEShape.prototype.DetailsLoaded = false;
VEShape.prototype.IsCrimeMarker = false;

var crimeDensityAdded = false;
function getMap()
{
  //alert('ie6=' + ie6);
  map = new VEMap('MapImageHolder');
  map.SetDashboardSize(VEDashboardSize.Normal);  
  //restore cookies
  var lat =  Cookie.get("MapCenterLat");
  var lng =  Cookie.get("MapCenterLong");
  var zoom = Cookie.get("ZoomLevel");
  if (lat != null && lng != null && zoom != null)
    map.LoadMap(new VELatLong(lat, lng), zoom,null,null,VEMapMode.Mode2D, true);
  else
    map.LoadMap(new VELatLong(29.7787298889194, -95.3581739969888), 10,null,null,VEMapMode.Mode2D, true);
            
  map.AttachEvent("onchangeview", processMapChangeView);
  map.AttachEvent("onmouseover", processMapMouseOver);
  map.AttachEvent("onmouseout", processMapMouseOut);
  map.AttachEvent("onresize", processMapResize);
  //map.AttachEvent("onclick", processMouseMove);
  crimeLayer = new VEShapeLayer();
  map.AddShapeLayer(crimeLayer);
  
  //add density legend
  map.AddControl(document.getElementById('DensityLegend'));
  repositionDensityControl();
  
  //remove from here because the "visibleOnLoad" param doesn't work
  //addCrimeDensityLayer();
  
  showCrimes();
  
}
registerPageLoadFunction(getMap);

//density layer id will incremented each time the map settings change
//the server will only adjust the color scale when this changes
var densityLayerId = 0;  
var lastCrimeDensitySettings = "";
function addCrimeDensityLayer()
{
  //alert("addCrimeDensityLayer");
  crimeDensityAdded = true;
  lastCrimeDensitySettings = _generateMapArgsCrimeSetup();
  
  //added "generatemapargs" to the end so that it only caches the tiles that have the same arguments
  var tileSourceSpec = new VETileSourceSpecification("CrimeDensity", "tiles/%4maptile.aspx?" + _generateMapArgs(0,0,0,0) + "&densityLayerId=" + densityLayerId);
  tileSourceSpec.NumServers = 1;
  tileSourceSpec.Bounds = [new VELatLongRectangle(new VELatLong(31,-98),new VELatLong(27,-93))];
  tileSourceSpec.MinZoom = 1;
  tileSourceSpec.MaxZoom = 18;
  tileSourceSpec.Opacity = .3;
  tileSourceSpec.ZIndex = 100;
  
  map.AddTileLayer(tileSourceSpec, true);
}


function removeCrimeDensityLayer()
{
  //alert("remove crime density");
  crimeDensityAdded = false;
  map.DeleteTileLayer("CrimeDensity");
}

var showingCrimeDensity = false;
function showCrimeDensity()
{
  //alert("show crime density");
  if (!crimeDensityAdded)
  {
    addCrimeDensityLayer();
    showDensityLegend();
    showingCrimeDensity = true;
  }
}

function hideCrimeDensity()
{
  //alert("hide crime density");
  if (crimeDensityAdded)
  {
    removeCrimeDensityLayer();
    hideDensityLegend();
    showingCrimeDensity = false;
  }
}

function deleteCrimeMarkers()
{
  crimeLayer.DeleteAllShapes();
}

function showCrimes()
{
  perfTimer.start("showCrimesServer");
  perfTimer.start("showCrimes");
  
  showWaitImage();
  
  _getElementById("MapStatusLabel").innerHTML = "Loading...";
  var mapBounds = getMapBounds();
  var top = mapBounds.TopLeftLatLong.Latitude;
  var left = mapBounds.TopLeftLatLong.Longitude;
  var bottom = mapBounds.BottomRightLatLong.Latitude;
  var right = mapBounds.BottomRightLatLong.Longitude;
//  printdebug("zoomlevel=" + map.getzoomlevel());
//  printdebug("top=" + top);
//  printdebug("bottom=" + bottom);
//  printdebug("left=" + left);
//  printDebug("right=" + right);
  var url = "RetrieveCrimes.aspx";
  var args = _generateMapArgs(top, left, bottom, right);
  var loader = new AjaxLoader(url, args, true);
  loader.load(processCrimeMarkers);
}

function processCrimeMarkers(inResponse)
{
	var resultsSize = inResponse.length;
  if (resultsSize > 0)
  {
    perfTimer.stop("showCrimesServer");
    deleteCrimeMarkers();
    perfTimer.start("processResults");
    perfTimer.start("parseResults");
	  var resultsTotal = eval("(" + inResponse + ")");
	  var results = resultsTotal.Results;
	  perfTimer.stop("parseResults");
    if (results.Status == "LoginExpired")
      window.location = "Expired.aspx";
    else if (results.Status == "SessionExpired" &&
             _getElementById('UserOriginallyLoggedIn').value == "true") //if they aren't logged in now, but were logged in at one point..redirect
      window.location = "Login.aspx";
	  else
	  {
      _getElementById("MapStatusLabel").innerHTML = "Showing " + results.CrimeCount + " crimes";
      currentCrimeCount = results.CrimeCount;
      if (results.Display == "Density")
      {
        if (lastCrimeDensitySettings != _generateMapArgsCrimeSetup())
        {
          //criem settings changed.  change the id for the density layer
          //so the server knows to recalculate the average density
          densityLayerId++;
          hideCrimeDensity(); //force a refresh of the density map
        }
        showCrimeDensity();
      }
      else
      {
        hideCrimeDensity();
        perfTimer.start("addMarkers");
	      for (var clusterIndex in results.CrimeClusters)
	      {
	        try
	        {
	          var thisCluster = results.CrimeClusters[clusterIndex];
	          //alert(thisCluster);
	          var clusterLocation = new VELatLong(thisCluster.Latitude, thisCluster.Longitude);
	          var pushpin = new VEShape(VEShapeType.Pushpin, clusterLocation);
		        pushpin.ServerSideIndex = clusterIndex;
		        pushpin.IsCrimeMarker = true;
		        var maxClusterSize = results.MaxClusterSize;
		        if (maxClusterSize < 5)
		          maxClusterSize = 10;
		          
		        if (thisCluster.Clustered)
		        {
		          var myPercentage = thisCluster.CrimeCount / maxClusterSize;
		          var myScale = Math.round(myPercentage * 8);
		          if (map.GetMapMode() == VEMapMode.Mode3D)  //3d mode can't handle customHTML
		            pushpin.SetCustomIcon("images/cluster3d" + myScale + ".png");
		          else
		          {
		            var customIconSpec = new VECustomIconSpecification();
		            if (!ie6)
		              customIconSpec.CustomHTML = "<div class=\"CrimeCountDiv\" style=\"background-image:url(images/cluster" + myScale + ".png);\"><table width=\"100%\" height=\"100%\"><tr><td align=\"center\" valign=\"middle\"><span class=\"CrimeCountText\">" + thisCluster.CrimeCount + "</span></td></tr></table></div>";		          //customIconSpec.Image = "images/cluster.png";
		            else
		              customIconSpec.CustomHTML = "<div class=\"CrimeCountDiv\" style=\"{filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/cluster" + myScale + ".png', sizingMethod='image');}\"><table width=\"100%\" height=\"100%\"><tr><td align=\"center\" valign=\"middle\"><span class=\"CrimeCountText\">" + thisCluster.CrimeCount + "</span></td></tr></table></div>";		          //customIconSpec.Image = "images/cluster.png";
		            
		            //customIconSpec.TextContent = thisCluster.CrimeCount;
		            pushpin.SetCustomIcon(customIconSpec);
		          }
		        }
		        else
		        {
		          if (!ie6)
                pushpin.SetCustomIcon("images/offense_" + thisCluster.OffenseCode + ".png");
              else
                pushpin.SetCustomIcon("<div style=\"{width:15px; height:15px; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/offense_" + thisCluster.OffenseCode + ".png', sizingMethod='image');}\"></div>");
		        }
            pushpin.SetTitle("Crimes at this location");
	          pushpin.SetDescription("Loading...");
	          //printDebug("PushPin.serversideindex=" + pushpin.ServerSideIndex + "<br>PushPin.DetailsLoaded=" + pushpin.DetailsLoaded + "<br>");
	          crimeLayer.AddShape(pushpin);
	        }
	        catch(e)
	        {
	          printVE_Exception(e);
	        }
	      }
        perfTimer.stop("addMarkers");

	    }
	    hideWaitImage();
	  }
    //printDebug("resultsSize= " + resultsSize);
	  //printServerPerformance(resultsTotal.Performance);
	  perfTimer.stop("processResults");
    perfTimer.stop("showCrimes");
    perfTimer.displayResults();
  }
}

function printServerPerformance(perf)
{
  for (var resultIndex in perf)
    printDebug(perf[resultIndex].Event + " took " + perf[resultIndex].Time + " seconds<br>");
}

function processMapResize(e)
{
  //printDebug(e.eventName);
  //hack...delay the reposition, because something is happening
  //in the virtual earth javascript that is overriding this later on and
  //the legend ends up on the left top of hte map
  setTimeout("repositionDensityControl()", 500);
  if (showingCrimeDensity)
    setTimeout("showDensityLegend()", 700);
}

var showCrimesTimeoutId = 0;
function processMapChangeView(e)
{
  saveMapSettingsToCookie();
  currentAddressPinViewChangeCount--;
  if (currentAddressPinViewChangeCount <= 0 &&
      currentAddressPin != null)
  {
    map.DeleteShape(currentAddressPin);
    currentAddressPin = null;
  }
  clearTimeout(showCrimesTimeoutId);
  showCrimesTimeoutId = setTimeout("showCrimes()", 1000);
}

function saveMapSettingsToCookie()
{
  var encodedCenter = map.GetCenter();
  //start removal ****
  var dc = new _xy1; //careful...deep in the virt earth code I found this to decode lat/long
  var center = dc.Decode(encodedCenter);
  //var center = encodedCenter;
  //end removal ******
  
  var expirationMinutes = 5;
  var zoomLevel = map.GetZoomLevel();
  if(map.GetMapStyle() == VEMapStyle.BirdseyeHybrid ||
     map.GetMapStyle() == VEMapStyle.Birdseye)
    zoomLevel = 17; //birdseye returns 1 here...which is all the earth
    
  Cookie.set("MapCenterLat", center.Latitude, 0, 0, expirationMinutes);
  Cookie.set("MapCenterLong", center.Longitude, 0, 0, expirationMinutes);
  Cookie.set("ZoomLevel", zoomLevel, 0, 0, expirationMinutes);
}

var hoveredPin = null;
var hoveredPinTimeoutID = null;
function processMapMouseOver(e)
{
  if (e.elementID &&
      map.GetShapeByID(e.elementID).IsCrimeMarker)
  {
    clearTimeout(hoveredPinTimeoutID);
    hoveredPinTimeoutID = setTimeout(processMapMouseHover, 1000);
    hoveredPin = e.elementID;
    return true;//tell MS not to show the popup;
  }
}

function processMapMouseOut(e)
{
  if (e.elementID)
    clearTimeout(hoveredPinTimeoutID);
}

function processMapMouseHover()
{
  var thisCrimeShape = map.GetShapeByID(hoveredPin);
  if (thisCrimeShape != null)
  {
    map.ShowInfoBox(thisCrimeShape, null, new VEPixel(0,-15));
    //printDebug("thisCrimeShape.serversideindex=" + thisCrimeShape.ServerSideIndex + "<br>ThisCrimeShape.DetailsLoaded=" + thisCrimeShape.DetailsLoaded + "<br>");

    if (typeof(thisCrimeShape.DetailsLoaded) != "undefined" && //ie hack
        !thisCrimeShape.DetailsLoaded)
      loadCrimeInfoBox(thisCrimeShape);
    //printDebug(thisCrimeShape.ServerSideIndex);
  }
}

var pendingInfoBoxShape = null;
var infoBoxRequest = null;
function loadCrimeInfoBox(inShape)
{
  pendingInfoBoxShape = inShape;
  var loader = new CrimeClusterLoader(inShape.ServerSideIndex, true, "printWindow", ie6);
  loader.loadCluster(processClusterInfoBox);
}

function processClusterInfoBox(description, count)
{
  if (count > 1)
    pendingInfoBoxShape.SetTitle(count + " Crimes at this location");
  else
    pendingInfoBoxShape.SetTitle("Crimes at this location");
    
  pendingInfoBoxShape.SetDescription(description);
  pendingInfoBoxShape.DetailsLoaded = true;
  map.HideInfoBox();//had to put this here because the infobox wasn't resizing itself
  map.ShowInfoBox(pendingInfoBoxShape, null, new VEPixel(0,-15));
}

function getMapBounds()
{
  if(map.GetMapStyle() == VEMapStyle.BirdseyeHybrid ||
     map.GetMapStyle() == VEMapStyle.Birdseye)
  {
  //alert("Birdseye");
    //build view decoding latlongs
    result = getMapBoundsBirdsEye();
  }
  else if (map.GetMapMode() == VEMapMode.Mode3D)
  {
  //alert("3d");
    result = getMapBounds3D();
  }
  else
  {
  //alert("nrmal");
    //get view from map
    result = map.GetMapView();
  }
  return result;
}

function getMapBounds3D()
{
  var view = map.GetMapView();
  var points = new Array();
  points.push(view.TopLeftLatLong);
  points.push(view.TopRightLatLong);
  points.push(view.BottomLeftLatLong);
  points.push(view.BottomRightLatLong);

  var result = new VELatLongRectangle(view.TopLeftLatLong.Clone(), view.BottomRightLatLong.Clone());
  for (var index in points)
  {
    if (points[index].Latitude > result.TopLeftLatLong.Latitude)
      result.TopLeftLatLong.Latitude = points[index].Latitude;
      
    if (points[index].Latitude < result.BottomRightLatLong.Latitude)
      result.BottomRightLatLong.Latitude = points[index].Latitude;
      
    if (points[index].Longitude < result.TopLeftLatLong.Longitude)
      result.TopLeftLatLong.Longitude = points[index].Longitude;
    
    if (points[index].Longitude > result.BottomRightLatLong.Longitude)
      result.BottomRightLatLong.Longitude = points[index].Longitude;
  }
  return result;
}
function getMapBoundsBirdsEye()
{
  var result;
  
  var birdsEyeScene = map.GetBirdseyeScene();

//start removal ******
  var v = map.GetMapView();
  var dc = new _xy1;//used to be VELatLongDecoder
  var tl = dc.Decode(v.TopLeftLatLong);
  var br = dc.Decode(v.BottomRightLatLong);
  //this is the official method, but the rectangle it returns is freaking huge
  //so hack away I go
  //var v = birdsEyeScene.GetBoundingRectangle();
  //var tl = v.TopLeftLatLong;
  //var br = v.BottomRightLatLong;
  //printDebug("tl, br=" + tl + ", " + br);
  //printDebug("v=" + v );
//end removal ******
  //check birds eye direction and correct rectangle
  var be = map.GetBirdseyeScene();
  switch(be.GetOrientation())
  {
    case VEOrientation.North:
      result = new VELatLongRectangle(tl,br,null,null);
      break;
    case VEOrientation.East:
      //flip long
      result = new VELatLongRectangle(new VELatLong(tl.Latitude,br.Longitude),new VELatLong(br.Latitude,tl.Longitude),null,null);
      break;
    case VEOrientation.South:
      //flip lat and long
      result = new VELatLongRectangle(br,tl,null,null);
      break;
    case VEOrientation.West:
      //flip lat
      result = new VELatLongRectangle(new VELatLong(br.Latitude,tl.Longitude),new VELatLong(tl.Latitude,br.Longitude),null,null);
      break;
  }

  return result;
}
var booger = 0;
function processMouseMove(e)
{
  if (map.GetMapMode() == VEMapMode.Mode3D)
  {
    if (booger == 0)
      clearDebug();
    printDebug("<b>Click Location</b><br>Latitude: " + e.latLong.Latitude + "<br>Longitude: " + e.latLong.Longitude + "<br>");
    var latlong;
    var name;
    printDebug("<b>");
    if (booger == 0)
    {
      printDebug("TopLeftLatLong</b><br>");
      latlong = map.GetMapView().TopLeftLatLong;
    }
    if (booger == 1)
    {
      printDebug("TopRightLatLong</b><br>");
      latlong = map.GetMapView().TopRightLatLong;
    }
    if (booger == 2)
    {
      printDebug("BottomLeftLatLong</b><br>");
      latlong = map.GetMapView().BottomLeftLatLong;
    }
    if (booger == 3)
    {
      printDebug("BottomRightLatLong</b><br>");
      latlong = map.GetMapView().BottomRightLatLong;
    }
    printDebug("Latitude: " + latlong.Latitude + "<br>Longitude: " + latlong.Longitude + "<br>");
    booger++;
    booger %= 4;
  }
  
  return true;
}

preloadImage("Images/wait.gif");
                         
function preloadImage(imageName)
{
  var image = new Image();
  image.src = imageName;
}

function _getElementById(inId)
{
  //prepend the f'ing prefix that M$ insists on using on all my id's
  return document.getElementById(_getClientId(inId));
}

function _getClientId(inId)
{
  return CrimeIdPrefix + inId;
}

function printWindow(inId)
{
  winWidth = document.getElementById('identifyWindowHolder').offsetWidth + 35;
  newwindow=window.open('id_location_print.htm?id=' + inId,'name','toolbar=1,menubar=1,resizable=1,scrollbars=1,height=' + 300 + ',width=' + winWidth);
}

var tipWindow = new PopupWindow("infoPopup");
var tipEndWidth = 0;
var tipEndHeight = 0;
var currentWidth = 0;
var currentHeight = 0;
var numIterations = 20;
var currentIteration = 0;

function showTip()
{
  var popUpDiv = document.getElementById("infoPopup");
  tipEndWidth = popUpDiv.offsetWidth;
  tipEndHeight = popUpDiv.offsetHeight;

  currentIteration = 0;

  //alert("Width: " + tipEndWidth + "\nHeight: " + tipEndHeight );

  currentWidth = 0;
  currentHeight = 0;

  popUpDiv.style.width = "0px";
  popUpDiv.style.height = "0px";
  
  tipWindow.showPopup("tipAnchor");
  expandTip();
}

function expandTip()
{
  var popUpDiv = document.getElementById("infoPopup");
  //alert("Width: " + popUpDiv.style.width + "\nHeight: " + popUpDiv.style.height );
  currentWidth = (tipEndWidth-tipEndWidth*Math.cos(Math.PI/2/numIterations*currentIteration));
  currentHeight = (tipEndHeight-tipEndHeight*Math.cos(Math.PI/2/numIterations*currentIteration));

  currentIteration++;

  popUpDiv.style.width = currentWidth + "px";
  popUpDiv.style.height = currentHeight + "px";

  if (currentIteration == numIterations)
  {
    popUpDiv.style.width = tipEndWidth + "px";
    popUpDiv.style.height = tipEndHeight + "px";
    setTimeout("closeTip()", 5000);
  }
  else
    setTimeout("expandTip()", 5);
}

function closeTip()
{
  tipWindow.hidePopup();
}

function isFirefox()
{
  var agt=navigator.userAgent.toLowerCase();
  if (agt.indexOf("firefox") != -1)
    return true;
  return false;
}

var lastClickX;
var lastClickY;

var popUpActive = false;

var allMenus = Array();
var menuHeaderCell = Object();
var popUpMenus = Object();

allMenus[0] = "offenseMenuDiv";
menuHeaderCell["offenseMenuDiv"] = "offenseMenuHeaderCell";
popUpMenus["offenseMenuDiv"] = new PopupWindow("offenseMenuDiv");
setPopupOffset(popUpMenus["offenseMenuDiv"]);

allMenus[1] = "mapSizeMenuDiv";
menuHeaderCell["mapSizeMenuDiv"] = "mapSizeMenuHeaderCell";
popUpMenus["mapSizeMenuDiv"] = new PopupWindow("mapSizeMenuDiv");
setPopupOffset(popUpMenus["mapSizeMenuDiv"]);

allMenus[2] = "dateToSelectorDiv"
menuHeaderCell["dateToSelectorDiv"] = "dateToAnchor";

allMenus[3] = "dateFromSelectorDiv"
menuHeaderCell["dateToSelectorDiv"] = "dateToAnchor";

allMenus[4] = "multiHitMenuDiv";
menuHeaderCell["multiHitMenuDiv"] = "zipMultiHitMenuHeaderCell";
popUpMenus["multiHitMenuDiv"] = new PopupWindow("multiHitMenuDiv");
setPopupOffset(popUpMenus["multiHitMenuDiv"]);

var currentLength = allMenus.length;
var lastPremisesMenu = "premisesMenuDiv0"
for (var i = 0; i < (Math.floor(getNumPremises() / 15) + 1); i++)
{
  allMenus[currentLength+i] = "premisesMenuDiv"+i;
  menuHeaderCell["premisesMenuDiv"+i] = "premisesMenuHeaderCell";
  popUpMenus["premisesMenuDiv"+i] = new PopupWindow("premisesMenuDiv"+i);
  setPopupOffset(popUpMenus["premisesMenuDiv"+i]);
}


var menuActive = Object();
for (var menu = 0; menu < allMenus.length; menu++)
{
  menuActive[allMenus[menu]] = false;
}

var hoverTimerId = 0;
var onMapImage = false;

var hSizeOpen = false;
var vSizeOpen = false;

//create calendar popups
var earliestDate = getEarliestDate();
var latestDate = getLatestDate();
subtractDay(earliestDate);
addDay(latestDate);
//alert("EarliestDate: " + earliestDate + "\nLatestDate: " + latestDate);
var dateToCal = new CalendarPopup('dateToSelectorDiv');
var dateFromCal = new CalendarPopup('dateFromSelectorDiv');
popUpMenus["dateToSelectorDiv"] = dateToCal;
popUpMenus["dateFromSelectorDiv"] = dateFromCal;

setPopupOffset(dateFromCal);

dateToCal.setDisplayType("date");
dateToCal.showYearNavigation();
dateToCal.addDisabledDates(null, formatDate(earliestDate, "M/d/yyyy"));
dateToCal.addDisabledDates(formatDate(latestDate, "M/d/yyyy"), null);
setPopupOffset(dateToCal)

dateFromCal.setDisplayType("date");
dateFromCal.showYearNavigation();
dateFromCal.addDisabledDates(null, formatDate(earliestDate, "M/d/yyyy"));
dateFromCal.addDisabledDates(formatDate(latestDate, "M/d/yyyy"), null);

dateToCal.setReturnFunction('setToDate');
dateFromCal.setReturnFunction('setFromDate');
//dateToCal.showNavigationDropdowns();  IE sucks...when the dropdown is visible, it triggers mouse friggin' out and the menu closes
//dateFromCal.showNavigationDropdowns();

var numTabs = 3;
var allTabNames = new Array();
allTabNames[0] = "CrimeFilterMenuTab";
allTabNames[1] = "SearchMenuTab";
allTabNames[2] = "ToolsMenuTab";

var tabContentsDivName = new Array();
tabContentsDivName[0] = "CrimeFilterItems";
tabContentsDivName[1] = "SearchMenuItems";
tabContentsDivName[2] = "ToolsMenuItems";

var currentSelectedTab = 0;
function switchTab(inMenu)
{
  //this function swaps the innerhtml of the placeholder div with the content divs
  closeAllMenus();

  var itemsPlaceholder = document.getElementById("toolbarItemsDiv");

  document.getElementById(tabContentsDivName[currentSelectedTab]).innerHTML = itemsPlaceholder.innerHTML;

  for (var i = 0; i < numTabs; i++)
  {
    var thisTab = document.getElementById(allTabNames[i]);
    if (i == inMenu)
    {
      var content = document.getElementById(tabContentsDivName[i]);
      itemsPlaceholder.innerHTML = content.innerHTML;
      content.innerHTML = "";
      thisTab.className = "tabSelected";
    }
    else
    {
      thisTab.className = "tabNotSelected";
    }
  }
  currentSelectedTab = inMenu;
}

function setPopupOffset(inPopup)
{
  //alert(inPopup);
  if (!isFirefox())
  {
    inPopup.offsetX = 0;
    inPopup.offsetY = 19;
  }
  else
  {
    inPopup.offsetX = 0;
    inPopup.offsetY = 9;
  }

}

function showDateToCalendar(anchor)
{
  closeAllMenus();
  clearMenuTimeout("dateToSelectorDiv");

  dateToCal.showCalendar(anchor, _getElementById("DateTo").value);
  menuActive["dateToSelectorDiv"] = true;
}

function showDateFromCalendar(anchor)
{
  closeAllMenus();
  clearMenuTimeout("dateFromSelectorDiv");

  dateFromCal.showCalendar(anchor, _getElementById("DateFrom").value);
  menuActive["dateFromSelectorDiv"] = true;
}

function setToDate(y,m,d)
{
  //alert(m+"/"+d+"/"+y);
  var newDate = m+"/"+d+"/"+y;
  _getElementById("DateTo").value = m+"/"+d+"/"+y;
  menuActive[allMenus["dateToSelectorDiv"]] = false;
  document.getElementById('dateToLabel').innerHTML=newDate;
}

function setFromDate(y,m,d)
{
  //alert(m+"/"+d+"/"+y);
  var newDate = m+"/"+d+"/"+y;
  _getElementById("DateFrom").value = newDate;
  menuActive[allMenus["dateFromSelectorDiv"]] = false;
  document.getElementById('dateFromLabel').innerHTML=newDate;
}

function selectAllPremises()
{
  for (var i = 0; i < getNumPremises(); i++)
    document.getElementById("Premises"+i).checked = true;
}

function selectNoPremises()
{
  for (var i = 0; i < getNumPremises(); i++)
    document.getElementById("Premises"+i).checked = false;
}

function _generateMapArgsCrimeSetup()
{
  var args = _generateMapArgsDate();
  args += "&" + _generateMapArgsOffensePremises();
  return args;
}

function _generateMapArgsDate()
{
  var args = "";
  args += "DateTo=" + _getElementById("DateTo").value;
  args += "&DateFrom=" + _getElementById("DateFrom").value;
  return args;
}

function _generateMapArgsOffensePremises()
{
  var args = "";
  args += "NumPremises=" + getNumPremises();
  args += "&NumOffenses=" + getNumOffenses();

  var allOffenses = new Array();
  allOffenses = _getElementById("AllOffenses").value.split(",");
  var offensePart = "&DisabledOffenses=";
  var allEnabled = true;
  //alert(allOffenses.length + "," + getNumOffenses());
  var firstTime = true;
  for (var i = 0; i < getNumOffenses(); i++)
  {
    var checkBox = _getElementById("OffenseList_"+i);
    if (!checkBox.checked)
    {
      if (!firstTime)
        offensePart += ",";
      offensePart += allOffenses[i];
      allEnabled = false;
      firstTime = false;
    }
  }
  if (!allEnabled)
    args += offensePart;
  
  var premisesPart = "&DisabledPremises=";
  allEnabled = true;
  firstTime = true;
  for (var i = 0; i < getNumPremises(); i++)
  {
    var premisesCheckBox = document.getElementById("Premises"+i);
    if (!premisesCheckBox.checked)
    {
      if (!firstTime)
        premisesPart += ",";
      premisesPart += premisesCheckBox.value;
      allEnabled = false;
      firstTime = false;
    }
  }
  if (!allEnabled)
    args += premisesPart;
  return args;
}

function _generateMapArgsLatLongZoom(top, left, bottom, right)
{
  var args = "Top="+top+
             "&Left="+left+
             "&Bottom="+bottom+
             "&Right="+right+
             "&ZoomLevel=" + map.GetZoomLevel()+
             "&BirdsEye=";
  if (map.GetMapStyle() == VEMapStyle.BirdseyeHybrid ||
      map.GetMapStyle() == VEMapStyle.Birdseye)
    args += "1";
  else
    args += "0";
    
  args += "&3DMode=";
  if (map.GetMapMode() == VEMapMode.Mode3D)
    args += "1";
  else
    args += "0";
  return args;
}

function _generateMapArgs(top, left, bottom, right)
{
  var args = _generateMapArgsLatLongZoom(top, left, bottom, right);
  args += "&" + _generateMapArgsCrimeSetup();
  //printDebug(args);
  return args;
}

function closePopup(divId)
{
  //this is for the ID popup
  var divElement = document.getElementById(divId);
  var style = divElement.style;
  style.width = "0px";
  style.height = "0px";
  style.visibility = "hidden";
  divElement.innerHTML = "";
  popUpActive = false;
  
}

function setAllOffenseChecked(inValue)
{
  for (var i = 0; i < getNumOffenses(); i++)
  {
    var checkBox = _getElementById("OffenseList_"+i);
    checkBox.checked = inValue;
  }
}

var closeMenuDelayId = new Object();
for (var menu = 0; menu < allMenus.length; menu++)
{
  closeMenuDelayId[allMenus[menu]] = false;
}

function clearMenuTimeout(id)
{
  if (closeMenuDelayId[id])
    clearTimeout(closeMenuDelayId[id]);
}

function closeMenuDelay(id)
{
  clearMenuTimeout(id);
  closeMenuDelayId[id] = setTimeout("closeMenu(\""+id+"\")", 500);
}

function closeDateFromMenuDelay(id)
{
  clearMenuTimeout(id);
  closeMenuDelayId[id] = setTimeout("closeDateFromMenu(\""+id+"\")", 500);
}

function closeDateFromMenu(id)
{
  dateFromCal.hideCalendar();
  menuActive[id] = false;
}

function closeDateToMenuDelay(id)
{
  clearMenuTimeout(id);
  closeMenuDelayId[id] = setTimeout("closeDateToMenu(\""+id+"\")", 500);
}

function closeDateToMenu(id)
{
  dateToCal.hideCalendar();
  menuActive[id] = false;
}

function closeMenu(id)
{
  //alert("closeMenu("+id+")");
  popUpMenus[id].hidePopup();

//do it like this so that it works on calendars as well
  //var menuDiv = document.getElementById(id);
  //menuDiv.style.visibility = "hidden";
  //menuActive[id] = false;
}

function closeAllMenus()
{
  for (var i = 0; i < allMenus.length; i++)
  {
    clearMenuTimeout(allMenus[i]);
    closeMenu(allMenus[i]);
  }
}

/*
function initializeMenu(id)
{
  //alert("initializing id=" + id + " firstPrem=" + firstPremises + "\nInnerHTML=" + document.getElementById(firstPremises).innerHTML);
  if (id == "premisesMenuDiv")
  {
    //alert("document.getElementById(\"premisesTable0\").innerHTML="+document.getElementById("premisesTable0").innerHTML);
    document.getElementById(id).innerHTML=document.getElementById("premisesTable0").innerHTML;
  }
}
*/

function printDebug(inValue)
{
  document.getElementById("debug").innerHTML += inValue + "<br>";
}
function clearDebug()
{
  document.getElementById("debug").innerHTML = "";
}
function showMenu(id)
{
  //initializeMenu(id);

  closeAllMenus();
  clearMenuTimeout(id);

  menuActive[id] = true;
  //printDebug(id + " pre show popup");
  popUpMenus[id].showPopup(menuHeaderCell[id]);
}

function toggleMenu(id)
{
  if (menuActive[id])
    closeMenu(id);
  else
    showMenu(id);
}

function resizeMap(width, height)
{
  hideDensityLegend();
  _getElementById("MapWidth").value = width;
  _getElementById("MapHeight").value = height;
  map.Resize(width, height);
  var mapImageHolder = document.getElementById("MapImageHolder");
  mapImageHolder.style.width = width + "px";
  mapImageHolder.style.height = height + "px";
  Cookie.set("MapSizeWidth", width, 30);
  Cookie.set("MapSizeHeight", height, 30);
}

function isAnyMenuActive()
{
  //document.getElementById('debug').innerHTML = "";
  for (var menu = 0; menu < allMenus.length; menu++)
  {
    //document.getElementById('debug').innerHTML="Testing "+allMenus[menu]+": " + menuActive[menu] + "\#\#\#" + document.getElementById('debug').innerHTML;
  
    if (menuActive[allMenus[menu]])
      return true;
  }
  
  if (popUpActive)
    return true;
    
  return false;
}

function doGeocode()
{
  doGeocodeVirtualEarth();
}
function displayAddressNotFound(inMessage)
{
  var multiHitPrompt = document.getElementById("multiHitMenuDiv");
  var theHtml = "";
  theHtml = "<table class=\"menuWindowTable\">";
  theHtml += " <tr><td align=center class=\"errorHeader\">" + inMessage + "</td></tr>";
  theHtml +="</table>";
  multiHitPrompt.innerHTML = theHtml;
  showMenu("multiHitMenuDiv");
}

function doGeocodeVirtualEarth()
{
  //map.Find(what, where, findType, shapeLayer, startIndex, numberOfResults, showResults, createResults, useDefaultDisambiguation, setBestMapView, callback);
  var street = document.getElementById("streetSearch").value;
  var zip = document.getElementById("zipSearch").value;
  var city = document.getElementById("citySearch").value;
  var placeName;
  var valid = true;
  //alert("'" + street + "', length=" + street.length);
  if (street.length > 0)
    placeName = street + ", " + city + " " + zip;
  else if (zip.length > 0)
    placeName = zip;
  else
    valid = false;  
  if (valid)
    map.Find(null, placeName, null, null, 0, 10, false, false, false, false, handleGeocodeVirtualEarth);
}

function handleGeocodeVirtualEarth(inShapeLayer,inFindResult,inPlaces,inHasMore)
{
  //alert("handleGeocodeVirtualEarth");
  if (inPlaces == null ||
      inPlaces.length == 0)
  {
    displayAddressNotFound("Address not found...");
    return;
  }
  
  var filteredPlaces = new Array();
  for (var index in inPlaces)
  {
  //start removal *****
    var dc = new _xy1;//VELatLongDecoder;
    var latlong = dc.Decode(inPlaces[index].LatLong);
    //var latlong = inPlaces[index].LatLong;
  //end removal ****
    if (isLocationInHouston(latlong))
      filteredPlaces.push(inPlaces[index]);
  }
  if (filteredPlaces == null ||
      filteredPlaces.length == 0)
    displayAddressNotFound("Address not found...");
  else if (filteredPlaces.length  == 1)
  {
  //start removal *****
    var dc = new _xy1; //VELatLongDecoder;
    var latlong = dc.Decode(filteredPlaces[0].LatLong);
    //var latlong = filteredPlaces[0].LatLong;
  //end removal *****
    zoomToAddress(filteredPlaces[0].Name, latlong.Latitude, latlong.Longitude);
  }  
  else
  {
    var multiHitPrompt = document.getElementById("multiHitMenuDiv");
    var theHtml = "";
    theHtml = "<table class=\"menuWindowTable\">";
    theHtml += " <tr><td align=center class=\"multiHitHeader\">Did you mean...</td></tr>";
    var found = false;
    for (var placeIndex in filteredPlaces)
    {
      var thisPlace = filteredPlaces[placeIndex];
  //start removal *****
      var dc = new _xy1;//VELatLongDecoder;
      var latlong = dc.Decode(thisPlace.LatLong);
      //var latlong = thisPlace.LatLong;
  //end removal *****
      theHtml += "<tr>";
      theHtml += "  <td>";
      theHtml += "    <span class=\"menuLink\" onclick=\"closeMenu('mapSizeMenuDiv');zoomToAddress('" + thisPlace.Name + "', " + latlong.Latitude+ ", " + latlong.Longitude + ");\">" + thisPlace.Name + "</span>";
      theHtml += "  </td>";
      theHtml += "</tr>";
    }
    theHtml += "</table>";      
    multiHitPrompt.innerHTML = theHtml;
    showMenu("multiHitMenuDiv");  
  }
}

function isLocationInHouston(latlong)
{
  if (latlong.Latitude >= 29.4635140263 &&
      latlong.Latitude <= 30.113057804 &&
      latlong.Longitude >= -95.93124389 &&
      latlong.Longitude <= -94.763946533)
     return true;
  return false;
}

var currentAddressPin = null;
var currentAddressPinViewChangeCount = 0;
function zoomToAddress(inName, inLat, inLong)
{
  //alert("zoomToAddress");
  var latlong = new VELatLong(inLat, inLong);
  map.SetCenterAndZoom(latlong, 15);
  var thisPin = map.AddPushpin(latlong);
  thisPin.SetTitle("Address Match");
  thisPin.SetDescription(inName);
  if (currentAddressPin != null)
    map.DeleteShape(currentAddressPin);
  currentAddressPin = thisPin;
  currentAddressPinViewChangeCount = 7;
}

function isEnterKey(e)
{
  return (e.keyCode ? e.keyCode : e.which) == 13;
}

function showWaitImage()
{
  document.getElementById('WaitImage').src = "Images/wait.gif";
}
function hideWaitImage()
{
  document.getElementById('WaitImage').src = "Images/wait_stopped.gif";
}

function showDensityLegend()
{
  //alert('showdensitylegend');
  var legend = document.getElementById('DensityLegend');
  map.ShowControl(legend);
  //repositionDensityControl();
  //legend.style.visibility = "visible";
}
function hideDensityLegend()
{
  //alert('HidingDensity');
  try
  {
  
  //document.getElementById('DensityLegend').style.visibility = "hidden";
  map.HideControl(document.getElementById('DensityLegend'));
  }
  catch(e)
  {
    printVE_Exception(e);
    }
}
function repositionDensityControl()
{
  var mapImageHolder = document.getElementById("MapImageHolder");
  var width = parseInt(mapImageHolder.style.width.substr(0, mapImageHolder.style.width.length-2));
  var densityLegend = document.getElementById('DensityLegend');
  densityLegend.style.top = map.GetTop() + 5 + "px";
  densityLegend.style.left = map.GetLeft() + width - densityLegend.offsetWidth - 5 + "px";
  //printDebug("Left: " + map.GetLeft());
  //printDebug("Width: " + width);
  //printDebug("legendwidth: " +densityLegend.offsetWidth);
  //printDebug("left: " + densityLegend.style.left);
  
}

function initiateTipDisplay()
{
  repositionTip();
  startTipDisplay(document.getElementById('MapTipDiv'), document.getElementById('MapTipDiv'));
}

function toggleTipDisplay()
{
  var tipDiv = document.getElementById('MapTipDiv');
  var tipLink = document.getElementById('TipLink');
  if (tipDiv.style.visibility == "hidden")
  {
    startTipDisplay(document.getElementById('MapTipDiv'), document.getElementById('MapTipDiv'));
    tipLink.innerHTML = "Tip Display: On";
  }
  else
  {
    stopTipDisplay();
    tipLink.innerHTML = "Tip Display: Off";
  }
}

function repositionTip()
{
  var tipDiv = document.getElementById('MapTipDiv');
  var tipDivStyle = tipDiv.style;
  var image = document.getElementById('MapImageHolder');
  var imagePos = getAbsolutePosition(image);
  tipDivStyle.left = imagePos.left + "px";
  tipDivStyle.top = imagePos.top + parseInt(_getElementById("MapHeight").value) - tipDiv.offsetHeight + "px";
  //tipDivStyle.visibility = "visible";
}

//YAHOO.util.Event.on(window, "load", initiateTipDisplay);

function showCrimeGraph()
{
  var mapBounds = getMapBounds()
  var top = mapBounds.TopLeftLatLong.Latitude;
  var left = mapBounds.TopLeftLatLong.Longitude;
  var bottom = mapBounds.BottomRightLatLong.Latitude;
  var right = mapBounds.BottomRightLatLong.Longitude;
  
  var url = "CrimeCountGraph.aspx?" + _generateMapArgs(top, left, bottom, right);
  
  //window.location = url;
  window.open(url, "crimelist", "status=1, toolbar=0, location=0, menubar=1, scrollbars=1, width=550, height=450, resizable=1");
}

function showCrimeTrends()
{
  var mapBounds = getMapBounds();
  var top = mapBounds.TopLeftLatLong.Latitude;
  var left = mapBounds.TopLeftLatLong.Longitude;
  var bottom = mapBounds.BottomRightLatLong.Latitude;
  var right = mapBounds.BottomRightLatLong.Longitude;
  
  var url = "CrimeTrends.aspx?" + _generateMapArgsOffensePremises() + "&" + _generateMapArgsLatLongZoom(top, left, bottom, right);
  
  //window.location = url;
  window.open(url, "crimelist", "status=1, toolbar=0, location=0, menubar=1, scrollbars=1, width=850, height=650, resizable=1");
}

function showCrimeList()
{
  if (currentCrimeCount > 1500)
    alert("There are too many crimes to display in a table.  Please limit your view to less than 1500 crimes.");
  else if (currentCrimeCount == 0 || !anyOffensesChecked() || !anyPremisesChecked())
    alert("There are no visible crimes to list.");
  else
  {
    var mapBounds = getMapBounds();
    var top = mapBounds.TopLeftLatLong.Latitude;
    var left = mapBounds.TopLeftLatLong.Longitude;
    var bottom = mapBounds.BottomRightLatLong.Latitude;
    var right = mapBounds.BottomRightLatLong.Longitude;

    var url = "CrimeList.aspx?" + _generateMapArgs(top, left, bottom, right);
    
    //window.location = url;
    window.open(url, "crimelist", "status=1, toolbar=0, location=0, menubar=1, scrollbars=1, width=680, height=400, resizable=1");
  } 
}

function showNonGeocoded()
{
  var url = "ListNonGeocoded.aspx?" + _generateMapArgsCrimeSetup();
  
  //window.location = url;
  window.open(url, "crimelist", "status=1, toolbar=0, location=0, menubar=1, scrollbars=1, width=680, height=400, resizable=1");
}

function anyOffensesChecked()
{
  for (var i = 0; i < getNumOffenses(); i++)
  {
    var checkBox = _getElementById("OffenseList_"+i);
    if (checkBox.checked)
      return true;
  }
  return false;
}

function anyPremisesChecked()
{
  for (var i = 0; i < getNumPremises(); i++)
  {
    if (document.getElementById("Premises"+i).checked)
      return true;
  }
  return false;
}

function getAbsolutePosition(obj)
{
  var pos = new Object();
  pos.left = 0;
  pos.top = 0;
	if( document.all)
	{
		var element = obj;

		do
		{
			pos.left += element.offsetLeft;
			pos.top += element.offsetTop;

		}
		while( (element = element.offsetParent))
	}
	else
	{
		pos.left = obj.x;
		pos.top = obj.y;
	}
	return pos;
}
