	//this global object contains all references needed across functions 
	var globals = {};	  

	var map, locator;
	var houseNum;
	var preDir;
	var streetName;
	var streetType;
	 
	  
	/***************************************************************/
	/*                                                             */
	/***************************************************************/
	function initLayers() 
	{
		globals.map = new esri.Map("map");
		var FirstScreen_Layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://maps2.utahcountyonline.org/ArcGIS/rest/services/UCBaseMap/MapServer", {id:"County & Cities",visible:true});
		globals.map.addLayer(FirstScreen_Layer);
				
		ParcelLive_Layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://maps2.utahcountyonline.org/ArcGIS/rest/services/CentralProperty/MapServer", {id:"Parcels",visible:true});
		globals.map.addLayer(ParcelLive_Layer);
		
		RoadsForAerials_Layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://maps2.utahcountyonline.org/ArcGIS/rest/services/RoadsForAerials/MapServer", {id:"Roads",visible:true});
	    globals.map.addLayer(RoadsForAerials_Layer);
		
		//locator = new esri.tasks.Locator("http://maps2.utahcountyonline.org/ArcGIS/rest/services/UC_SC_GeocodeService/GeocodeServer");
		locator = new esri.tasks.Locator("http://maps2.utahcountyonline.org/ArcGIS/rest/services/UC_SC_Address_Locator93/GeocodeServer");
		dojo.connect(locator, "onAddressToLocationsComplete", showLocatorResults);
	}

	/***************************************************************/
	/* called from the 'Find' button                               */
	/***************************************************************/
	function findAddress() 
	{
		globals.map.graphics.clear();
		

		var addrField = dojo.byId("address").value;  //get the address field from the form
		addrField = addrField.replace(/\./g,'');     //get rid of the periods
		addrField = addrField.replace(/\,/g,'');     //get rid of the comma's
		var add = addrField.split(" ");              //parse the address with 'space' being the delimiter
		

		houseNum = add[0];
		preDir = add[1].toUpperCase();
		
		if (preDir == "NORTH")
		{
			preDir = "N"
		}
		else if (preDir == "SOUTH")
		{
			preDir = "S"
		}
		else if (preDir == "EAST")
		{
			preDir = "E"
		}
		else if (preDir == "WEST")
		{
			preDir = "W"
		}
		streetName = "";
		if (preDir in oc(['N', 'S', 'E', 'W']))
		{
			//do nothing
		}
		else //the prefix direction should be N, S, E, or W.  If it is not then we assume there is not one meaning the field is part of the street address
		{
			preDir = "";
			streetName = add[1].toUpperCase();
		}
				
		for(var i=2; i < add.length-1; i++)
		{
			streetName = streetName + add[i].toUpperCase() + " ";
		}
		
		streetType = add[add.length - 1].toUpperCase();
		

		   //if the street type is one of the street type domain values then it is a valid street type otherwise the value probably goes with the street name
		if(streetType.toUpperCase() in oc(['ALY', 'ALLEY', 'AVE', 'AVENUE', 'BLVE', 'BOULEVARD', 'CYN', 'CANYON', 'CIR', 'CIRCLE', 'CT', 'COURT', 'CV', 'COVE', 'DR', 'DRIVE', 'EXPY', 'EXPRESSWAY', 'FWY', 'FREEWAY', 'HTS', 'HEIGHTS', 'HWY', 'HIGHWAY', 'HL', 'HILL', 'HOLW', 'HOLLOW', 'LN', 'LANE', 'LA', 'LOOP', 'LOOP', 'PKWY', 'PARKWAY', 'PASS', 'PASS', 'PL', 'PLACE', 'RDG', 'RIDGE', 'RD', 'ROAD', 'ROW', 'ROW', 'RUN', 'RUN', 'ST', 'STREET', 'TER', 'TERRACE', 'TRL', 'TRAIL', 'VW', 'VIEW', 'WAY', 'WAY', 'XING', 'CROSSING', 'ON', 'ON', 'OFF', 'OFF']))
		{
			streetType = getStreetCode(streetType.toUpperCase());
		}
		else
		{
			streetName = streetName.toUpperCase() + streetType.toUpperCase();
			streetType = "";	
		}
		var lsCity = dojo.byId("cities").value.toUpperCase();
		
			//if the street name is something like 700 S change it to 700 SOUTH
		var stName = streetName.split(" ");
		if (stName[stName.length-1] == "N")
		{
			streetName += "ORTH"
		}
		else if (stName[stName.length-1] == "S")
		{
			streetName += "OUTH"
		}
		else if (stName[stName.length-1] == "E")
		{
			streetName += "AST"
		}
		else if (stName[stName.length-1] == "W")
		{
			streetName += "EST"
		}
		
		//alert("houseNum: " + houseNum + " preDir:" + preDir + " streetName: " +  streetName + " streetType: " + streetType + " lsCity: " + lsCity);
		
			//Here we can use an SQL on the point layer
		QueryAndPanToAddressPoint(houseNum.trim(), preDir.trim(), streetName.trim(), streetType.trim(), lsCity.trim());
		
	}  //end of function findAddress()
	
	/***************************************************************************/
	/* Return the street code as defined int the STREET_TYPE_GIS domain in SDE */
	/***************************************************************************/
	function getStreetCode(asStreetType)
	{
		var streetCode = asStreetType
		if (asStreetType == "ALLEY"){streetCode = "ALY";}
		else if (asStreetType == "AVENUE") {streetCode = "AVE";}
		else if (asStreetType == "BOULEVARD") {streetCode = "BLVD";}
		else if (asStreetType == "CANYON") {streetCode = "CYN";}
		else if (asStreetType == "CIRCLE") {streetCode = "CIR";}
		else if (asStreetType == "COURT") {streetCode = "CT";}
		else if (asStreetType == "COVE") {streetCode = "CV";}
		else if (asStreetType == "DRIVE") {streetCode = "DR";}
		else if (asStreetType == "EXPRESSWAY") {streetCode = "EXPY";}
		else if (asStreetType == "FREEWAY") {streetCode = "FWY";}
		else if (asStreetType == "HEIGHTS") {streetCode = "HTS";}
		else if (asStreetType == "HIGHWAY") {streetCode = "HWY";}
		else if (asStreetType == "HILL") {streetCode = "HL";}
		else if (asStreetType == "HOLLOW") {streetCode = "HOLW";}
		else if (asStreetType == "LANE") {streetCode = "LN";}
		else if (asStreetType == "LA") {streetCode = "LN";}
		else if (asStreetType == "LOOP") {streetCode = "LOOP";}
		else if (asStreetType == "PARKWAY") {streetCode = "PKWY";}
		else if (asStreetType == "PASS") {streetCode = "PASS";}
		else if (asStreetType == "PLACE") {streetCode = "PL";}
		else if (asStreetType == "RIDGE") {streetCode = "RDG";}
		else if (asStreetType == "ROAD") {streetCode = "RD";}
		else if (asStreetType == "ROW") {streetCode = "ROW";}
		else if (asStreetType == "RUN") {streetCode = "RUN";}
		else if (asStreetType == "STREET") {streetCode = "ST";}
		else if (asStreetType == "TERRACE") {streetCode = "TER";}
		else if (asStreetType == "TRAIL") {streetCode = "TRL";}
		else if (asStreetType == "VIEW") {streetCode = "VW";}
		else if (asStreetType == "WAY") {streetCode = "WAY";}
		else if (asStreetType == "CROSSING") {streetCode = "XING";}
		else if (asStreetType == "ON") {streetCode = "ON";}
		else if (asStreetType == "OFF") {streetCode = "OFF";}		
		
		return streetCode;
	}

	/******************************************************************/
	/*do an sql query on the address_points layer as the first attempt*/
	/******************************************************************/
	function QueryAndPanToAddressPoint(asHouseNum, asPreDir, asStreetName, asStreetType, asCity)
	{
		//First Query Task represents 
		var queryTask = new esri.tasks.QueryTask("http://maps2.utahcountyonline.org/ArcGIS/rest/services/RoadsForAerials/MapServer/0");
		var query = new esri.tasks.Query(); 
		
		 //build query filter                
		query.returnGeometry = true;
		query.outFields = ["SITE_HOUSENUM", "SITE_PREDIR", "SITE_STREETNAME", "SITE_CITYPOST"];
		

		//query.where = "SITE_HOUSENUM = " + asHouseNum + " AND SITE_PREDIR = '" + asPreDir + "' AND SITE_STREETNAME = '" + asStreetName + "' AND SITE_CITYPOST = '" + asCity + "'";          
		query.where = "SITE_HOUSENUM = '" + asHouseNum
		if (asPreDir.length > 0)
		{
			query.where += "' AND SITE_PREDIR = '" + asPreDir
		}
		query.where += "' AND SITE_STREETNAME = '" + asStreetName 
		if (asStreetType.length > 0)
		{
			query.where += "' AND SITE_STREETTYPE = '" + asStreetType
		}
		query.where += "' AND SITE_CITYPOST = '" + GetCity(asCity) + "'";
		
        //alert("QueryAndPanToAddressPoint()" + query.where);
		
		//Execute task and call showResults on completion
		queryTask.execute(query, function(fset) {
            //alert("QueryAndPanToAddressPoint() Found " + fset.features.length + " features");
			if (fset.features.length >= 1) 
			{
				showAddressPointFeature(fset.features[0]);
				return 1;
			}
			else if (fset.features.length !== 0) 
			{
				//alert("Address not found by query. (a)");
				invokeLocator();                       //since the address was not found by the query on the points layer try the address locator
			}
			else 
			{
				//alert("Address not found by query. (b)");
				invokeLocator();                       //since the address was not found by the query on the points layer try the address locator
			}
			globals.map.refresh();
		});
	}  //end of function QueryAndPanToAddressPoint()

	/***************************************************************/
	/* Get the city for the address point layer search.            */
	/* This layer uses 'UNINCORPORATED' instead of 'Utah County'.  */
	/***************************************************************/
	function GetCity(asCity)
	{
		if (asCity == "CEDAR VALLEY")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "COVERED BRIDGE")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "FAIRFIELD")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "FAIRVIEW")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "PROVO CANYON")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "SUNDANCE")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "UTAH COUNTY")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "WEST MOUNTAIN")
		{
			return "UNINCORPORATED";
		}
		else if (asCity == "WHITE HILLS")
		{
			return "UNINCORPORATED";
		}
		else
		{
			return asCity;
		}	
	}

	
	/***************************************************************/
	/*                                                             */
	/***************************************************************/
	function showAddressPointFeature(feature) 
	{
		var points =  new esri.geometry.Multipoint(globals.map.spatialReference);
		

		
        //alert("1.showFeature X: " + feature.geometry.x + " Y: " + feature.geometry.y);
		globals.map.graphics.clear();

		//var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NULL, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.5]));
		var symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 25,
					 new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, 
					 new dojo.Color([255,0,0]), 1),
					 new dojo.Color([0,255,0,0.25]));

		feature.setSymbol(symbol);
		globals.map.graphics.add(feature);
		
		pt = feature.geometry;

		//xMin = pt.x - 200;
	    //yMin = pt.y - 200;
	    //xMax = pt.x + 200;
	    //yMax = pt.y + 200;
 
		//globals.map.graphics.add(feature);
		
	    //var newExtent = new esri.geometry.Extent();
	    //newExtent.xmin = xMin;
	    //newExtent.ymin = yMin;
	    //newExtent.xmax = xMax;
	    //newExtent.ymax = yMax;


	    //globals.map.setExtent(newExtent,true);
		
//trying to get the map to refresh after it finds the point.  The problem is that it is not going back to the server to get a fresh page since the url hasn't changed
		//globals.map.resize();
        //alert("5.showFeature");		

		//ParcelLive_Layer.refresh();
FindAndPanToParcel(pt);


 //       alert("6.showFeature");

		
	}
	
	/***************************************************************/
	/* Call the address locator service                            */
	/***************************************************************/
	function invokeLocator() 
	{
	    //alert("Trying the address locator...")
		
			//now call the address locator service
		var lsStreet
		//lsStreet = dojo.byId("address").value;
		//lsStreet = lsStreet + " ST"                               //tack on the "ST" to the road name
        //alert("1.lsStreet: " + lsStreet);	

			//if the street name is something like 700 SOUTH add 'ST' to it so it looks like: 700 SOUTH ST
		var stName = streetName.split(" ");
		if ( (stName[stName.length-1] == "NORTH") || (stName[stName.length-1] == "SOUTH") || (stName[stName.length-1] == "EAST") || (stName[stName.length-1] == "WEST") ) 
		{
			streetName += " ST"
		}
		
		lsStreet = houseNum + " " + preDir + " " + streetName;
		
		if (streetType.length > 0) 
		{
			lsStreet += " " + streetType;
		}
        //alert("2.lsStreet: " + lsStreet);
		
	    var lsCity = dojo.byId("cities").value.toUpperCase();
		lsCity = GetCity(lsCity);
		if (lsCity == "UNINCORPORATED")
		{
			lsCity = "Utah County";   //the roads layer uses 'Utah County' rather than 'UNINCORPORATED' line the address point layer
		}
		var address = {Street : lsStreet, Zone: lsCity};
		
	    locator.addressToLocations(address,["Loc_name"]);
	}
	  

	/***************************************************************/
	/* show the results of the geocoder                            */
	/***************************************************************/
	function showLocatorResults(candidates) 
	{
		//alert("Got to showResults...");
		var candidate;
		var symbol = new esri.symbol.SimpleMarkerSymbol();
		var infoTemplate = new esri.InfoTemplate("Location", "Address: ${address}<br />Score: ${score}<br />Source locator: ${locatorName}");
		
		symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE);
		symbol.setColor(new dojo.Color([255,0,0,0.75]));
		
		var points =  new esri.geometry.Multipoint(globals.map.spatialReference);
		
		var score = 0;
		var can;
		for (var i = 0, il = candidates.length; i < il; i++) {
		
			candidate = candidates[i];
			if (candidate.score > 70) {
				if (score < candidates[i].score) {
					can = candidates[i];
					score = can.score;
				}
			}
		}
		if (score < 40) {
			esri.hide(dojo.byId("loader"));
			alert("Unable to match address!")
		}
		else {
			try {
				//console.info("match add: " + can.address + "score: " + can.score + " locator Name: " + can.attributes.Loc_name);
				
				//alert("can: " + i + " " + can.score)
				var attributes = {
					street: can.street,
					//address: can.address,
					score: can.score,
					locatorName: can.attributes.Loc_name
				};
				var graphic = new esri.Graphic(can.location, symbol, attributes, infoTemplate);
				globals.map.graphics.add(graphic);
				globals.map.graphics.add(new esri.Graphic(can.location, new esri.symbol.TextSymbol(attributes.address).setOffset(0, 8)));
		
				points.addPoint(can.location);
				points.addPoint({"x": can.location.x + 10, "y": can.location.y + 10});  //we need to add another point so that we don't have an extent of 0 width & height as you get with only 1 point in the Multipoint object
				
				//globals.map.centerAndZoom(graphic.geometry, 1);
				//globals.map.centerAndZoom(graphic.geometry, .001);
				globals.map.setExtent(points.getExtent().expand(50));
				
			}   
			catch (e) {
				alert(e.message);
			}
		}
	
	//globals.map.setExtent(points.getExtent().expand(3));
	//alert("z.ShowResults");
//globals.map.refresh();
	}   //end of function showLocatorResults()

	
	/***************************************************************/
	/*                                                             */
	/***************************************************************/
	function SetCity(value)
	{
		//alert("Selected: " + value);
		//alert("City: " + dojo.byId("cbxCity").attr('value'));
		//var selectedtext = dojo.byId("cities").value;
		//alert(selectedtext);
		//alert(dojo.byId("cbxCity".attr('value')));
	}
	
	/***************************************************************/
	/* implement a trim function for strings in javascript         */
	/***************************************************************/
	String.prototype.trim = function () 
	{
	  return this.replace(/^\s*/, "").replace(/\s*$/, "");
	}
	
	/***************************************************************/
	/* object converter                                            */
	/***************************************************************/
	function oc(a)
	{
	  var o = {};
	  for(var i=0;i<a.length;i++)
	  {
	    o[a[i]]='';
	  }
	  return o;
	}

	/***************************************************************/
	/* Zoom to the Parcel Polygon that the point falls within.     */
	/***************************************************************/
	function FindAndPanToParcel(aPoint)   //passed in the point the address locator found
	{
		//alert("FindAndPanToParcel(a)  x:" + aPoint.x + " y: " + aPoint.y);

		var pt =  new esri.geometry.Point(aPoint.x, aPoint.y, new esri.SpatialReference({ wkid: 102743 }));  //set the spatial reference on the point

		var queryTask = new esri.tasks.QueryTask("http://maps2.utahcountyonline.org/ArcGIS/rest/services/ParcelLive/MapServer/2");
		var query = new esri.tasks.Query(); 
		
		 //build query filter                
		query.returnGeometry = true;		
		query.geometry = pt;    			//the point passed into this function
		

		  //Execute task and call showResults on completion
       	queryTask.execute(query, function(fset) {
		    if (fset.features.length >= 1) 
			{
		        ZoomToPolygonFeatures(fset.features);
		    } 
			else 
			{ 
			 	alert ("Precinct not found.");
			}
          
        });
	}
	
	/*******************************************************************/
	/* Passed in an array of parcel polygon features.                  */
	/* Used for zooming since I can't seem to zoom to a point feature. */
	/*******************************************************************/
	function ZoomToPolygonFeatures(features) 
	{
		for (var i=0; i < features.length; i++)             //8-6-10 modified to highlight 'ALSO' parcels
		{
			var fExtent = features[i].geometry.getExtent();
			globals.map.setExtent(fExtent.expand(1.5));
			
			var centerPt = fExtent.getCenter();
			globals.map.centerAt(centerPt);
		}
	}
	
	
