    var searchExec = new MQExec(spatServerName,mqServerPath,mqServerPort,proxyServerName,proxyServerPath,proxyServerPort);
 
    var searchStateOptions = new stateOptions(); 

   /*
    *  geocodes the origin of the search, and call search function
    */
    function getResultsForForm() {
     
        //geocode the address
        var address = new MQAddress();
        address.setStreet(document.getElementById("street1").value);
        address.setCity(document.getElementById("city").value);
        var stateSel  = document.getElementById("stateList");
        address.setState(stateSel.options[stateSel.selectedIndex].value);
        address.setPostalCode(document.getElementById("postalcode").value);
        var countrySel = document.getElementById("countryList");
        address.setCountry(countrySel.options[countrySel.selectedIndex].value);
        
        geocodeAndMapAddress(address);
    } 
    
        /*
    *  geocodes the origin of the search, and call search function
    */
    function getResultsForAddress(street, city, state, postalCode, country, lat, lng) {
        //geocode the address
        var address = new MQAddress();
        address.setStreet(street);
        address.setCity(city);
        address.setState(state);
        address.setPostalCode(postalCode);
        address.setCountry(country);
        
        if(lat != null && lng != null)
        {
        	getResultsForAmbiguousAddr(street, city, state, postalCode, country, lat, lng, false);
        }
        else
        {
        	geocodeAndMapAddress(address);
        }
    }
    
    function getResultsForAmbiguousAddr(street, city, state, postalCode, country, lat, lng, showOrigin) {
        //geocode the address
        var address = new MQGeoAddress();
        address.setStreet(street);
        address.setCity(city);
        address.setState(state);
        address.setPostalCode(postalCode);
        address.setCountry(country);
        var latLng = new MQLatLng(lat, lng);
        address.setMQLatLng(latLng);
        showMap(address, showOrigin);
    }
    
    function geocodeAndMapAddress(address)
    {
        var gaCollection = new MQLocationCollection();
        var geocodeResult = geocodeAddress(address, gaCollection);
        
        if ( geocodeResult == "LOCATION_NOT_FOUND" ||  geocodeResult == "LOCATION_NOT_EXACT")
        {
            document.getElementById("errorMessage").innerHTML = UNKNOWN_LOCATION;
            var loadingMap = document.getElementById("loadingMap");
            if ( loadingMap ) 
            {
                loadingMap.innerHTML = "";
            }
            return false;
        }
        else if ( geocodeResult == "LOCATION_AMBIGUOUS" )
        {
            showSelectFromMultipleGeocodeResults(address, gaCollection);
        }
        else
        {
            showMap(geocodeResult);
        }            
        
    }
    
    
    function showMap(geoAddr, showOrigin)
    {
    	if(showOrigin == null)
    		showOrigin = true;
    		
        myMap = startMap('locatorMap');
        myPoiEvents = new poiEvents(myMap);
        
        // Setup the header above the map that shows the original address and new search link
        var headerDiv = document.getElementById('locatorMapHeader');
        origAddrDiv = document.createElement('div');
        origAddrDiv.id = "locatorResultsOrigAddress";        
        origAddrDiv.appendChild(document.createTextNode("SONIC Drive-In locations near: "));        
        addressToString(geoAddr, origAddrDiv);
        headerDiv.appendChild(origAddrDiv);
        
        var newSearchLink = document.createElement('a');
        newSearchLink.href = newSearchUrl;
        newSearchLink.id = "locatorResultsNewSearchLink";
        var newSearchImg = document.createElement('img');
        newSearchImg.src = newSearchButtonUrl;
        newSearchImg.id = "locatorResultsNewSearchImg";
        newSearchLink.appendChild(newSearchImg);
  
        headerDiv.appendChild(newSearchLink);
       
        //create a variable for the origin of the search
        origin = geoAddr.getMQLatLng();
        //call search function, get back a FeatureCollection of results
        var searchRes = new doSearch(origin);
        
        //If get results from search create collection of location ids from result keys
        var results;
        if(searchRes.getSize() > 0 )
        {
            var recordset = new MQRecordSet();
            var ids = new MQStringCollection();
            for(var i=0; i < searchRes.getSize(); i++)
            {
                ids.add(searchRes.getAt(i).getKey());
            }

            //Retrieve record set for each id in the results
            var fields = new MQStringCollection();
    
            //Create Database Query Collection and Add Database Query to Collection
            var dbLayerQueryCollection = new MQDBLayerQueryCollection();
            var dbLayerQuery = new MQDBLayerQuery();
            dbLayerQuery.setDBLayerName(MQDB);
            dbLayerQueryCollection.add(dbLayerQuery);
            
            
            searchExec.getRecordInfo(fields, dbLayerQuery, recordset, ids);
            results = getResultsAsArray(recordset, searchRes);
        }
        
        var locationsDivList = buildStoreLocationsDivList(results, myPoiEvents, geoAddr);  
        
        if(showOrigin)
        {
	        //Add the search origin to the map
	        var myPoint = new MQA.Poi(origin);
	        myPoint.setValue('infoTitleHTML','Starting Address');
	        startDiv = document.createElement("div");
	        addressToString(geoAddr, startDiv);
	        myPoint.setValue('infoContentHTML',startDiv.innerHTML);
	        myPoint.setValue('key', 'Origin');
	        myMap.addShape(myPoint);
        }
        //Best-Fit the map to the results
        myMap.bestFit();
        
        var parent = document.getElementById('mapDataContainer');
        removeAllChildren(parent);
        parent.appendChild(locationsDivList);
        roundCorners();

    }
    

    function showSelectFromMultipleGeocodeResults(address, gaCollection)
    {
        var ol = document.createElement("ol");
        ol.className = 'ambiguousMapResults';
        for (var i=0; i < gaCollection.getSize(); i++)
        {
            var addr = gaCollection.getAt(i);
            var li = document.createElement("li");
            var a = document.createElement("a");
            var href = "javascript:getResultsForAmbiguousAddr(";
            href  += "\"" + addr.getStreet() + "\", ";
            href  += "\"" + addr.getCity() + "\", ";
            href  += "\"" + addr.getState() + "\", ";
            href  += "\"" + addr.getPostalCode() + "\", ";
            href  += "\"" + addr.getCountry()+ "\", ";
            href  += "\"" + addr.getMQLatLng().getLatitude() + "\", ";
            href  += "\"" + addr.getMQLatLng().getLongitude() + "\");";
            
            a.href = href;
            a.appendChild(document.createTextNode("Find SONIC Drive-In locations near: "));
            var addrDiv = document.createElement("div");
            addrDiv.className = "addressMultiLine";
            addressToString(addr, addrDiv);
            li.appendChild(a);
            li.appendChild(addrDiv);
            li.appendChild(document.createElement("p"));
            ol.appendChild(li);
        }
        var headerDiv = '<div class="error"><h2>Multiple Locations Found:</h2> Cannot find an exact match for ';
        headerDiv += address.getStreet() + ", " + address.getCity() + ", " + address.getState();
        headerDiv += ". But similar addresses were found. Select one of these addresses to search for nearby SONIC Drive-In locations or click Store Locator to start a new search.</div>";
        document.getElementById('mapDataContainer').innerHTML = headerDiv + "<p/>" + ol.innerHTML;        
    }
    
    /*
    *  set up search parameters and search
    *  returns search results(featurecollection)
    */
    function doSearch(LLobj) {
        //set up the SearchCriteria - centerLL, radius, # results
        var sCriteria = new MQRadiusSearchCriteria();
        sCriteria.setMaxMatches(5);
        sCriteria.setRadius(1000);
        sCriteria.setCenter(LLobj);
        //Setup search source - in this case, the Test DB table
        var dbLayerQueryCollection = new MQDBLayerQueryCollection();
        var dbLayerQuery = new MQDBLayerQuery();
        dbLayerQuery.setDBLayerName(MQDB);
        dbLayerQueryCollection.add(dbLayerQuery);
        //empty FeatureCollection to hold the search results
        var searchResults = new MQFeatureCollection();
        //Search!
        searchExec.search(sCriteria, searchResults,'', dbLayerQueryCollection);
        //return the featurecollection
        return searchResults;
    }



// Check to see if a zip code is specified as a query parameter and if so, 
// bypass the form and show the map.
function loadMapForZip()
{
    var qs = new Querystring();
    var zip = qs.get("zip");
    var lat = qs.get("lat");
    var lng = qs.get("lng");
    
    if ( lat != null && lng != null)
    {
    	var street = qs.get("street");
    	var city = qs.get("city");
    	var state = qs.get("state");
    	var country = qs.get("country");
    	return getResultsForAddress(street,city,state,zip,country,lat,lng);
    }
    else if ( zip != null && zip != 'ZIP' && zip != 'zip' && zip.length > 0 )
    {
        // Strip out any non-digit characters.
        zip = zip.replace(/\D/g, "");
        
        if ( zip.length > 0 )
	    {
	        return getResultsForAddress('','','',zip,'');
	    }
	    else
	    {
	       // zip was non-null so they must have entered a value in the 'find a sonic' box
	       // don't try to set the statelist because it won't exist
	        document.getElementById("errorMessage").innerHTML = UNKNOWN_LOCATION;
            var loadingMap = document.getElementById("loadingMap");
            if ( loadingMap ) 
            {
                loadingMap.innerHTML = "";
            }
            return false;
	       return;
	    }
    }
    
    // no zip specified set state drop down.
    searchStateOptions.stateListSwitch('stateList','US'); 
    
}    

