//Core functions -- Javascript Ninjas only!
//V6 - 07/30/09 [Eric]
//----------------------------------------
dojo.require("esri.map");
dojo.require("esri.tasks.identify");
dojo.require("esri.tasks.query");
dojo.require("esri.tasks.find");
dojo.require("esri.toolbars.draw");
dojo.require("esri.toolbars.navigation");

dojo.require("dojo.parser");
dojo.require("dojo.data.ItemFileReadStore");

dojo.require("dojox.layout.ResizeHandle"); 

dojo.require("dijit.ColorPalette");
dojo.require("dijit.Dialog");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.CheckBox");
dojo.require("dijit.form.Form");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dijit.form.ValidationTextBox");
dojo.require("dijit.layout.AccordionContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.Toolbar");


//FIX for 1.4
if ( esri.version === 1.4 ){
  var __oldSymFn = esri.symbol.fromJson;

  esri.symbol.fromJson = function(j){
    var s = __oldSymFn(j);
    if (s == null) return null;
    s.type = s.declaredClass.split(".").pop().toLowerCase();
    return s;
  };
}


var map, maplayer, aeriallayer, navTB, pickerTb, geometryService;
var selectionExtent = null, selectedParcelID = -1;
var ListCacheCaption, ListCacheBody;
var LayerBlockList = [];
var URLPinList = "";
var MapSelectedParcelID = -1;
var MapLayers = null;
var MapAerials = null;

var measureStage = ""; // either "", "STARTED", "DRAWING", "ENDDED"
var extentsMapCoord = null, extentsWorldCoord = null;
var baseURL = "http://resources.mygisonline.com/";

var _lastTool = "pan";
var _multiselect = false;
var _isShiftDown = false;
var _mouseCoordType = "NATIVE";
var _pickerFunction = null;
var _MapLayersLoaded = 0;
var _graphicsFeatures = [];
var _graphicsMarkup = [];
var _graphicsTemp = [];
var _sideBarState = "EXPANDED";

var _colorFill = "#FFFFFF";
var _colorOutline = "#0000AA";
var _colorFont = "#000000";


//Initial and Setup Functions Start
//-----------------------------
function init() {
  dojo.parser.parse(dojo.byId("wrapper"));
  //dojo.parser.parse();
    
  esri.config.defaults.io.proxyUrl = "proxy.php";
  esri.config.defaults.io.alwaysUseProxy = true;
  //esri.config.defaults.map.zoomDuration = 200; //time in milliseconds; default is 250
  //esri.config.defaults.map.zoomRate = 20; //refresh rate of zoom animation; default is 25
  //esri.config.defaults.map.panDuration = 200; //time in milliseconds; default panDuration:250
  //esri.config.defaults.map.panRate = 20; //refresh rate of zoom animation; default panRate:25
  
  if (typeof(MouseCoordType) !== 'undefined') {
    _mouseCoordType = MouseCoordType;
  }
  
  if (typeof(MapGraphics) !== 'undefined') {
    for(var r = 0; r < MapGraphics.length; r++) {
    _graphicsMarkup.push(new esri.Graphic(MapGraphics[r]));
  }
  }  
  
  //Setup the Map Layers
  maplayer = new esri.layers.ArcGISDynamicMapServiceLayer(MapServiceURL, {useMapImage:false});
  if( dojo.isIE && dojo.isIE < 7 ){
    maplayer.setImageFormat("gif");
  } else {
    maplayer.setImageFormat("png32");
  }
  dojo.connect(maplayer, "onUpdate", hideMapLoading);
  dojo.connect(maplayer, "onError", function(error){
  dojo.byId('siteloading').innerHTML = '<img src="'+baseURL+'images/warning.png" style="float: left;"><p class=\'aligntext\'><b>Website is currently in maintenance</b><br><br>(Details: ' + error.details + ')</p>';
  hideControl("wrapper");
  });
  
  if (maplayer.loaded) {
    setupQuery();
  } else {
  dojo.connect(maplayer, "onLoad", setupQuery);
  }
    
  //Kill mouse selection on overlay elements:
  disableSelection('mapscaleinfo');
  disableSelection('mapuserinfo');
  disableSelection('mapactivelayer');
  disableSelection('mapcursorinfo');
  disableSelection('mapinfobar');
  disableSelection('mapscaletxt');
  disableSelection('maploading');
}

function setupQuery(layer) {        
  if (maplayer.visibleLayers.length == 0) return;
  
  if (URLPinList != '') {
    
    processQuery("IN ('" + URLPinList.replace(/,/g, '\',\'') + "')", null, null, 0, function(featureSet) {
      if (featureSet.features.length) {
        selectionExtent = getExtents(featureSet);
        
        if (selectionExtent != null) {
          MapExtentXMin = selectionExtent.xmin;
          MapExtentYMin = selectionExtent.ymin;
          MapExtentXMax = selectionExtent.xmax;
          MapExtentYMax = selectionExtent.ymax;
        }
      }
      
      setupMap();
    });
    
  } else {
    setupMap();
  }
}

function setupMap() {
  //Setup the Geometry Service
  geometryService = new esri.tasks.GeometryService(GeometryServiceURL);
  dojo.connect(geometryService, "onBufferComplete", function(graphics) { 
    var symbol = new esri.symbol.SimpleFillSymbol("none", new esri.symbol.SimpleLineSymbol("dashdot", new dojo.Color([255,0,0]), 2), new dojo.Color([255,255,0,0.25]));
    var graphic = new esri.Graphic(graphics[0].geometry,symbol);
  
    _graphicsTemp.push(graphic);
  
    refreshGraphics();
    
    processQuery(null, esri.tasks.Query.SPATIAL_REL_INTERSECTS, graphics[0].geometry, 0, showResults);
  });
  dojo.connect(geometryService, "onProjectComplete", function(graphics) {
    extentsWorldCoord = graphics[0].geometry;
    updateMapScale();
  });   
 

  //Setup the Map Service
  var customExtent = new esri.geometry.Extent(MapExtentXMin, MapExtentYMin, MapExtentXMax, MapExtentYMax, new esri.SpatialReference({"wkid": MapWKID}));

  if ((typeof(AerialServiceURL) !== 'undefined') && (dojo.byId("mapinfobar"))) {
    map = new esri.Map("map", {extent:customExtent});
  } else {
    map = new esri.Map("map", {extent:customExtent, slider:false, nav:false });
  }
  
  map.disableClickRecenter();
  
  dojo.connect(map, "onZoom", showMapLoading);
  dojo.connect(map, "onPanEnd", showMapLoading);
  dojo.connect(map, "onLoad", function() {    
  
    //Add Map Events
  dojo.connect(map, "onKeyDown", function(keyEvent) {
    if ((keyEvent.keyCode == 16)||(keyEvent.keyCode == 17)){ 
      _isShiftDown = true;
      dojo.stopEvent(keyEvent);
    }
  });
  
  dojo.connect(map, "onKeyUp", function(keyEvent) {
    if ((keyEvent.keyCode == 16)||(keyEvent.keyCode == 17)){ 
      _isShiftDown = false;
      dojo.stopEvent(keyEvent);
    }
  }); 
  
  dojo.connect(map, "onMouseMove", updateMouseCoords);
  
  dojo.connect(map, "onMouseDrag", updateMouseCoords);
  
  dojo.connect(map, "onMouseOut", hideMouseCoords);
  
  dojo.connect(map, "onMouseDown", function(evt){
    if (measureStage == "STARTED") {
      measureStage = "DRAWING";
      updateUserInfo("Double-Click on the map to end Measuring", true);
    }
  });
  
  dojo.connect(window, "onresize", function(){  
    map.reposition();
  });
  
  pickerTb = new esri.toolbars.Draw(map);
    dojo.connect(pickerTb, "onDrawEnd", function(geometry) {
      _pickerFunction(geometry);
    });
    
    navTB = new esri.toolbars.Navigation(map);
    dojo.connect(navTB, "onExtentHistoryChange", extentHistoryChangeHandler);

    activateTool(_lastTool);   

    setupMapLayers();
    
    if (dojo.byId("disclaimer")) {
      if(window.top==window){
        if (document.cookie.indexOf("readDisclaimer=" + MapServiceURL) == -1) {
          document.cookie = "readDisclaimer=" + MapServiceURL + ";" + document.cookie;
          dijit.byId('disclaimer').show();
        }
      }
    }
    
    if (URLPinList != '') {
      //build query filter for PIN
      processQuery("IN ('" + URLPinList.replace(/,/g, '\',\'') + "')", null, null, 0, showResults);
    }
        
    hideControl("siteloading");
    showControl("wrapper", 1, 1000);
    
    if (dojo.byId("mapinfobar")) {
      updateMapScale();
      showControl("mapinfobar", 0.7, 500);
      showControl("mapcursorinfo", 1, 500);
      showControl("mapscaleinfo", 1, 500); 
      showControl("mapscaletxt", 1, 500);   
    }
      
    extentHistoryChangeHandler();
    refreshGraphics();
  });
  
  showMapLoading();

  //Aerial Layer:
  if (typeof(AerialService) !== 'undefined') {
    
    AerialServiceURL = "/ArcGIS/rest/services/" + AerialService + "/MapServer";
    
    if (typeof(AerialServiceLevels) !== 'undefined') {
      aeriallayer = new esri.layers.ArcGISTiledMapServiceLayer(AerialServiceURL, {visible: ShowInitialAerials, tileServers: ["http://cache.mygisonline.com/"+AerialService], displayLevels:AerialServiceLevels});
    } else {
      aeriallayer = new esri.layers.ArcGISTiledMapServiceLayer(AerialServiceURL, {visible: ShowInitialAerials, tileServers: ["http://cache.mygisonline.com/"+AerialService]});
    }
  
  } else if (typeof(AerialServiceURL) !== 'undefined') {

    if (typeof(AerialServiceLevels) !== 'undefined') {
      aeriallayer = new esri.layers.ArcGISTiledMapServiceLayer(AerialServiceURL, {visible: ShowInitialAerials, displayLevels:AerialServiceLevels});
    } else {
      aeriallayer = new esri.layers.ArcGISTiledMapServiceLayer(AerialServiceURL, {visible: ShowInitialAerials});
    }
  
  }
  
  if (typeof(aeriallayer) !== 'undefined') {
    if (MapAerials != null) {
      //Set Special visible layers
      if (MapAerials == "1") {
        aeriallayer.show();
      } else {
        aeriallayer.hide();
      }
    }     

    map.addLayer(aeriallayer);  
  }


  //Add Map Layer to Map
  if (MapLayers != null) {
    //Set Special visible layers
    maplayer.setVisibleLayers(MapLayers.split(','));
  }     

  map.addLayer(maplayer);
}

function setupMapLayers() {
  var layerList = {identifier:"value",
                  items: []};
  
  var al = dijit.byId('activeLayer');
  var te = dijit.byId('layersTab');
  if (te) {
    var content = "";

    for (var k=0; k < maplayer.layerInfos.length; k++) {
      var currentLayerInfo = maplayer.layerInfos[k];
      
      if (!isLayerBlocked(currentLayerInfo)) {
      
        if (!isLayerBlacklisted(currentLayerInfo)) {

          var strDisplayValue = "".pad(getLayerDepth(currentLayerInfo.id)*2, "-", 0) + currentLayerInfo.name;

          if (DefaultActiveLayer == currentLayerInfo.name) {
            DefaultActiveLayer = strDisplayValue;
          }

          if (typeof(IdentifyBlackList) !== 'undefined') {
            if (!(IdentifyBlackList.has(strDisplayValue))) {
              layerList.items.push({name:strDisplayValue, value:currentLayerInfo.id});
            }
          } else {
            layerList.items.push({name:strDisplayValue, value:currentLayerInfo.id});
          }

          content += "<div id=\"layerdiv" + currentLayerInfo.id + "\">";

          if (getLayerDepth(currentLayerInfo.id) > 0) {
            content += "<img src=\"" + baseURL + "images/tree_l.png\" style=\"padding-left:" + ((getLayerDepth(currentLayerInfo.id) - 1) * 15) + "px;\">";
          }

          content += "<input id=\"layer" + currentLayerInfo.id + "\" dojotype=\"dijit.form.CheckBox\" " + ((currentLayerInfo.defaultVisibility)?"checked=\"checked\" value=\"on\"":"") + " type=\"checkbox\" />";
          content += "<label for=\"layer" + currentLayerInfo.id + "\"> " + currentLayerInfo.name + "</label><br/>";
          content += "</div>";

        } else {
        
          content += "<input id=\"layer" + currentLayerInfo.id + "\" check=\"" + ((currentLayerInfo.defaultVisibility)?"true":"false") + "\" checked=\"" + ((currentLayerInfo.defaultVisibility)?"true":"false") + "\" type=\"hidden\" />";       
        
        }
        
      } else {
      
        content += "<input id=\"layer" + currentLayerInfo.id + "\" check=\"false\" checked=\"false\" type=\"hidden\" />";
        
      }
      
    }
    
    if (al) {
      al.store = new dojo.data.ItemFileReadStore({data: layerList});
    al.attr('displayedValue', DefaultActiveLayer);
    }
  
    
    if (typeof(aeriallayer) !== 'undefined') {
      var currentLayerInfo = aeriallayer.layerInfos[0];
      
      content += "<div id=\"aerialdiv" + currentLayerInfo.id + "\" style=\"padding-left:" + (getLayerDepth(currentLayerInfo.id) * 15) + "px;\">";
      content += "<input id=\"aerial" + currentLayerInfo.id + "\" dojotype=\"dijit.form.CheckBox\" " + ((ShowInitialAerials)?"checked=\"checked\" value=\"on\"":"") + " type=\"checkbox\" />";
      content += "<label for=\"aerial" + currentLayerInfo.id + "\"> " + AerialServiceLabel + "</label><br/>";
      content += "</div>";
    }

    content += "<p id=\"refreshButton\"><button dojoType=\"dijit.form.Button\" onclick=\"setVisibleMapLayers\" iconClass=\"btnRefreshIcon\">Refresh</button></p>";
        
    te.attr("content", "<div style=\"padding: 5px;\">" + content + "</div>");
  }
}

function ZoomToPolysFromPoints(selectionList) {
  var allpoints = new esri.geometry.Multipoint({"wkid": MapWKID});
  
  for (var i=0; i < selectionList.length; i++) {
    if (!(selectionList[i].attributes[ParcelPointFieldName] == undefined)) {
      if (selectionList[i].geometry.type == "point") {
        allpoints.addPoint(selectionList[i].geometry);
      }
    }
  }
  
  if (allpoints.points.length == 0) return;
  
  processQuery(null, esri.tasks.Query.SPATIAL_REL_INTERSECTS, allpoints, 0, function(featureSet) {
    if (featureSet.features.length) {
      if (featureSet.layerId == getLayerIDFromName(SearchLayerNames[0])) {
        var newSelectionExtent = getExtents(featureSet);

        addToMapSelection(featureSet);

        if (selectionExtent != null) { 
          selectionExtent = selectionExtent.union(newSelectionExtent);
        } else {
          selectionExtent = newSelectionExtent;
        }
      
    map.setExtent(selectionExtent);
      }
    }
  });
}
//-----------------------------
//Initial and Setup Functions End

//Utility Functions Start
//-----------------------------
String.prototype.pad = function(l, s, t){
    return s || (s = " "), (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length)
        + 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2))
        + this + s.substr(0, l - t) : this;
};

String.prototype.trim = function() {
  return this.replace(/^\s+|\s+$/g,"");
};

Array.prototype.has=function(v){
  for (i=0; i<this.length; i++){
    if (this[i]==v) return true;
  }
  return false;
};

Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

Number.prototype.formatMoney = function(c, d, t){
  var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
  return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};

function getExtents(featureSet) { 
  var thisExtent = null;
  
  if (featureSet.features) {
    for (var i=0; i < featureSet.features.length; i++) {
      //Get the current feature from the featureSet. (Query)
      var graphic = featureSet.features[i];
      
      if (graphic.geometry.type != "point") {
        var extents = graphic.geometry.getExtent();
        
        if (thisExtent != null) {
          thisExtent = thisExtent.union(extents);
        } else {
          thisExtent = extents;          
        }        
      }
    }
  } else {
    for (var i=0; i < featureSet.length; i++) {
      //Get the current feature from the featureSet. (Identify)
      var graphic = featureSet[i].feature;
      
      if (graphic.geometry.type != "point") {
        var extents = graphic.geometry.getExtent();
        
        if (thisExtent != null) {
          thisExtent = thisExtent.union(extents);
        } else {
          thisExtent = extents;          
        }        
      }
    }
  }
  
  if (thisExtent == null) { 
    return null;
  } else {
    return thisExtent.expand(1.5);
  }
}

function hasGraphic(gfxArray, graphic) {
  if (gfxArray != null) {
    for(var r = 0; r < gfxArray.length; r++) {
      if (dojo.toJson(gfxArray[r].geometry) == dojo.toJson(graphic.geometry)) {
      return r;
    }
    }
  }
  return -1;
}

function addToMapSelection(featureSet) {  
  if (featureSet.features) {
    for (var i=0; i < featureSet.features.length; i++) {
      //Get the current feature from the featureSet. (Query)
      var graphic = featureSet.features[i];
 
      graphic.setSymbol(getSymbol(graphic, false)); 
      graphic.layerId = featureSet.layerId;
      graphic.fieldAliases = featureSet.fieldAliases;
      graphic.value = featureSet.features[i].attributes[featureSet.displayFieldName];
    
    var intPos = hasGraphic(_graphicsFeatures, graphic);
    
    if (intPos == -1) {
    //Add to selection
    _graphicsFeatures.push(graphic);    
    } else {
    //Remove original (toggling effect)
    _graphicsFeatures.remove(intPos);
    }
    }
  } else {
    for (var i=0; i < featureSet.length; i++) {
      //Get the current feature from the featureSet. (Identify)
      var graphic = featureSet[i].feature;
       
      graphic.setSymbol(getSymbol(graphic, false));
    graphic.layerId = featureSet[i].layerId;
      graphic.value = featureSet[i].value;
    
    var intPos = hasGraphic(_graphicsFeatures, graphic);
    
    if (intPos == -1) {
    //Add to selection
    _graphicsFeatures.push(graphic);    
    } else {
    //Remove original (toggling effect)
    _graphicsFeatures.remove(intPos);
    }
    }
  }

  refreshGraphics();  
}

function refreshGraphics() {
  if (!map.graphics) return;
  
  map.graphics.clear();
  
  //Add Features Graphics to Map
  for(var r = 0; r < _graphicsFeatures.length; r++) {
    map.graphics.add(_graphicsFeatures[r]);
  }
  
  //Add Markup Graphics to Map
  for(var r = 0; r < _graphicsMarkup.length; r++) {
    map.graphics.add(_graphicsMarkup[r]);
  }
  
  //Add Temp Graphics to Map
  for(var r = 0; r < _graphicsTemp.length; r++) {
    map.graphics.add(_graphicsTemp[r]);
  }
  
  _graphicsTemp = [];
} 

function updateMapScale() {
  if (dojo.byId("mapscaletxt")) {
  //Get Map Extent and Scale
  var me = map.extent;
  var scale = (me.getWidth() / dojo.byId("map").clientWidth) * 96;
    
  //Update Map Scale Panel
  dojo.byId("mapscaletxt").innerHTML = scale.toFixed(0) + " Feet";
  }
}

function updateMouseCoords(evt) {
  dojo.stopEvent(evt);
  
  if((!ShowMouseCoords) || (!dojo.byId("mapcursorinfo"))) return;

    //Get mapPoint from event
    var mp = evt.mapPoint;
    
    if (((_mouseCoordType == "WORLD")||(_mouseCoordType == "WORLDDMS"))&&(extentsWorldCoord != null)) {
      var xmaprange = (extentsMapCoord.xmax - extentsMapCoord.xmin);
      var ymaprange = (extentsMapCoord.ymax - extentsMapCoord.ymin);    
      var xworldrange = (extentsWorldCoord.xmax - extentsWorldCoord.xmin);
      var yworldrange = (extentsWorldCoord.ymax - extentsWorldCoord.ymin);

      var xmappct = (mp.x - extentsMapCoord.xmin) / xmaprange;
      var ymappct = (mp.y - extentsMapCoord.ymin) / ymaprange;

      var xworldcoord = (xworldrange * xmappct) + extentsWorldCoord.xmin;
      var yworldcoord = (yworldrange * ymappct) + extentsWorldCoord.ymin;
      
      if (_mouseCoordType == "WORLDDMS") {
        //Update Mouse Cursor World Coordinates (DMS)
        var signlat = 1;
        var signlon = 1;
        var latAbs=0;
        var lonAbs=0;
        var deglat=' ';
        var deglon=' ';

        if(yworldcoord < 0)  { signlat = -1; }
        latAbs = Math.abs( Math.round(yworldcoord * 1000000.));
        
        if(xworldcoord < 0)  { signlon = -1; }
        lonAbs = Math.abs(Math.round(xworldcoord * 1000000.));

        
        deglat = ((Math.floor(latAbs / 1000000) * signlat) + '&deg; ' + Math.floor(  ((latAbs/1000000) - Math.floor(latAbs/1000000)) * 60)  + '\' ' +  ( Math.floor(((((latAbs/1000000) - Math.floor(latAbs/1000000)) * 60) - Math.floor(((latAbs/1000000) - Math.floor(latAbs/1000000)) * 60)) * 100000) *60/100000 ).toFixed(2) + '&quot;'  );
        deglon = ((Math.floor(lonAbs / 1000000) * signlon) + '&deg; ' + Math.floor(  ((lonAbs/1000000) - Math.floor(lonAbs/1000000)) * 60)  + '\' ' +  ( Math.floor(((((lonAbs/1000000) - Math.floor(lonAbs/1000000)) * 60) - Math.floor(((lonAbs/1000000) - Math.floor(lonAbs/1000000)) * 60)) * 100000) *60/100000 ).toFixed(2) + '&quot;'  );

        
        dojo.byId("mapcursorinfo").innerHTML = "Cursor: " + deglat + ", " + deglon;  
      } else {
        //Update Mouse Cursor World Coordinates (Decimal)
        dojo.byId("mapcursorinfo").innerHTML = "Mouse Position: " + xworldcoord.toFixed(4) + ", " + yworldcoord.toFixed(4);  
      }
      
    } else {
    
      //Update Mouse Cursor Native Coordinates
      dojo.byId("mapcursorinfo").innerHTML = "Mouse Position: " + mp.x.toFixed(1) + ", " + mp.y.toFixed(1);  
      
    } 
}

function hideMouseCoords() {
  if (dojo.byId("mapcursorinfo")) dojo.byId("mapcursorinfo").innerHTML = "";
}

function updateResultsTab(caption, content) {
  ListCacheCaption = caption;
  ListCacheBody = content;
  
  var te = dijit.byId('mainTabContainer');   
  
  if (te) {
    var childrenTabs = te.getChildren();
    
    for( var t = 0; t < childrenTabs.length; t++) {
      if (childrenTabs[t].id == "resultsTab") {
        childrenTabs[t].controlButton.attr('label', "<img src='http://resources.mygisonline.com/images/results.png' style='margin-bottom: -2px;'> " + caption);
        childrenTabs[t].attr("content", "<div style=\"padding: 5px;\">" + content + "</div>");
        te.selectChild(childrenTabs[t]);
        return;
      }
    }
  } else {
    dojo.byId("resultsTab").innerHTML = "<div style=\"padding: 5px;\">" + content + "</div>";
  }
}

function updateUserInfo(caption, showIcon) {
  if (dojo.byId("mapuserinfo")) {
  
    if (caption == "") {
      
      //Hide
      dojo.byId("mapuserinfo").innerHTML = "";
      hideControl('mapuserinfo', 500);
      
    } else {
      
      //Show
      if (showIcon) {
        dojo.byId("mapuserinfo").innerHTML = "<img src=\"" + baseURL + "images/information.png\" style=\"float: left;\"/><p class=\"aligntext\">" + caption + "</p>";
      } else { 
        dojo.byId("mapuserinfo").innerHTML = caption;
      }
      showControl('mapuserinfo', 0.85, 500);
      
    }
  }
}

function glowGeometry(index) {
  if(map.graphics.graphics == null) return;
  if(map.graphics.graphics.length == 0) return;
    
  for (var i=0; i < _graphicsFeatures.length; i++) {
    var selected = map.graphics.graphics[i];
    
    if(i == index) {
      selected.setSymbol(getSymbol(selected, true)); //Highlight this graphic
    } else {
      selected.setSymbol(getSymbol(selected, false)); //UnHighlight this graphic
    } 
  }
}

function getLayerIDFromName(name) {
  for (var k=0; k < maplayer.layerInfos.length; k++) {
    var currentLayerInfo = maplayer.layerInfos[k];

    if (currentLayerInfo.name == name) {
      return currentLayerInfo.id;
    }
  }
  
  return -1;
}

function getLayerDepth(layerid) {
  var depth = 0;
  
  for (var k=0; k < maplayer.layerInfos.length; k++) {
    var currentLayerInfo = maplayer.layerInfos[k];
    
    if (currentLayerInfo.id == layerid) {
      
      if (currentLayerInfo.parentLayerId > -1) {
        depth++;
        depth += (getLayerDepth(currentLayerInfo.parentLayerId));
      }
      
    }    
  }
  
  return depth;
}

function getLayerVisible(layerid) {
  var isVisible = true;
  
  for (var k=0; k < maplayer.layerInfos.length; k++) {
    var currentLayerInfo = maplayer.layerInfos[k];
    
    if (currentLayerInfo.id == layerid) {
           
      if (currentLayerInfo.parentLayerId == -1) {
        if (dojo.byId('layer' + currentLayerInfo.id).check) {
          return getBoolean(dojo.byId('layer' + currentLayerInfo.id).check);       
        } else {  
          return getBoolean(dojo.byId('layer' + currentLayerInfo.id).checked);
        }
      } else {
        if (dojo.byId('layer' + currentLayerInfo.id).check) {
          if (!getBoolean(dojo.byId('layer' + currentLayerInfo.id).check)) return false;
        } else {        
          if (!getBoolean(dojo.byId('layer' + currentLayerInfo.id).checked)) return false;
        }
        
        isVisible = getLayerVisible(currentLayerInfo.parentLayerId);
        if (!isVisible) return false;
      }
      
    }    
  }
  
  return isVisible;
}

function getVisibleMapLayers() {
  var visibleLayers = [];

  for (var k=0; k < maplayer.layerInfos.length; k++) {
    var currentLayerInfo = maplayer.layerInfos[k];
    if (currentLayerInfo.subLayerIds == null) {
      if (getLayerVisible(currentLayerInfo.id)) {
        visibleLayers.push(currentLayerInfo.id);
      }
    }
  }
  
  return visibleLayers;
}

function setVisibleMapLayers() {
  showMapLoading();

  var visibleLayers = [];

  for (var k=0; k < maplayer.layerInfos.length; k++) {
    var currentLayerInfo = maplayer.layerInfos[k];
    if (currentLayerInfo.subLayerIds == null) {
      if (getLayerVisible(currentLayerInfo.id)) {
        visibleLayers.push(currentLayerInfo.id);
      }
    }
  }

  maplayer.setVisibleLayers(visibleLayers);
  
  
  if (typeof(aeriallayer) !== 'undefined') {   
    var currentLayerInfo = aeriallayer.layerInfos[0];
    
    if (getBoolean(dojo.byId('aerial' + currentLayerInfo.id).checked)) {
      aeriallayer.show();
    } else {
      aeriallayer.hide();
    }
  }
}

function isLayerBlacklisted(layerInfo) {
  if (dojo.indexOf(LayerBlackList, layerInfo.name) > -1) return true;
        
  if (layerInfo.parentLayerId > -1) {
    for (var k=0; k < maplayer.layerInfos.length; k++) {
      var currentLayerInfo = maplayer.layerInfos[k];

      if (currentLayerInfo.id == layerInfo.parentLayerId) {
        return isLayerBlacklisted(currentLayerInfo);
      }
    }
  }
  
  return false;
}

function isLayerBlocked(layerInfo) {
  for(var x = 0; x < LayerBlockList.length; x++){
    if(LayerBlockList[x] == layerInfo.id) {
    
      for(var y = 0; y < LayerWhiteList.length; x++){
        if(LayerWhiteList[y] == layerInfo.id) {
          return false;
        }
      }

      return true;
    }
  }

  if (layerInfo.parentLayerId > -1) {
    for (var k=0; k < maplayer.layerInfos.length; k++) {
      var currentLayerInfo = maplayer.layerInfos[k];

      if (currentLayerInfo.id == layerInfo.parentLayerId) {
        return isLayerBlocked(currentLayerInfo);
      }
    }
  }
  
  return false;
}

function getBoolean(variable) {
  var toReturn;

  if(variable != null) {
    switch(typeof(variable)) {
      case 'boolean':
        return variable;
        break;
      case 'number':
        if(variable == 0)
          toReturn = false;
        else toReturn = true;
        break;
      case 'string':
        if(variable == "true")
          toReturn = true;
        else if(variable == "false")
          toReturn = false;
        else if(variable.length > 0)
          toReturn = true;
        else if(variable.length == 0)
          toReturn = false;
        break;
    }

    return toReturn; 
  }
}

function getSymbol(graphic, hilite) {  
  if (hilite) {  
    switch (graphic.geometry.type) {
      case "point": return symbolHilitePoint;
      case "polyline": return symbolHilitePolyline;
      case "polygon": return symbolHilitePolygon;
      case "multipoint": return symbolHiliteMultipoint;
    } 
  } else {
    switch (graphic.geometry.type) {
      case "point": return symbolNormalPoint;
      case "polyline": return symbolNormalPolyline;
      case "polygon": return symbolNormalPolygon;
      case "multipoint": return symbolNormalMultipoint;
    }
  }
}


function disableSelection(elementid) {
  var element = dojo.byId(elementid);
  if(!element) return;
  
  dojo.connect(element, "onselectstart", function(e) {return false;});
  dojo.connect(element, "ondragstart", function(e) {return false;});  
  dojo.connect(element, "onmouseover", function(e) {return false;});

  element.unselectable = "on";
  element.style.MozUserSelect = "none";
  element.style.cursor = "default";
}


function processQuery(strWhere, spatialRelationship, geometry, searchIndex, finishFunction){
  var SearchLayerName = SearchLayerNames[searchIndex];
  var SearchFieldName = SearchFieldNames[searchIndex];
  var SearchFields = SearchFieldsArray[searchIndex];
    
  var queryParams = new esri.tasks.Query();
  queryParams.returnGeometry = true;
  queryParams.outFields = SearchFields;
  
  if (strWhere) queryParams.where = SearchFieldName + " " + strWhere;
  
  if (spatialRelationship) queryParams.spatialRelationship = spatialRelationship;
  
  if (geometry) queryParams.geometry = geometry;

  var initqueryTask = new esri.tasks.QueryTask(MapServiceURL + "/" + getLayerIDFromName(SearchLayerName));  
  dojo.connect(initqueryTask, "onComplete", function(featureSet) {
    if ((!featureSet.features.length) && ((SearchLayerNames.length-1) > searchIndex)) {
      processQuery(strWhere, spatialRelationship, geometry, searchIndex+1, finishFunction);
    } else {
      featureSet.layerId = getLayerIDFromName(SearchLayerName);
      finishFunction(featureSet);
    }
  });
  dojo.connect(initqueryTask, "onError", function(error) {
    finishFunction(new esri.tasks.FeatureSet());
  });  

  initqueryTask.execute(queryParams);
}

function toggleControl(element) {
  if (dojo.byId(element).style.display == "none") {
    showControl(element, 1, 200);
  } else {
    hideControl(element);
  }
}

function showControl(element, opacity, duration) {
  if (!dojo.byId(element)) return;
    
  dojo.anim(element, {opacity: opacity}, duration);
  dojo.style(element,"display","block");
  dojo.style(element,"visibility","visible");
}

function hideControl(element, duration) {
  if (!dojo.byId(element)) return;
  
  dojo.style(element,"opacity","0");
  dojo.style(element,"display","none");
}
//-----------------------------
//Utility Functions End

function showMapLoading(){
  _MapLayersLoaded = 0;
  showControl("maploading", 1, 200);  
  //if ((typeof(AerialServiceURL) !== 'undefined') && (dojo.byId("mapinfobar"))) {
  //  map.hideZoomSlider();
  //}
}

function hideMapLoading(){ 
  var MapLayerCount = 0;
  _MapLayersLoaded++;
  
  for(var r = 0; r < map.layerIds.length; r++) {
    if ((map.getLayer(map.layerIds[r]).visible) && (map.getLayer(map.layerIds[r]).declaredClass == "esri.layers.ArcGISDynamicMapServiceLayer")) {
      MapLayerCount++;
    }
  }
  
  if (MapLayerCount == 0) return;
  
  if (_MapLayersLoaded == MapLayerCount) {
    
  dojo.query("img,div").
    forEach(function(node, idx, arr){
    if (node.filters) {
      if (node.style.filter.toLowerCase().indexOf('alpha(opacity=100') != -1) {
        node.style.filter = "";
      }
    }
    });
   
    hideControl("maploading", 200);
    //if ((typeof(AerialServiceURL) !== 'undefined') && (dojo.byId("mapinfobar"))) {
    //  map.showZoomSlider();
    //}   
    //map.reposition();
    _MapLayersLoaded = 0;
  }    
}

//Toolbar Events Start
//-----------------------------
function activateTool(toolname) {

  measureStage = "";

  if (dojo.byId("zoomin")) dojo.byId("zoomin").style.border = "none";
  if (dojo.byId("zoomout")) dojo.byId("zoomout").style.border = "none";
  if (dojo.byId("pan")) dojo.byId("pan").style.border = "none";

  if (dojo.byId("select")) dojo.byId("select").style.border = "none";
  if (dojo.byId("identify")) dojo.byId("identify").style.border = "none";
  if (dojo.byId("measure")) dojo.byId("measure").style.border = "none";  
  if (dojo.byId("buffer")) dojo.byId("buffer").style.border = "none";
  if (dojo.byId("graphicmarker")) dojo.byId("graphicmarker").style.border = "none";  
  if (dojo.byId("graphictext")) dojo.byId("graphictext").style.border = "none";  
  if (dojo.byId("zillow")) dojo.byId("zillow").style.border = "none";  
  if (dojo.byId("geospan")) dojo.byId("geospan").style.border = "none";  
 
  updateUserInfo("", false);
  hideControl("mapactivelayer", 500);
  
  map.disableMapNavigation();

  pickerTb.deactivate();
  navTB.deactivate();


  switch(toolname) {
    
    case "none":
      break;
    
    
    case "measure":
      if (dojo.byId("measure")) {
        dojo.byId("measure").style.border = "1px solid red";
          
    dijit.byId('divMeasureSettings').show();
      }
      break;
      
      
    case "buffer":
      if (dojo.byId("buffer")) {
        dojo.byId("buffer").style.border = "1px solid red";
    
    dijit.byId('btnBufferSelected').attr('disabled', (_graphicsFeatures.length == 0));
    dijit.byId('divBufferSettings').show();

        map.enableMapNavigation();
      }
      break;
      
    
    case "identify":      
      _lastTool = "identify";
      if (dojo.byId(_lastTool)) {
        dojo.byId(_lastTool).style.border = "1px solid red";

        if (ShowActiveLayer) {
          showControl("mapactivelayer", 0.85, 500);
        }

        _pickerFunction = processIdentify;
        pickerTb.activate(esri.toolbars.Draw.POINT);

        map.enableMapNavigation();
      }
      break;
      
      
    case "select":      
      _lastTool = "select";
      if (dojo.byId(_lastTool)) {
        dojo.byId(_lastTool).style.border = "1px solid red";

        _pickerFunction = processSelect;
        pickerTb.activate(esri.toolbars.Draw.EXTENT); 
    
    updateUserInfo("Draw box/pick point to select parcels (hold Ctrl for multiselect)", true);
      }
      break;
     
    
    case "graphictext":
      if (dojo.byId("graphictext")) {
        dojo.byId("graphictext").style.border = "1px solid red";
        
        _pickerFunction = processGraphicText;
        pickerTb.activate(esri.toolbars.Draw.POINT);
    
    dojo.query('#btnFontColor .dijitButtonText').style('backgroundColor', _colorFont);
          
        dijit.byId('divTxtSettings').show();
      }
      break;
     
    
    case "graphicmarker":
      if (dojo.byId("graphicmarker")) {
        dojo.byId("graphicmarker").style.border = "1px solid red";   
        
        _pickerFunction = processGraphicMarker;
        pickerTb.activate(esri.toolbars.Draw.POINT);
        
    dojo.query('#btnFillColor .dijitButtonText').style('backgroundColor', _colorFill);
    dojo.query('#btnOutlineColor .dijitButtonText').style('backgroundColor', _colorOutline);
    
        dijit.byId('divMarkerSettings').show();
      }
      break;
      
      
    case "zoomin":
      _lastTool = "zoomin";
      if (dojo.byId(_lastTool)) {
        dojo.byId(_lastTool).style.border = "1px solid red";

        navTB.activate(esri.toolbars.Navigation.ZOOM_IN);
      }
      break;
    
      
    case "zoomout":
      _lastTool = "zoomout";
      if (dojo.byId(_lastTool)) {
        dojo.byId(_lastTool).style.border = "1px solid red";

        navTB.activate(esri.toolbars.Navigation.ZOOM_OUT);
      }
      break;
    
      
    case "pan":
      _lastTool = "pan";
      if (dojo.byId(_lastTool)) {
        dojo.byId(_lastTool).style.border = "1px solid red";
      }
    map.enableMapNavigation();
      break;


    case "clear":
      clearResults();
      updateResultsTab("Results", "<img src='" + baseURL + "images/information.png' style=\"float: left;\"/><p class=\"aligntext\">No features selected</p>");
      activateTool(_lastTool);
      break;
    
    
    case "zoomnext":
      navTB.zoomToNextExtent();
      extentHistoryChangeHandler();
      activateTool(_lastTool);
      break;
      
      
    case "zoomprev":
      navTB.zoomToPrevExtent();
      extentHistoryChangeHandler();
      activateTool(_lastTool);
      break;      


    case "zillow":      
      if (dojo.byId("zillow")) {
        dojo.byId("zillow").style.border = "1px solid red";

        _pickerFunction = openZillowWindow;
        pickerTb.activate(esri.toolbars.Draw.POINT);

        map.enableMapNavigation();
      }
      break;
      
    
    case "geospan":      
      if (dojo.byId("geospan")) {
        dojo.byId("geospan").style.border = "1px solid red";

        _pickerFunction = openGeospanWindow;
        pickerTb.activate(esri.toolbars.Draw.POINT);

        map.enableMapNavigation();
      }
      break;
    
    
    default:
      activateCustomTool(toolname);
      break;
  }

}

function activateCustomTool(toolname) {
  //Function to override
}

function processMeasure(geometry) {
  _graphicsTemp.push(new esri.Graphic(geometry, new esri.symbol.SimpleFillSymbol()));

  refreshGraphics();

  measureStage = "ENDDED";
  
  var _strUnits = "Feet";
  var _intDigits = 2;
  
  if (geometry.type == "polygon") {
  
    //Figure out area
    geometryService.areasAndLengths([new esri.Graphic(geometry)], function(areasAndLengths) {
      
      var _area = areasAndLengths.areas[0];
      
      switch (dijit.byId("measureAreaUnits").value) {
        case "UNIT_ACRE":
          _area *= 0.0000229568411;
          _intDigits = 3;
          _strUnits = "Acres";
          break;        
        case "UNIT_FOOT":
          _strUnits = "sq. Feet";
          break;
        case "UNIT_METER":
          _area *= 0.09290304;
          _strUnits = "sq. Meters";
          break;
        case "UNIT_STATUTE_MILE":
          _area *= 0.000000035870064129935721;
          _intDigits = 6;
          _strUnits = "sq. Miles";
          break;
        case "UNIT_KILOMETER":
          _area *= 0.00000009290304;
          _intDigits = 6;
          _strUnits = "sq. Kilometers";
          break;
      }
      
      updateUserInfo("Measure Area: " + _area.toFixed(_intDigits) + " " + _strUnits, true);     
    });
    
  } else {
    
    //Figure out length
    var _length = 0.0;
    for (var i = 0; i < (geometry.paths[0].length - 1); i++) {
      var x1 = geometry.paths[0][i][0];
      var y1 = geometry.paths[0][i][1];
      var x2 = geometry.paths[0][i+1][0];
      var y2 = geometry.paths[0][i+1][1];

      var distance = Math.sqrt((x1 -= x2) * x1 + (y1 -= y2) * y1);

      _length += distance;
    }
    
    switch (dijit.byId("measureLinearUnits").value) {
      case "UNIT_METER":
        _length *= 0.3048;
        _strUnits = "Meters";
        break;
      case "UNIT_STATUTE_MILE":
        _length *= 0.000189393939;
        _intDigits = 4;
        _strUnits = "Miles";
        break;
      case "UNIT_KILOMETER":
        _length *= 0.0003048;
        _intDigits = 4;
        _strUnits = "Kilometers";
        break;
    }
    
    updateUserInfo("Measure Length: " + _length.toFixed(2) + " " + _strUnits, true);
    
  }
}

function processBuffer(geometry) {
  if ((geometry.length == 0) && (geometry.type == undefined)) {
    updateResultsTab("Results", "<img src='" + baseURL + "images/information.png' style=\"float: left;\"/><p class=\"aligntext\">No selected features to buffer from.</p>");
  return;
  }
  
  updateResultsTab("Results", "<img src='" + baseURL + "images/loader.gif' style=\"float: left;\"/><p class=\"aligntext\">Buffering features...</p>");
  
  var symbol = new esri.symbol.SimpleMarkerSymbol();
  

  //Setup the buffer Parameters
  var bufferParams = new esri.tasks.BufferParameters();
  bufferParams.unit = eval('esri.tasks.BufferParameters.' + dijit.byId('txtBufferUnits').value);
  bufferParams.unionResults = true;
  bufferParams.features = [];
  bufferParams.distances = [];
    
  if (geometry.length > 0) {
  //Array
  for (var i = 0; i < geometry.length; i++) {
    bufferParams.features.push(new esri.Graphic(geometry[i], symbol));
    bufferParams.distances.push(dojo.byId('bufferDistance').value);
  }
  } else {
    //Single
  bufferParams.features.push(new esri.Graphic(geometry, symbol));
  bufferParams.distances.push(dojo.byId('bufferDistance').value);
  }
  
  geometryService.buffer(bufferParams);
}

function processIdentify(geometry) { 
  if (!(getLayerVisible(dijit.byId("activeLayer").value))) {
  updateResultsTab("Results", "<img src='" + baseURL + "images/warning.png' style=\"float: left;\"/><p class=\"aligntext\">Layer <b>" + dijit.byId("activeLayer").textbox.value + "</b> is not visible to Identify.</p>");
  return;
  }
  
  _multiselect = _isShiftDown;
  
  if (!_multiselect) {
  updateResultsTab("Results", "<img src='" + baseURL + "images/loader.gif' style=\"float: left;\"/><p class=\"aligntext\">Identifying features...</p>");
  }
  
  //Setup the identify Parameters
  var identifyParams = new esri.tasks.IdentifyParameters();
  identifyParams.tolerance = 3;
  identifyParams.returnGeometry = true;
  identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
  identifyParams.width = map.width;
  identifyParams.height = map.height;
  identifyParams.geometry = geometry;
  identifyParams.mapExtent = map.extent;
  identifyParams.layerIds = [dijit.byId("activeLayer").value];
  
  var identify = new esri.tasks.IdentifyTask(MapServiceURL);
  identify.onComplete = SelectResults;
  identify.execute(identifyParams);
}

function processSelect(geometry) {
  if (!(getLayerVisible(getLayerIDFromName(SearchLayerNames[0])))) {
  updateResultsTab("Results", "<img src='" + baseURL + "images/warning.png' style=\"float: left;\"/><p class=\"aligntext\">Layer <b>" + SearchLayerNames[0] + "</b> is not visible to Select.</p>");
  return;
  }  
  
  _multiselect = _isShiftDown;
  
  if (!_multiselect) {  
    updateResultsTab("Results", "<img src='" + baseURL + "images/loader.gif' style=\"float: left;\"/><p class=\"aligntext\">Selecting parcels...</p>");
  }
  
  //Setup the select Parameters
  var selectParams = new esri.tasks.IdentifyParameters();
  selectParams.tolerance = 3;
  selectParams.returnGeometry = true;
  selectParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
  selectParams.width = map.width;
  selectParams.height = map.height;
  selectParams.layerIds = [getLayerIDFromName(SearchLayerNames[0])];
  selectParams.geometry = geometry;
  selectParams.mapExtent = map.extent;

  var select = new esri.tasks.IdentifyTask(MapServiceURL);
  select.onComplete = SelectResults;
  select.execute(selectParams);
}

function processGraphicMarker(geometry) {
  var markerSymbol = new esri.symbol.SimpleMarkerSymbol();

  switch (dijit.byId("markerStyle").value) {
      case "STYLE_CIRCLE":
          markerSymbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE);
          break;
      case "STYLE_CROSS":
          markerSymbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_CROSS);
          break;
      case "STYLE_DIAMOND":
          markerSymbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_DIAMOND);
          break;
      case "STYLE_SQUARE":
          markerSymbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
          break;
      case "STYLE_X":
          markerSymbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_X);
          break;
  }

  var markerOutlineSymbol = new esri.symbol.SimpleLineSymbol();

  switch (dijit.byId("markerOutlineStyle").value) {
      case "STYLE_SOLID":
          markerOutlineSymbol.setStyle(esri.symbol.SimpleLineSymbol.STYLE_SOLID);
          break;
      case "STYLE_DASH":
          markerOutlineSymbol.setStyle(esri.symbol.SimpleLineSymbol.STYLE_DASH);
          break;
      case "STYLE_DASHDOT":
          markerOutlineSymbol.setStyle(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT);
          break;
      case "STYLE_DASHDOTDOT":
          markerOutlineSymbol.setStyle(esri.symbol.SimpleLineSymbol.STYLE_DASHDOTDOT);
          break;
      case "STYLE_DOT":
          markerOutlineSymbol.setStyle(esri.symbol.SimpleLineSymbol.STYLE_DOT);
          break;
  }

  markerOutlineSymbol.setWidth(dojo.byId("txtMarkerOutlineWidth").value);
  markerOutlineSymbol.setColor(new dojo.Color(_colorOutline));
  markerSymbol.setOutline(markerOutlineSymbol);
  markerSymbol.setColor(new dojo.Color(_colorFill));
  markerSymbol.setSize(dojo.byId("txtMarkerSize").value);
  
  var newGraphic = new esri.Graphic(geometry, markerSymbol);
  
  _graphicsMarkup.push(newGraphic);
  
  refreshGraphics();

  activateTool(_lastTool);
}

function processGraphicText(geometry) {
  var myFont = new esri.symbol.Font();
  myFont.setFamily(dijit.byId("txtFontFamily").textbox.value);
  myFont.setSize(dojo.byId("txtFontSize").value);
  
  if (dijit.byId("btnFontItalic").checked) {
  myFont.setStyle(esri.symbol.Font.STYLE_ITALIC);
  } else {
  myFont.setStyle(esri.symbol.Font.STYLE_NORMAL);
  }
  
  if (dijit.byId("btnFontBold").checked) {
  myFont.setWeight(esri.symbol.Font.WEIGHT_BOLD);
  } else {
  myFont.setWeight(esri.symbol.Font.WEIGHT_NORMAL);
  }
  
  var symbol = new esri.symbol.TextSymbol(dojo.byId("mapText").value, myFont, new dojo.Color(_colorFont));

  if (dijit.byId("btnFontLeft").checked) {
  symbol.setAlign(esri.symbol.TextSymbol.ALIGN_START);
  }
  if (dijit.byId("btnFontCenter").checked) {
  symbol.setAlign(esri.symbol.TextSymbol.ALIGN_MIDDLE);
  }
  if (dijit.byId("btnFontRight").checked) {
  symbol.setAlign(esri.symbol.TextSymbol.ALIGN_END);
  }
    
  var newGraphic = new esri.Graphic(geometry, symbol);
  
  _graphicsMarkup.push(newGraphic);
  
  refreshGraphics();
  
  activateTool(_lastTool);
}
      
function showPrintDialog() {

  var pinlist = "";
   
  for (var i=0; i < _graphicsFeatures.length; i++) {
  
    var ParcelFieldName;

    if (_graphicsFeatures[i].geometry.type == "point") {
      ParcelFieldName = ParcelPointFieldName;
    } else {
      ParcelFieldName = ParcelPolyFieldName;
    }  
  
    if (!(_graphicsFeatures[i].attributes[ParcelFieldName] == undefined)) {
      if (pinlist != "") pinlist += ',';
      pinlist += _graphicsFeatures[i].attributes[ParcelFieldName];
    }
  }
  
  var layers = getVisibleMapLayers().join(',');
  var aerials = 0;
  
  if (typeof(aeriallayer) !== 'undefined') {   
    var currentLayerInfo = aeriallayer.layerInfos[0];
    
    if (getBoolean(dojo.byId('aerial' + currentLayerInfo.id).checked)) {
      aerials = 1;
    }
  }
  
  var gfx = [];
  for(var r = 0; r < _graphicsMarkup.length; r++) {
    gfx.push(_graphicsMarkup[r].toJson());
  }
  
  dojo.rawXhrPost({
          url: PrintPage,
          postData: 'pin=' + pinlist + '&selectedparcelid=' + selectedParcelID + '&extent=' + map.extent.xmin + ',' + map.extent.ymin + ',' + map.extent.xmax + ',' + map.extent.ymax + '&layers=' + layers + '&aerials=' + aerials + '&graphics=' + dojo.toJson(gfx),
          timeout: 1000,
          load: function(response, ioArgs) {
                window.open(PrintPage);
                return response;
          },
          error: function(response, ioArgs) {
                return response;
          }
  });

}

function openHelpWindow() {
  window.open(baseURL + "help/Index.htm");
}

function openZillowWindow(geometry) {  
  if ((_mouseCoordType == "NATIVE") && (extentsWorldCoord == null)) {
    geometryService.project([new esri.Graphic(extentsMapCoord)], new esri.SpatialReference({"wkid" : 4326}), function(graphics) {
      extentsWorldCoord = graphics[0].geometry;
      openZillowWindow(geometry);
    });
    return;
  }

  var xmaprange = (extentsMapCoord.xmax - extentsMapCoord.xmin);
  var ymaprange = (extentsMapCoord.ymax - extentsMapCoord.ymin);    
  var xworldrange = (extentsWorldCoord.xmax - extentsWorldCoord.xmin);
  var yworldrange = (extentsWorldCoord.ymax - extentsWorldCoord.ymin);

  var xmappct = (geometry.x - extentsMapCoord.xmin) / xmaprange;
  var ymappct = (geometry.y - extentsMapCoord.ymin) / ymaprange;

  var sLong = (xworldrange * xmappct) + extentsWorldCoord.xmin;
  var sLat = (yworldrange * ymappct) + extentsWorldCoord.ymin;
  
  //http://www.zillow.com/homes/map/47.614528,-122.339465,47.613557,-122.342515_rect/
  window.open("http://www.zillow.com/homes/map/" + (sLat+0.0005) + "," + (sLong+0.0005) + "," + (sLat-0.0005) + "," + (sLong-0.0005) + "_rect/", "_zillow");
  
  if (_mouseCoordType == "NATIVE") extentsWorldCoord = null;  
}

function openGeospanWindow(geometry) {
  if ((_mouseCoordType == "NATIVE") && (extentsWorldCoord == null)) {
    geometryService.project([new esri.Graphic(extentsMapCoord)], new esri.SpatialReference({"wkid" : 4326}), function(graphics) {
      extentsWorldCoord = graphics[0].geometry;
      openGeospanWindow(geometry);
    });
    return;
  }
  
  var xmaprange = (extentsMapCoord.xmax - extentsMapCoord.xmin);
  var ymaprange = (extentsMapCoord.ymax - extentsMapCoord.ymin);    
  var xworldrange = (extentsWorldCoord.xmax - extentsWorldCoord.xmin);
  var yworldrange = (extentsWorldCoord.ymax - extentsWorldCoord.ymin);

  var xmappct = (geometry.x - extentsMapCoord.xmin) / xmaprange;
  var ymappct = (geometry.y - extentsMapCoord.ymin) / ymaprange;

  var sLong = (xworldrange * xmappct) + extentsWorldCoord.xmin;
  var sLat = (yworldrange * ymappct) + extentsWorldCoord.ymin;
  
  //http://kaneil.mygisonline.com/GVPro/ViewerA.htm?region=11&lat=42.12004764258458&lon=-88.25786067259155&rev=1&res=2
  //window.open(GeospanURL + "&lat=" + sLat + "&lon=" + sLong, "_geospan");
    
  dijit.byId('geospanviewer').setContent("<iframe src=\"" + GeospanURL + "&lat=" + sLat + "&lon=" + sLong + "\" border=\"0\" name=\"new_dialog\" style=\"width:615px; height:488px;\"></iframe>");
  dijit.byId('geospanviewer').startup();
  dijit.byId('geospanviewer').show();
  
  if (_mouseCoordType == "NATIVE") extentsWorldCoord = null;
}
//-----------------------------
//Toolbar Events End

//Search Frame Events Start
//-----------------------------
function executePINSearch() {
  if (dojo.byId("txtPIN").value != "") {
    //build query filter for PIN
    updateResultsTab("Results", "<img src='" + baseURL + "images/loader.gif' style=\"float: left;\"/><p class=\"aligntext\">Searching for PIN matching <b>" + dojo.byId("txtPIN").value + "</b></p>");
    
    processQuery("= '" + dojo.byId("txtPIN").value + "'", null, null, 0, showResults);
  }
}
//-----------------------------
//Search Frame Events End

function clearResults() { 
  ListCacheCaption = "";
  ListCacheBody = "";  
  
  if (_multiselect) { return; }
  
  selectedParcelID = -1;
  selectionExtent = null;
  
  _graphicsFeatures = [];
  refreshGraphics();
}

function clearForm(){
  dojo.byId("txtPIN").value = "";
}

function extentHistoryChangeHandler() {
  if (dojo.byId("zoomprev")) {
    dijit.byId("zoomprev").attr("disabled", navTB.isFirstExtent());
    dijit.byId("zoomnext").attr("disabled", navTB.isLastExtent());
  }
  extentsMapCoord = map.extent;
  
  if (_mouseCoordType == "NATIVE") {
  updateMapScale();
  } else {
  geometryService.project([new esri.Graphic(extentsMapCoord)], new esri.SpatialReference({"wkid" : 4326}), function(graphics) {
    extentsWorldCoord = graphics[0].geometry;
    updateMapScale();
  });
  }
}

function SelectResults(results) {
  clearResults();
  
  if(results.length == 0) {
    updateResultsTab("Results", "<img src='" + baseURL + "images/information.png' style=\"float: left;\"/><p class=\"aligntext\">No features selected</p>");
  _multiselect = false;
    return;
  }   
  
  var newSelectionExtent = getExtents(results);
  if (selectionExtent != null) { 
    selectionExtent = selectionExtent.union(newSelectionExtent);
  } else {
    selectionExtent = newSelectionExtent;
  }
  
  addToMapSelection(results); 
  
  if (ListCacheCaption != "") {
    updateResultsTab(ListCacheCaption, ListCacheBody);
  _multiselect = false;
    return;
  }
  
  if(_graphicsFeatures.length == 1) {
    getParcelDetails(0);
  } else if(_graphicsFeatures.length > 1) {
    getParcelList();
  } else {
    activateTool("clear");
  }
  
  _multiselect = false;
}

function showResults(featureSet) { 
  clearResults();

  if (featureSet.features.length == 0) {
    updateResultsTab("Results", "<img src='" + baseURL + "images/information.png' style=\"float: left;\"/><p class=\"aligntext\">No results found</p>");
    return;
  }
  
  var newSelectionExtent = getExtents(featureSet);
  if (selectionExtent != null) { 
    selectionExtent = selectionExtent.union(newSelectionExtent);
  } else {
    selectionExtent = newSelectionExtent;
  }
  
  addToMapSelection(featureSet);
  
  if (MapSelectedParcelID != -1) {
    getParcelDetails(MapSelectedParcelID);
    MapSelectedParcelID = -1;
  } else {
    if (ListCacheCaption != "") {
      updateResultsTab(ListCacheCaption, ListCacheBody);
      return;
    }    

    if(_graphicsFeatures.length == 1) {
      getParcelDetails(0);
    } else if(_graphicsFeatures.length > 1) {
      getParcelList();
    } else {
      activateTool("clear");
    }
  }
}

function getParcelDetails(id) {
  var selected = _graphicsFeatures[id];
  
  selectedParcelID = id;

  //Write out Parcel Detail
  var html_content = "";

  if (_graphicsFeatures.length > 1) {
    html_content += "<p id=\"backToListButton\"><button dojoType=\"dijit.form.Button\" onclick=\"getParcelList();\" iconClass=\"btnBackToListIcon\">Back to List</button></p>";
  }

  var isParcelLayerType = false;
  for(var i=0; i < SearchLayerNames.length; i++) {
    if (selected.layerId == getLayerIDFromName(SearchLayerNames[i])) { 
      isParcelLayerType = true;
    } 
  }
  
  glowGeometry(id);
  
  if (selected.geometry.type != 'point') {
  map.setExtent(selected.geometry.getExtent().expand(1.5));
  } else if (isParcelLayerType) {
    ZoomToPolysFromPoints([selected]);
  }  
  
  if (!isParcelLayerType) {       
    generateGenericTab(html_content, selected);    
  } else {    
    generateParcelDetailTab(html_content, selected);    
  }
}

function generateGenericTab(html_content, selected) {
  //Get the current feature from the featureSet.
  for( var p in selected.attributes) {
    if ((p != "Shape") && (p.toUpperCase() != "OBJECT ID") && (p.toUpperCase() != "OBJECTID") && (p.toUpperCase() != "OID")) {
      var value = selected.attributes[p];
      if (value == "Null") value = "<i>n/a</i>";

      if (selected.fieldAliases == undefined) {
        html_content += p + ":<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>" + value + "</b><br/>";
      } else {
        html_content += selected.fieldAliases[p] + ":<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>" + value + "</b><br/>";
      }
    }
  }    
    
  updateResultsTab("Results", html_content);
}

function generateParcelDetailTab(html_content, selected) {
  var RealFields, AliasFields, ParcelFieldName;

  if (selected.geometry.type == "point") {
    RealFields = ParcelPointFields;
    AliasFields = ParcelPointAlias;
    ParcelFieldName = ParcelPointFieldName;
  } else {
    RealFields = ParcelPolyFields;
    AliasFields = ParcelPolyAlias;
    ParcelFieldName = ParcelPolyFieldName;
  }
  
 
  for (var f=0; f < RealFields.length; f++) {
    var value = selected.attributes[RealFields[f]];

    html_content += AliasFields[f] + ":<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>" + value + "</b><br/>";
  }

  //Vanguard Code:
  if (typeof(VanguardURL) !== 'undefined') {   
  if (typeof(VanguardField) == 'undefined') VanguardField = ParcelFieldName;
    html_content += "<p id=\"vanguardButton\"><button dojoType=\"dijit.form.Button\" onClick=\"window.open('" + VanguardURL + selected.attributes[VanguardField] + "').focus();\"><img src=\"" + baseURL + "images/button_vanguard.png\" border=\"0\"></button></p>";
  }    
  
  //Governmax Code:
  if (typeof(GovernmaxURL) !== 'undefined') {   
  if (typeof(GovernmaxField) == 'undefined') GovernmaxField = ParcelFieldName;  
    html_content += "<p id=\"governmaxButton\"><button dojoType=\"dijit.form.Button\" onClick=\"window.open('" + GovernmaxURL + selected.attributes[GovernmaxField] + "').focus();\"><img src=\"" + baseURL + "images/button_governmax.png\" border=\"0\"></button></p>";
  }      
    
  updateResultsTab("Results", html_content);
}

function getParcelList() {
  var ResultsFound = _graphicsFeatures.length;
  var ResultsBody = "";
  
  selectedParcelID = -1;
  
  ResultsBody = "<div class=\"ResultHeader\">Found " + ResultsFound + " Matches</div>";

  for (var i = 0; i < ResultsFound; i++) {
    var ParcelFieldName;

    if (_graphicsFeatures[i].geometry.type == "point") {
      ParcelFieldName = ParcelPointFieldName;
    } else {
      ParcelFieldName = ParcelPolyFieldName;
    }
  
  
    ResultsBody += "<div class=\"ResultItem\" onmouseover=\"this.className='ResultItemHover'\" onmouseout=\"this.className='ResultItem'\">";
    ResultsBody += "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\" onclick=\"getParcelDetails(" + i + ")\" onmouseover=\"glowGeometry(" + i + ")\" onmouseout=\"glowGeometry(-1)\"><tr valign=\"top\">" +
      "<td><b>" + _graphicsFeatures[i].value + "</b></td></tr></table>";
    ResultsBody += "</div>";
  }
  
  ResultsBody += "<p id=\"clearResultsButton\"><button dojoType=\"dijit.form.Button\" onclick=\"activateTool('clear');\" iconClass=\"btnClearResultsIcon\">Clear Results</button></p>";
    
  updateResultsTab("Results (" + ResultsFound + ")", ResultsBody); 
  
  glowGeometry(-1);
  
  if (selectionExtent != null) {
  if (!_multiselect) map.setExtent(selectionExtent);
  } else {
    ZoomToPolysFromPoints(_graphicsFeatures);
  }
}

function resizeMapWindow(e){
  var mapdiv = dojo.byId("map");
  var resizediv = dojo.byId("dojoxGlobalResizeHelper");

  if (_sideBarState == "EXPANDED") {
  
    dojo.animateProperty({
      node: dojo.byId('map'),
      duration: 500,
      properties: {
          width: {end: parseInt(resizediv.style.width) - 313}
      }
        }).play();  
    
  } else {
  
    dojo.animateProperty({
      node: dojo.byId('map'),
      duration: 500,
      properties: {
          width: {end: parseInt(resizediv.style.width) - 10}
      }
        }).play();    
    
  }
  
  dojo.animateProperty({
    node: dojo.byId('wrapper'),
    duration: 500,
    properties: {
        width: {end: parseInt(resizediv.style.width)+2}
    },
    onEnd: function(){
        map.resize(); 
        setTimeout("map.reposition()",1000);
    }
  }).play();    
    
  dijit.byId('mainTabContainer').resize({ h: (parseInt(resizediv.style.height) - 2) });
}

function toggleSidepanel() {
  var mapcontainer = dojo.byId("mapcontainer"); 
  
  if (_sideBarState == "EXPANDED") {
  
    //Collapse it   
    dojo.animateProperty({
      node: dojo.byId('map'),
      duration: 500,
      properties: {
          width: {end: mapcontainer.offsetWidth - 12}
      },
      onEnd: function(){
          dojo.byId("mainTabContainer").style.right = "-304px";
          dojo.byId("sidepanelResizer").style.right = "2px";
          map.resize(); 
      }
        }).play();
    
    _sideBarState = "COLLAPSED";
    
  } else {
  
    //Expand it
    dojo.animateProperty({
      node: dojo.byId('map'),
      duration: 500,
      properties: {
          width: {end: mapcontainer.offsetWidth - 314}
      },
      onEnd: function(){
          dojo.byId("mainTabContainer").style.right = "2px";
          dojo.byId("sidepanelResizer").style.right = "304px";
          map.resize(); 
      }
        }).play();
    
    _sideBarState = "EXPANDED";
    
  }
}


dojo.addOnLoad(init);