//Add filter item
///UNDO MARK
/* function to grab a value from the querystring by key name */ 
function getQueryStringValue(key, default_) {
	if(default_ == null) default_ = "";
	var search = unescape(location.search);
	if (search == "") return default_;
	search = search.substr(1);
	var params = search.split("&");
	for (var i = 0; i < params.length; i++)
	{
		var pairs = params[i].split("=");
		if(pairs[0] == key)
		{
			return pairs[1];
		}
	}
	return default_; 
}

/* function to grab a value from the querystring by key name within a specified range */
function getIntQueryStringInRange(key,default_,min,max) {
	var value = getQueryStringValue(key,default_);
	value = parseInt(value);
	if(isNaN(value)) { // set to default if not a number
		value = default_;
	} else { // range check
		if(value < min) value = min;
		if(value > max) value = max;
	}
	return value;
}
	
// if there is an agency zoom level, make sure it's between 0 and 19
agency_zoom = getIntQueryStringInRange('agencyzoomlevel',null,0,19);

displayed_categories = new Object(); //GLOBAL
hidden_categories  = new Array ();   //GLOBAL
emptyFilters = true; //GLOBAL

MIN_ZOOM_WITH_MARKERS = 9;

/* object to transfer search address to signup box */
var searchAddress = {
    address : "",
    city : "",
    state : "",
    country : ""
}

var lastGeoCoded = {
		point : new GLatLng(),
		country: '?'
};

var polyoverlays = [];
function clearPolyOverlays() {
    for (var i = 0; i < polyoverlays.length; i++) {
        map.removeOverlay(polyoverlays[i]);
    }
    polyoverlays = [];
}

/* THE UI FUNCTIONS FOR SHOWING/HIDING SO DATA POPINS
 * 
 */
function cancelShowSoData(){
	lightbox.prototype.hide('showSoDataExistsWithNoCrimeData');
	//save the response so this doesn't popup each time they drag or do a new search
	var c = new CookieHandler(); //see utility.js for usage
	c.setCookie('so_terms_agreed', 0, 60*60*24*7);
}

function showSoTerms(){
	lightbox.prototype.hide('showSoDataExistsWithNoCrimeData');
	//Assume, it's as if they clicked 'Show Sex Offenders'
	checkSoTerms(true);
}

function agreedSoTerms(){
	//user has now agreed to show so data, so update the UI and cookie
	document.getElementById('showSexOffendersCheckbox').checked=true;
	var c = new CookieHandler(); //see utility.js for usage
	c.setCookie('so_terms_agreed', 1, 60*60*24*7);
	lightbox.prototype.hide('showSoTerms');
	toggleSOData();
}

function cancelSoTerms(){
	lightbox.prototype.hide('showSoTerms');
	document.getElementById('showSexOffendersCheckbox').checked=false;
}

/* check to see if we need to pop up the sex offender terms/conditions 
 * This is called whenever the 'Show Sex Offender' checkbox is clicked, and from showSoTerms()
 */
function checkSoTerms(checked) {
    //only run if checking the so checkbox, not unchecking
	if(checked){
		//uncheck until the terms have been agreed upon. Make sure the UI matches the intent of the user at this point in the
		//space time continuum (however brief). If the haven't agreed to terms yet, they haven't really checked it in their head

		var c = new CookieHandler(); //see utility.js for usage
	    cookie = c.getCookie('so_terms_agreed');
	    //if the user has never seen the terms, or has previously declined
	    if(cookie==null || cookie==0) {
	    	lightbox.prototype.showme("showSoTerms", 0);
	    }
	    else{
		    //if previously agreed, proceed
		    toggleSOData();
	    }
	}
	else
		toggleSOData();
}

/* END UI FUNCTIONS FOR SHOWING/HIDING SO DATA POPINS */

/*FB 104 THIS WAS DISABLED*/

/* Each time a crimeDataForFilter response success happens, this is called
 * alert user if no crime data is found, but sex offender data is (per reqs of FB 104) 
 * Note that each time the SO checkbox in the UI is clicked, it makes another request to google (toggleSOData calls getDataForNewFilter)
 * 
 */
function soDataWithoutCrimeDataTerms() {
    //check the so_terms cookie
	var c = new CookieHandler(); //see utility.js for usage
    cookie = c.getCookie('so_terms_agreed');
    //make sure that the terms haven't already come up. 
    //Note if the checkbox has been unclicked, and the response handler fires off 
    //and calls this again, 
    //SO MAKE SURE THAT WHEN THE USER AGREES TO SHOW SO DATA THE COOKIE IS SET SO NO POPIN WILL COME UP AGAIN
    //Edge case -  if the user has 'Show Sex Offenders' checked or saved in Session 
	//and then deletes the cookie - don't show the popin (!document.getElementById('showSexOffendersCheckbox').checked)
    //if cookie is 0 (soterms have been declined), then stop bugging the user, who has already declined to see SoData
    //only show if cookie is null (user has yet to decline or has reset cookies)
    if(cookie==null && !document.getElementById('showSexOffendersCheckbox').checked) {
        lightbox.prototype.showme("showSoDataExistsWithNoCrimeData", 0);
    }
}

/*Updates the default address, based on the two-letter country code  */
function updateDefaultAddress(countryCode){
	//right now just handle Canada and US
	switch (countryCode){
	case "US":
	document.getElementById("defaultAddressLinks").innerHTML = '\"<a href="/map?search=695+Coleman+Avenue%2C+San+Jose%2C+CA">695 Coleman Avenue, San Jose CA</a>\", \"' + 
				'<a href="/map?search=San+Jose%2C+CA">San Jose, CA</a>\", \"' + '<a href="map?search=95110">95110</a>\"';
	break;
	case "CA":
	document.getElementById("defaultAddressLinks").innerHTML = '\"<a href="/map?search=110%20Laurier%20Avenue%20West%20Ottawa,%20Ontario%20K1P%201J1">110 Laurier Avenue West Ottawa, Ontario K1P 1J1</a>\"';
	break;
	default : document.getElementById("defaultAddressLinks").innerHTML = '\"<a href="/map?search=695+Coleman+Avenue%2C+San+Jose%2C+CA">695 Coleman Avenue, San Jose CA</a>\", \"' + 
	'<a href="/map?search=San+Jose%2C+CA">San Jose, CA</a>\", \"' + '<a href="map?search=95110">95110</a>\"';
	}
}

/*Takes a lat/long and reverse geocodes it to get the country code*/
function getCountryCodeFromLatLng(lat, lng){
	tr= YAHOO.util.Connect.asyncRequest('GET', htmlbase + 'map/reversegeocodeforcountry/lat/'+map.getCenter().lat()+'/lng/'+map.getCenter().lng(), reverseGeoCodecallback);
}

//Define the callbacks for the asyncRequest
var reverseGeoCodecallback = {
	success: reverseGeoCodeSuccessCallback,
	failure: reverseGeoCodeFailCallback
}


/*
* Ignore warnings from the reverse geocoding process
*/
function reverseGeoCodeSuccessCallback(o){
	var obj = o.responseText.evalJSON();
	//gmapsSuccessStatus is 0 or 1, and then 2 for valid responses that gmaps returns with no country code (ignore these)
	if (obj && obj.gmapsSuccessStatus ==1){
		updateDefaultAddress(obj.countryCode);
	}
	else if(obj && obj.gmapsSuccessStatus == 2){}//alert("Warning from server: " + obj.statusMessage);}
	else if(obj && obj.gmapsSuccessStatus == 0)
		{}//alert("Error from server: " + obj.statusMessage);}
	else
		{}//alert("Error getting country for map center");}
}

function reverseGeoCodeFailCallback(o){
	//this shows up if you leave the page and requests to google are still pending. Let's not show this.
	//alert("Error from server getting country for map center");
}

// startCoords needs to be a string with lat,lng coordinates, comma-separated
function setCoordsString(startCoords) {
	
	var coords = startCoords.split(',');
	if (coords.length < 2)
		return;
	var zoom = 5;
	if (coords.length >= 3)
		zoom = parseInt(coords[2]); // if agency zoom was passed-in, use that
	zoom = agency_zoom != null ? agency_zoom : zoom; 
	map.setCenter(new GLatLng(parseFloat(coords[0]), parseFloat(coords[1])), zoom);
}

function createGMap() {
	//try {
    if (GBrowserIsCompatible() ) { 
      
        map = new GMap2(document.getElementById("map"));
        map.addMapType(G_PHYSICAL_MAP);  
        map.addControl(new GLargeMapControl(),new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(5,-60)));  
        map.addControl(new GMapTypeControl());
        map.overlays = [];

	   GEvent.addListener(map,'addoverlay',function(o) {
	       this.overlays.push(o);
	   });
	   GEvent.addListener(map,'click',function(overlay, latlng, overlaylatlng) {
				var doThematic = getDoThematic();
				if (doThematic) {
					getShapeIdFromLatLng(latlng.lat(), latlng.lng(), function () {map.closeInfoWindow()} );
				}
				
	   });
	           
        GEvent.addListener(map,'removeoverlay',function(o) {
            for(var i = 0; i < this.overlays.length; i++)
                if(this.overlays[i] === o)
                    return this.overlays.splice(i,1);
        });
        
        GEvent.addListener(map,'clearoverlays',function(){
            this.overlays = [];
        }); 
        //end map.overlays

        if(a_crimeid) {  //if the map has been started with just a crime id
        	
            getDataForCrimeID(true,a_crimeid);  
        	
            map.setCenter(new GLatLng(a_lat,a_lng),14);
            a_lat = null;
            a_lng = null;
        } else {
            if(a_mapid) {
            	
                getDataForMapID(true,a_mapid); // grabs crimelist from the parameters encrypted in mapid
            	
                map.setCenter(new GLatLng(a_lat,a_lng),14);  //from crime report               
            } else {
            	
                if(!a_lat) {
					if (typeof(startCoords)!='undefined' && startCoords) {
						setCoordsString(startCoords); // parse out lat/lng and possible, optional zoom from the startCoords string and center the map on it
					} else {
						map.setCenter(new GLatLng(38.89,-77.037),5); // Eastern Seaboard near Washington D.C.
					}
                } else {
                	
                    map.setCenter(new GLatLng(a_lat,a_lng),14);  //from alert if available
                }
            }
        }
        
        try {
            // stuff for area filter
            if (typeof(doSetupAreaPanTrigger) != 'undefined' && doSetupAreaPanTrigger 
                    && typeof(setupAreaPanTrigger)=='function') {
                setupAreaPanTrigger();
            }
            if (chosenAreaLat && chosenAreaLng) {
                loadAreaFilterTiles();
            } else if (thematic_shapefile_id) {
                showThematicView = true;
                thematicShapefileId = thematic_shapefile_id;
                document.getElementById('showThematicView').checked = true;
            } else if (areaShapeIds && getShapefileId) {
                window.chosenShapefileId = getShapefileId(areaShapeIds.split(',')[0]); //shapeToShapefileMap[areaShapeIds.split(',')[0]];
                initAFTileOverlay(map);
            }

        } catch (e) {}

        GEvent.addListener(map, "dragend", function() {
            var center = map.getCenter();
            //For now the country code is gotten using google reverse geocoding
            //We could expand this functionality if we need other map data besides lat/lng
            //OR figure a way to use shapefiles and countries in the database to avoid making extraneuos google requests
            //But somehow we need to obtain the country FB Case 19
            //SO - here we geocode the center lat/lng and get the counry code from the most general placemark point (The last one, see gmaps API)
            countryCode = getCountryCodeFromLatLng();
            if(a_mapid) {
                //don't refresh. for now we will load everything
            } else {
                if(map.getZoom()>=MIN_ZOOM_WITH_MARKERS) {
                    //GLog.write(map.getZoom());
                    getDataForNewFilter();
                }
            }
        });
     
        //controls what gets shown at the zoom level
        GEvent.addListener(map,'zoomend',function(oldLevel, newLevel) {
            drawCircles();
            if(newLevel >= MIN_ZOOM_WITH_MARKERS) {
                showAllMarkers();
                if(a_mapid == null) { getDataForNewFilter(); }
            } else {
                setMessage(t("Please zoom in to see crime detail."),"DISPLAY");
                hideAllMarkers();
            }
						try {
							if (showThematicView && thematicShapefileId) {
								thematicChangedZooms();
							}
						} catch (e) {}
        }); 
        
        GEvent.addListener(map,'subscribe',function() {
            
        });
      
        // ====== Create a Client Geocoder ======
        geo = new GClientGeocoder(); 

        // ====== Array for decoding the failure codes ======
        var reasons=[];
        reasons[G_GEO_SUCCESS]            = "Success";
        reasons[G_GEO_MISSING_ADDRESS]    = "The address was either missing or had no value.";
        reasons[G_GEO_UNKNOWN_ADDRESS]    = "No corresponding geographic location could be found for the specified address.";
        reasons[G_GEO_UNAVAILABLE_ADDRESS]= "The geocode for the given address cannot be returned due to legal or contractual reasons.";
        reasons[G_GEO_BAD_KEY]            = "The API key is either invalid or does not match the domain for which it was given";
        reasons[G_GEO_TOO_MANY_QUERIES]   = "The daily geocoding quota for this site has been exceeded.";
        reasons[G_GEO_SERVER_ERROR]       = "The geocoding request could not be successfully processed.";
    
        // display a warning if the browser was not compatible
    } else {
        setMessage(t("Your browser is not compatible with the CrimeReports.com mapping service."));
        //document.getElementById("message").innerHTML = "Your browser is not compatible with the CrimeReports.com mapping service.";
    }
	//}catch (e) { alert(e.name+" : "+e.message + " --- "+e);}
   
} // end function createGMap

/* Recursive function to search an object (up to depth levels) for a specific key.
** NOTE: This function was designed against the google maps "response" variable,
** and will most likely not work with prototype or DOM objects.
** returns the value of the first matching key */
function searchObject(searchName, obj, depth) {
    for(i in obj) {
        if(typeof(obj[i]) == "object" && depth) {
            if(next = searchObject(searchName, obj[i], --depth)) {
                return next;
            }
        } 
        if(i == searchName) {
           return obj[i];
        }
    }
    return false;
}

//default zoom level. Global So that it could be set dynamically via php.
var defZoom = 14;

// clearAreas is a boolean, indicates whether to clear the area filter
function loadMap(clearAreas) { //alert('a_mapid: '+a_mapid); alert('a_crimeid: '+a_crimeid);
    setMessage("");      
    document.getElementById('crimesnum').innerHTML=0;
    
    var search;
    if(document.getElementById("searchtext")) {
        search = document.getElementById("searchtext").value;
    }
    //====== Perform the Geocoding ======  

    if(search && search != "") { // if there is something in the searchbar
    	
        geo.getLocations(search, function (result) { // geo is a GClientGeocoder class
            // If that was successful
            if (result.Status.code == G_GEO_SUCCESS) {
                logSearch(result);
//alert('The Country : '+searchObject("CountryNameCode", result.Placemark.toArray(), 12));
                // Place Map Markers
            	
                for (var i=0; i<result.Placemark.length; i++) {
                    var p = result.Placemark[i].Point.coordinates;
                    var marker = new GMarker(new GLatLng(p[1],p[0]),{clickable:false});
                    map.addOverlay(marker);
                }
                var p = result.Placemark[0].Point.coordinates;
                lastGeoCoded.point = addressCoords = new GLatLng(p[1],p[0]);

                // If the result object has a bounding box, use it to determine an appropriate zoom. 
                // But don't let the map be zoomed out so much that crime markers wouldn't show.
                // Use default zoom if no bounding box specified
                // Also, center map on the first result
                
                try {
                  var bounds = result.Placemark[0].ExtendedData.LatLonBox;
              	
                  var llbounds = new GLatLngBounds(
                    new GLatLng(bounds.south, bounds.west),
                    new GLatLng(bounds.north, bounds.east));

                  // set initial zoom to the greater of Google's suggested zoom or our min zoom
                  var zm = Math.max(map.getBoundsZoomLevel(llbounds), MIN_ZOOM_WITH_MARKERS);
                  if(agency_zoom != null) zm = agency_zoom; // use agency zoom if it exists
                  map.setCenter(addressCoords, zm);
                } catch (e) {
                	var catch_zoom = agency_zoom != null ? agency_zoom : defZoom; // use agency zoom if it exists
                    map.setCenter(addressCoords, catch_zoom);
                }

                try {
                 if (clearAreas && areaShapeIds.length > 0) {
                  deselectAllAreas();
                 }
                } catch(e) {}
               
                // reset the save alert lat and lng coordinates
                document.getElementById('alert_lat').value = p[1];
                document.getElementById('alert_lng').value = p[0];
                document.getElementById('alert_address').value = search;

                //store address/city/state to global object for use with quick signup
                searchAddress.address = searchObject("ThoroughfareName", result.Placemark.toArray(), 12);
                searchAddress.city = searchObject("LocalityName", result.Placemark.toArray(), 10);
                searchAddress.state = searchObject("AdministrativeAreaName", result.Placemark.toArray(), 12);
                searchAddress.country = lastGeoCoded.country = searchObject("CountryNameCode", result.Placemark.toArray(), 12);

                //update the default address based on the search's result location FB Case 19
                if(searchAddress.country)
                	updateDefaultAddress(searchAddress.country);
                
                drawCircles(addressCoords);
                getDataForNewFilter(true, null, true);
            } else {
                this.setMessage("Sorry. We were unable to locate the requested address. Please try again.","DISPLAY"); 
            }
        });
    } else { /**** NO SEARCH ENTERED? ****/
    
        if(a_lat) {
            var marker = new GMarker(new GLatLng(a_lat,a_lng));
            map.addOverlay(marker);
            addressCoords = new GLatLng(a_lat,a_lng);
            map.setCenter(addressCoords, defZoom);
            if(!a_mapid)getDataForNewFilter(true, null, true);
        } else if (typeof(startCoords)!='undefined' && startCoords) {
			setCoordsString(startCoords);
        } else {
            map.setCenter(new GLatLng(38.89,-85.037),5);
        }
    }
    
    //If the user toggled on the distance guide, Then this will make the distance guide show up when they print. 
    if(AddBullsEye){
		showBullseye = true;
    	drawCircles(addressCoords);
    	//this is for printing. If the bullseye is added wait until the overlay is fully loaded and then change the div to be printable.
    	//I set it for 1 second because I think it is waiting on the server and you never know how long that will take.
    	window.setTimeout(function (){
    				makeBullseyePrintable();
    		}, 1000);
	}
} // end loadmap()
    

function addAddressToMap(response) {
    map.clearOverlays();
    if (!response || response.Status.code != 200) {
        this.setMessage(t("Sorry. We were unable to locate the requested address. Please try again."),"ERROR")
    } else {
        place = response.Placemark[0];
				point = lastGeoCoded.point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
        lastGeoCoded.country = searchObject("CountryNameCode", result.Placemark.toArray(), 12);

        marker = new GMarker(point);
        map.addOverlay(marker);
        map.setCenter(point,14);
        document.getElementById('address_lat').value = point.lat();
        document.getElementById('address_lng').value = point.lng();

        this.setMessage("","DISPLAY");
       
    }
} // end addAddressToMap()

function findLocation(address){
    geo.getLocations(address, addAddressToMap);
}


function category(name, id, on, col) {
	this.name = name;
	this.id   = id;
	this.on   = on;
	this.column = col;
}

var crimefiltersLoaded = false;

//numtries is optional, defaults to 4
function loadFilters(defaultFilters, numtries) {
	
	if (typeof numtries == 'undefined' || numtries===null) numtries = 4;
	if (typeof numtries != 'number') numtries = 0;
	if (numtries < 0) return;
	
	var callback =
	{
		success: responseSuccess,
		failure: responseFailure,
		argument: ['crimesubtypes', loadFilters, defaultFilters, numtries-1],
		timeout: 7000
	}

	var countryCode = '?';
	if (map.getCenter().equals(lastGeoCoded.point)) {
		countryCode = lastGeoCoded.country;
	}
	
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'map/xmldata/isAjax/true/cb/'+100*Math.random(), callback, 'countryCode='+countryCode+'&lat='+map.getCenter().lat()+'&lng='+map.getCenter().lng());

	//GLog.write(htmlbase + 'map/xmldata/isAjax/true/cb/'+100*Math.random());
}

function updateMGM() {
	var areas = "["; 
	for (var i=1; i<=17; i++) {
		var sub = document.getElementById('category_sub_'+i+'_0');
		var main = document.getElementById('category_main_'+i);
		var areastring = sub.innerHTML;
		
		if(main.className=='crimeTypeMain crimeTypeMainCheck') {
			s = new String(areastring);
			area = s.replace("&nbsp;","");
			if(i=='17') {
				areas += area
			} else {
				areas += area +',';
			}
		}		
	}
	areas +=']';
	
	createMGMap(areas);
} // end function updateMGM()

// delimiter can be undefined
function getCrimeTypeFiltersInString(filterObj, delimiter) {
	if (typeof(delimiter)=='undefined')
		delimiter = null;
	var postString = "";
	if (categoriesInited) {
		for (var n in filterObj) {
			for (var m in filterObj[n]) {
				if (filterObj[n][m]) {
					var id = subcategories[n][m].id;
					if (delimiter)
						postString += (postString?delimiter:'') + id;
					else
						postString += "filter_categories[]=" + id + "&";
				}
			}
		}
	} else {
		postString = "ALL";
		if (!delimiter)
			postString = "filter_categories="+postString+"&";
	}
	return postString;
}

function createPostString(filterObj, dayRange, customDateStart, customDateEnd, mapRadius, coords) {
    var postString = "&";
	postString += getCrimeTypeFiltersInString(filterObj);
	
	postString += 'dayrange='+dayRange+"&";
	postString += 'custom_date_start='+customDateStart+"&";
	postString += 'custom_date_end='+customDateEnd+"&";

	postString += 'mapradius='+mapRadius+"&";
	postString += 'center_lat='+coords['center_lat']+"&";
	postString += 'center_lng='+coords['center_lng']+"&";
	postString += 'address_lat='+coords['address_lat']+"&";
	postString += 'address_lng='+coords['address_lng']+"&";
	
	postString += 'map_minlat=' + map.getBounds().getSouthWest().lat()+"&";
	postString += 'map_maxlat=' + map.getBounds().getNorthEast().lat()+"&"; 
	postString += 'map_maxlng=' + map.getBounds().getNorthEast().lng()+"&";  
	postString += 'map_minlng=' + map.getBounds().getSouthWest().lng()+"&"; 

	if (typeof(areaShapeIds)=='string') {
		postString += 'areaShapeIds='+areaShapeIds+"&";
	}
	postString += 'thematic_shapefile_id=' + (typeof(showThematicView)!='undefined' && showThematicView && thematicShapefileId ? thematicShapefileId : '')+"&";
	
	postString += 'showSO='+showSO; //+ (displayed_categories[1000][0]?'1':'0'); // puts it into session so it remembers this setting across page loads

	return postString;
} // end function createPostString()

window.crimesObj = new crimesObject();

// Create our "tiny" marker icon
var base_crime_icon = new GIcon();
base_crime_icon.iconSize = new GSize(23, 26);
base_crime_icon.iconAnchor = new GPoint(6, 20);
base_crime_icon.infoWindowAnchor = new GPoint(5, 1);

function createCrimeMarker(point, color, trackingNum) {
	// Create a new icon using the icon class

	var icon = new GIcon(base_crime_icon);

	icon.image = htmlbase + "map-icon/map-icon_map1_" + color + ".gif";
	var marker = new GMarker(point, icon);

	if(trackingNum){
        GEvent.addListener(marker, "click", function(multiple) {
            window.supressLoadingDiv = true;
			var infoTabObj = getInfoWindowObj(trackingNum,color,multiple);
			if(infoTabObj) { //otherwise we are crgetInfoWindowObjeating the infotab asynchronously
                marker.openInfoWindowTabsHtml(infoTabObj);
			}
		});
	}

	GEvent.addListener(marker, "remove", function() {
		map.closeInfoWindow();
	});
	
	return marker;
} // end function createCrimeMarker()
/*
function jurisdictionMarker(point, trackingNum, areaName) {
	// Create a new icon using the icon class
    var icon = new GIcon();
	icon.iconSize = new GSize(29,36);
	icon.iconAnchor = new GPoint(26, 36);
	icon.infoWindowAnchor = new GPoint(10, 0);
	icon.image = htmlbase + "images/marker.gif";

	var marker = new GMarker(point, icon);

	GEvent.addListener(marker, "remove", function() {
		map.closeInfoWindow();
	});
	
	GEvent.addListener(marker, "mouseover", function() {
        win = map.getInfoWindow();
		//win.reset(null, null, null, null,null);
		marker.openInfoWindowHtml(areaName);	
	});
	
	GEvent.addListener(marker, "click", function() {
        document.getElementById('searchtext').value = "";
		map.setCenter(point);
		a_lat=point.lat();
		a_lng=point.lng();
		map.setZoom(14);
		loadMap();
		showAllMarkers();
    });
	
	GEvent.addListener(marker, "mouseout", function() {
		map.closeInfoWindow();
	});

	return marker;
} // end function jurisdictionMarker
*/
function overlayCrimes(newCrimes, clearExistingMarkers) {

	//var crimes = xmlObj.getElementsByTagName("crime");
	//if(clearExistingMarkers) map.clearOverlays();
	// have some garbage
	//FIRST GO THROUGH THE OLD MARKERS AND REMOVE ANY WE DON'T WANT ON THE SCREEN

	removecount = 0;
	totalcount = mixedXMLArray.length;
	newcrimescount = newCrimes.length;
	mycount = 2;

	d1 = new Date().getTime();
	
	var times=0;

	function CrimeObject(_obj){
		this.obj = _obj;
	}
	CrimeObject.prototype.toString = function str1() {
		return this.obj.getAttribute('occurrenceid');
	}

	//function for sorting crime arrays by tracking number.  speeds up the search
	var sortC = function sortCrimes(a,b){
		return a['tracking_number'] - b['tracking_number'];
	}
	var tempNewCrimes = new Array();
	var tempCrimesXML = new Array();

	for(i=0;i<newCrimes.length;i++){  //turn object into array to assist in removal of stuff.
		tempNewCrimes[i] = new CrimeObject(newCrimes[i]);
	}
	for(i=0;i<mixedXMLArray.length;i++){  //turn object into array to assist in removal of stuff.
		tempCrimesXML[i] = new CrimeObject(mixedXMLArray[i]);
	}

	var str = "";
	oldI = 0;
	//alert(newCrimes[0].getAttribute("occurrenceid"));
	for(j=0;j<tempCrimesXML.length;j++) {
		//we want to see if this marker already exists
		found = 0;

		for(i=oldI;i<tempNewCrimes.length;i++) {
			if(tempNewCrimes[i].obj.getAttribute("occurrenceid")==tempCrimesXML[j].obj.getAttribute("occurrenceid")) {
				//we already have this marker in the array and we want to keep it
				tempNewCrimes.splice(i,1);  //remove the element so we don't have to go through it again.
				found = 1;
				oldI = i;  //start where we left off.
				break;
			}
		}
		if(!found) {  //we didn't find the old marker in the new array so remove it
			removecount++;
			var trackingNum = tempCrimesXML[j].obj.getAttribute("occurrenceid");
			if(window.crimesObj['marker_'+trackingNum]) {
				map.removeOverlay(window.crimesObj['marker_'+trackingNum]);
				window.crimesObj['marker_'+trackingNum] = null;
			}
		}
	}
	d2 = new Date().getTime();


	//NEXT GO THROUGH THE NEW CRIMES AND ADD THE ONES THAT AREN'T ALREADY CREATED
	for(i=0;i<newCrimes.length;i++) {
		var trackingNum = newCrimes[i].getAttribute("occurrenceid");
		if(window.crimesObj['marker_'+trackingNum]) continue;

		var lat = newCrimes[i].getAttribute("lat");
		var lng = newCrimes[i].getAttribute("lng");
		var markerColor = getMarkerColorSpecial(newCrimes[i].getAttribute("marker_color"));
		

		var point = new GLatLng(lat,lng);
        window.crimesObj['marker_'+trackingNum] = createCrimeMarker(point, markerColor, trackingNum);
        window.crimesObj['marker_'+trackingNum].isMarker=true;
		map.addOverlay(window.crimesObj['marker_'+trackingNum]);
	}
	d3 = new Date().getTime();

} // end function overlayCrimes()

function createInfoObj(crimes, arg, color,multiple) {
    trackingNum = arg;
	
	var kind = '';
	if ((trackingNum+'').indexOf('so')==0) {
		kind = 'so';
	}
	for(i=0;i<crimes.length;i++) {
		if(crimes[i].getAttribute("occurrenceid") == trackingNum) {
			var crimeType = '';
			if (kind == 'so') {
				crimeType = t('REGISTERED SEX OFFENDER');
			} else {
				crimeType = getCrimeTypePretty(crimes[i].getAttribute("type"));
			}
			var offenseDate = crimes[i].getAttribute("offense_date");
			if (offenseDate) { 
				offenseDate = offenseDate.substr(0,11);
			}
			var distanceFromCenter = crimes[i].getAttribute("distance_from_center");
			var address = crimes[i].getAttribute("address");
			var narrative = crimes[i].getAttribute("narrative");
			var ccn = crimes[i].getAttribute("ccn");
			var agencyName = crimes[i].getAttribute("name");
			var imgTagStart = "<img src='"+htmlbase+"bubble/bubble_title-bar_"+color+"_main.gif' style='border: 0px none ; margin: 0px; padding: 0px; position: absolute; left: ";
			var imgTagEnd = "px; top: 0px; width: 900px; height: 26px;' />";
			var headerStyles = "overflow: hidden; position: absolute; top: -15px; height: 26px; ";
			var infoWindowHtml = "<div class='bubble' >";
			infoWindowHtml += "	<div style='" + headerStyles + "left: -16px; width: 21px;'>\n";
			infoWindowHtml += "		" + imgTagStart + "0" + imgTagEnd + "\n";
			infoWindowHtml += "	</div>\n";
			infoWindowHtml += "	<div style='" + headerStyles + "left: 4px; width: 255px;'>\n";
			infoWindowHtml += "		" + imgTagStart + "-19" + imgTagEnd + "\n";
			infoWindowHtml += "	</div>\n";
			infoWindowHtml += "	<div style='" + headerStyles + "left: 259px; width: 21px;'>\n";
			infoWindowHtml += "		" + imgTagStart + "-881" + imgTagEnd + "\n";
			infoWindowHtml += "	</div>\n";
			infoWindowHtml += "	<div style='position: absolute; left: 0px; top: -14px; padding-top: 5px; color: white;'>\n";
			infoWindowHtml += "		<span style='font-weight:bold;' >" + crimeType + "</span>\n"; 
			infoWindowHtml += "	</div>\n";
			infoWindowHtml += "	<div style='width:262px;height:11px;overflow:hidden;'></div>\n";
			if (kind == 'so') {
				var pic_id = crimes[i].getAttribute('pic_id');
				infoWindowHtml += "<div style='width:262px;display:block;'><table cellpadding='0' cellspacing='0' border='0' width='268'>\n";
				infoWindowHtml += "<tr>\n";
				infoWindowHtml += "<td valign='top' style='padding-top:5px;'>";
				if (pic_id && pic_id!='null')
					infoWindowHtml += "<img width=100 style='border:1px solid #ADADAD;' src='"+htmlbase+"map/sopic/?pic_id="+pic_id+"'>";
				infoWindowHtml += "</td>\n";
				var brs='<br>\n'; 
				var replaced= crimes[i].getAttribute('add_info').replace(/\|/g, brs)
				infoWindowHtml += "<td rowspan='4' valign='top' style='padding:5px 0px 0px 5px;'>"+replaced+"</td>\n";
				infoWindowHtml += "</tr>\n";
				infoWindowHtml += "<tr><td>"+crimes[i].getAttribute('f_name')+ " " + crimes[i].getAttribute('m_name') + " " + crimes[i].getAttribute('l_name')+"</td></tr>\n"; 
				infoWindowHtml += "<tr><td><b>"+address+"</b></td></tr>";
				if (crimes[i].getAttribute('orig_url')) {
					infoWindowHtml += "<tr>\n";
					infoWindowHtml += "<td>\n";
					infoWindowHtml += "<p style='margin-bottom:2px;'> <a class='smallActiveText' href='" + crimes[i].getAttribute('orig_url') + "' target='_blank' ><span class='smallActiveText'>"+t("Link")+"</span></a></p>\n";
					infoWindowHtml += "</td>\n";
					infoWindowHtml += "</tr>";
				}
				infoWindowHtml += "</table>\n";
				
				infoWindowHtml += "</div></div>\n";
			
			} else {
				infoWindowHtml += " <div style='width:262px;'>";
				infoWindowHtml += " <p style='font-size:11px; '>" + offenseDate.replace(/ /g, '&nbsp;') + "</p>";
				infoWindowHtml += " <p >" + address + "</p>";
				infoWindowHtml += "	<p><strong>"+t("Distance:")+"</strong> " + distanceFromCenter + t(" miles")+"</p>";
				infoWindowHtml += " <p><strong>"+t("Identifier:")+" </strong>" + ccn + "</p>";
				infoWindowHtml += " <p>" + narrative + "</p>";
				if(agencyName) {
					infoWindowHtml += " <p><strong>"+t("Agency:")+"</strong> " + agencyName + "</p>";
				}
				infoWindowHtml += " <p style='margin-bottom:2px;'> <a class='smallActiveText' href='javascript:void(0);' onclick='lightbox.prototype.show(\"emailcrime\", "+trackingNum+");' ><span class='smallActiveText'>"+t("Send to Friend")+"</span></a>";
				infoWindowHtml += " </div></div>";
				
				//if(multiple) infoWindowHtml += "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a class='smallActiveText' href='javascript:void(0);' onclick='GEvent.trigger(multipleObj["+multiple+"],\"click\")'><span class='smallActiveText'>"+t("Back to Crime List")+"</span></a>";
				infoWindowHtml += "</p>";
			}
			infoWindowHtml += "</div>";
			window.crimesObj['infoTab_'+trackingNum] = [
			new GInfoWindowTab("Information", infoWindowHtml)];
			//new GInfoWindowTab("Submit a Tip", "If you know information that would be <br>helpful in solving this crime, please submit it here.<br><form><input type=textarea class='sbmtTa'><input type=submit value='Submit Tip' class='sbmtTp'></form>")
		}
	}

	window.crimesObj['marker_'+trackingNum].openInfoWindowTabsHtml(window.crimesObj['infoTab_'+trackingNum]);
} // end function createInfoObject()

//Called by a click on the icon marker
function getInfoWindowObj(trackingNum,color,multiple) {
	createInfoObj(mixedXMLArray,trackingNum,color,multiple);
} // end function getInfoWindowObj

function crimesObject(name,val){
	this[name] = val;
}

function findMarkers() {
	alert("window has "+window.length);
	for(i=0;i<window.attributes.length;i++) {
		if(window.attributes[i].isMarker)alert('ismarker');
	}
}

var circ__oldCoords = null;
var circ__distInMiles = null;
var circ__latlngNE = null;
var circ__latlngSW = null;
var showBullseye = false;

function drawCircles(coords) {
        
	if (typeof(coords) == 'undefined' || !coords) {
	    coords = circ__oldCoords;
	} else {
        circ__oldCoords = coords;
        rad = 5;
        orad = rad;
        rad = rad * 1.61//convert to km
		var Cradius = rad;
		var d2r = Math.PI/180;
		var r2d = 180/Math.PI;
		var Clat = (Cradius/6378.8) * r2d;
		var Clng = Clat/Math.cos(coords.lat()*d2r);
        var theta = Math.PI / 4; // 45 degrees
		Cx = coords.lng() + (Clng * Math.cos(theta));
		Cy = coords.lat() + (Clat * Math.sin(theta));
		circ__latlngNE = new GLatLng(parseFloat(Cy),parseFloat(Cx));
		theta = 5 * Math.PI / 4; // 180 + 45 degrees, or 225 degrees
		Cx = coords.lng() + (Clng * Math.cos(theta));
		Cy = coords.lat() + (Clat * Math.sin(theta));
		circ__latlngSW = new GLatLng(parseFloat(Cy),parseFloat(Cx));

		circ__distInMiles = circ__latlngSW.distanceFrom(circ__latlngNE);// returns meters
		//1 meter = 0.000621371192 miles
		circ__distInMiles = circ__distInMiles * 0.000621371192; // convert to miles
	}

	if (!showBullseye) {
	    return;
	}
	if (!coords) {
        return;
	}
	clearPolyOverlays();

	var zoom = map.getZoom();
    if (zoom <= 9) {
        return;
    }
	var mapNormalProj = G_NORMAL_MAP.getProjection();
	var mapZoom = map.getZoom();
	var pixelsNE = mapNormalProj.fromLatLngToPixel(circ__latlngNE, mapZoom);
	var pixelsSW = mapNormalProj.fromLatLngToPixel(circ__latlngSW, mapZoom);
	pixelDist = Math.sqrt(Math.pow(pixelsNE.x-pixelsSW.x, 2) + Math.pow(pixelsSW.y-pixelsNE.y, 2));
			
	var pixPerMi = pixelDist/circ__distInMiles;
	
	var imgWidth = 474;
	var imgHeight = 474;
	var pixelLoc = mapNormalProj.fromLatLngToPixel(coords, mapZoom);
	var swBound = mapNormalProj.fromPixelToLatLng(new GPoint(pixelLoc.x-(imgWidth/2), pixelLoc.y+(imgHeight/2)), mapZoom);
	var neBound = mapNormalProj.fromPixelToLatLng(new GPoint(pixelLoc.x+(imgWidth/2), pixelLoc.y-(imgHeight/2)), mapZoom);
	//alert(htmlbase + 'map/bullseye?pixPerMi='+pixPerMi);
	
	var beye = new GGroundOverlay(htmlbase + 'map/bullseye?pixPerMi='+pixPerMi, new GLatLngBounds(swBound, neBound));
	polyoverlays.push(beye);
	map.addOverlay(beye);
	return;

/*
	//draws circles that are always at .25, .5, .75, and 1 mile radius, no matter the zoom level
	if (zoom <= 9)
		return;
	var radii = [.25, .5, .75, 1];
	for (var z = 0; z < radii.length; z++) {
		polys = drawHomeOverlayCircle(Math.round(coords.lat()*1000000)/1000000, Math.round(coords.lng()*1000000)/1000000, radii[z], false, false, 0, true, true);
		for (var i in polys) {
			polyoverlays.push(polys[i]);
		}
	}
	
	*/			
} // end function drawCircles()

function makeBullseyePrintable(){
	//this gets the bullseye and makes it printable.
	var overLayer = map.getPane(G_MAP_OVERLAY_LAYER_PANE);
	var divs = overLayer.getElementsByTagName('DIV');
	for(var i = 0; i < divs.length; i++){
		//google adds the div with a classname gnoprint we kill that.
		divs[i].className = '';
	}
}
function printMap(){
	makeBullseyePrintable();
	window.print();
}

// manageoverlay is optional, defaults to true!
// fillopacity is optional, defaults to 0.15
function drawHomeOverlayCircle(lat, lng, rad,changeZoom, manageoverlay, fillopacity, line, showscale) {
	//alert('lat: '+lat+','+lng);
	//try {
	if (typeof(manageoverlay)=='undefined')
		manageoverlay = true;
	if (typeof(fillopacity)=='undefined')
		fillopacity = 0.15;
	if(window.homeRadius && manageoverlay)map.removeOverlay(homeRadius);
	orad = rad;
	rad = rad * 1.61//convert to km
	var Cradius = rad;
	var d2r = Math.PI/180;
	var r2d = 180/Math.PI;
	var Clat = (Cradius/6378.8) * r2d;

	var Clng = Clat/Math.cos(lat*d2r);
	var CpointsLatLng = [] ;

	var minlatlng = null;
    //str = "";

	for (var i = 0 ; i < 100 ; i++) {
		var theta = Math.PI * (i/50) ;
		Cx = lng + (Clng * Math.cos(theta));
		Cy = lat + (Clat * Math.sin(theta));
		//str += "("+Cx+","+Cy+"),";
		var latlng = new GLatLng(parseFloat(Cy),parseFloat(Cx));
		if (minlatlng == null || latlng.lat() < minlatlng.lat()) {
			minlatlng = latlng;
		}
		CpointsLatLng.push(latlng);
	}

//alert(str);
	if (CpointsLatLng.length) // complete the circle, by adding the first point again
		CpointsLatLng.push(CpointsLatLng[0]);


	// color is defined elsewhere
	var poly = null;
	if (line)
		poly = new GPolyline(CpointsLatLng, '#000000', 2, 0.5);
	else
		poly = new GPolygon(CpointsLatLng, '#000000', 2, 0.5, '#ff0000', fillopacity, true);
	map.addOverlay(poly);
	var polys = [poly];

	var mapZoom = map.getZoom();
	if (showscale && mapZoom >= MIN_ZOOM_WITH_MARKERS) {
		var mapNormalProj = G_NORMAL_MAP.getProjection();
		var pixelLoc = mapNormalProj.fromLatLngToPixel(minlatlng, mapZoom);
		var imgWidth = 44;
		var imgHeight = 16;
		var swBound = mapNormalProj.fromPixelToLatLng(new GPoint(pixelLoc.x-(imgWidth/2), pixelLoc.y), mapZoom);
		var neBound = mapNormalProj.fromPixelToLatLng(new GPoint(pixelLoc.x+(imgWidth/2), pixelLoc.y-imgHeight), mapZoom);
		
		//alert(htmlbase + 'map-icon/mi_'+orad +'.png');
		scale = new GGroundOverlay(htmlbase + 'map-icon/mi_'+orad +'.png', new GLatLngBounds(swBound, neBound));
		polys.push(scale);
		map.addOverlay(scale);
    }

	//} catch (e) { alert(e); }
	if (manageoverlay)
		window.homeRadius = poly;
	if(changeZoom) {
		//pnt = window.map.getCenter();
		//window.map.setCenter(pnt,16);
		zoom_level=0;
		switch (parseInt(orad)) {
			case .5:
			zoom_level=15;
			break;
			case 1:
			zoom_level=14;
			break;
			case 2:
			zoom_level=13;
			break;
			case 3:
			zoom_level=12;
			break;
			case 4:
			zoom_level=12;
			break;
			case 5:
			zoom_level=12;
			break;
			default:
			zoom_level=14;
			break;
		}
		map.setZoom(zoom_level);
	}
	return polys;
}  // end function drawHomeOverlayCircle()

var mixedXMLArray = new Array();

function parseXML(xmlText) {

	if (window.ActiveXObject) {
		var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(xmlText);
	} else if (document.implementation && document.implementation.createDocument) {
		var parser=new DOMParser();
		var xmlDoc=parser.parseFromString(xmlText,"text/xml");
	}

	xmlObj=xmlDoc.documentElement;
	return xmlObj;
}

var addCrimeArray = new Array();
var removeCrimeArray = new Array();
var interruptAddRemove = false;
var crimelistXMLArray = new Array();  //THIS IS THE ARRAY THE LEFT HAND CRIME LIST USES.  It can be sorted, etc.
var solistXMLArray = new Array();  //THIS IS THE ARRAY THE LEFT HAND S.O. LIST USES.  It can be sorted, etc.

var subcategories = new Object();
var main_categories = new Object();

function subcategory(name, categoryid, index) { // categoryid is NOT unique
	this.name = name;
	this.id   = categoryid;
	this.categoryid   = categoryid;
	this.index = index;
}
var categoriesInited = false;

function pushSubCategoriesToDisplay(defaults) {
	for (var i = 1; ; i++) {
		var ele = document.getElementById('subcatsCol'+i)
		if (!ele) {
			break;
		}
		ele.innerHTML = ''; // clear them out to start with
	}
	var ndisplayed_categories = new Object();
		
	for (var i in subcategories) {
		var subOn = '';
		if (defaults === -1) {
			if(main_categories[i].on == 1) {
				subOn = "crimeTypeSubCheck";
			}
		}
		var str = "";
		str += "<div class='crimeGroup'>";
		ndisplayed_categories[i] = new Object();
		var subcatstr = "";
		var allOn = true;
		var atLeastOneOn = false;
	
		for (var j=0; j<subcategories[i].length; j++) {
			if (defaults !== -1) {
				subOn = '';
				if (typeof(displayed_categories[i])!='undefined') {
					if (displayed_categories[i][j])
						subOn = "crimeTypeSubCheck";
				} else if (defaults[subcategories[i][j].id]) {
					subOn = "crimeTypeSubCheck";
				}
				allOn = allOn && (subOn != '');
				atLeastOneOn = atLeastOneOn || (subOn != '');
			}

			if (subOn!='') {
                ndisplayed_categories[i][j] = true;
			}
			subcatstr += "		<div class='crimeTypeSub "+subOn+"' id='category_sub_"+i+"_"+j+"' onclick='toggleSubCategory("+i+","+j+");' style='"+(subcategories[i].length == 1 ? 'display:none;':'')+"' >"+t(subcategories[i][j].name)+"</div>";
		}
		
		var mainOn = '';
		if (defaults === -1) {
			if(main_categories[i].on == 1){
				mainOn = "crimeTypeMainCheck";
			}
		} else {
			if (allOn) {
				mainOn = "crimeTypeMainCheck";
			} else if (atLeastOneOn) {
				mainOn = "crimeTypeMainPartial";
			}
		}
		str += "	<div class='crimeTypeMain "+mainOn+"' id='category_main_"+i+"' onclick='toggleMainCategory("+i+");'>"+t(main_categories[i].name)+"</div>";
		str += subcatstr;
		str += "</div>";
		var colDiv = document.getElementById('subcatsCol'+main_categories[i].column);
		colDiv.innerHTML += str;
		
	}
	displayed_categories = ndisplayed_categories;
} // end function pushSubCategoriesToDisplay

			
var responseSuccess = function(o) {
	/* Please see the Success Case section for more
	* details on the response object's properties.
	* o.tId
	* o.status
	* o.statusText
	* o.getResponseHeader[ ]
	* o.getAllResponseHeaders
	* o.responseText
	* o.responseXML
	* o.argument
	*/
	//alert(o.responseText);
	errMessage="";
	errType="DISPLAY";
	var outOfArea = false;
	var searchResultsCrimes = document.getElementById("searchResultsCrimes");
	var newSOXMLArray = null;
	var showingSoData = false; //trying to make this accessible for the entire response function.
	
	var anXMLObj = parseXML(o.responseText);
	if (anXMLObj)
		var catsList = anXMLObj.getElementsByTagName('categories');

    //GLog.write(o.responseText);
	if (o.argument[0] == 'crimesubtypes' || (catsList!=null && catsList.length > 0)) {
		//GLog.write(o.responseText);
		try {
			var categoriesElement = anXMLObj.nodeName == 'categories' ? anXMLObj : catsList[0];
			var defaults = new Object(); // if this stays empty, it means use no filters at all (unless useDefaults is true)
			var useDefaults = false;
			var defaultIsSet = false;
			if (categoriesElement.getAttribute('defaults') == "true") {
				useDefaults = true; // use default filters
			}
			var categories = anXMLObj.getElementsByTagName("category");
			if (categories != null && categories.length > 0) {
				main_categories = new Object();
				subcategories = new Object();
				for (var i = 0; i < categories.length; i++) {
					//alert('categories[i] :' + categories[i]);
					var catid = categories[i].getAttribute('categoryid');
					main_categories[catid] = new category(
							categories[i].getAttribute('name'),
							categories[i].getAttribute('categoryid'),
							categories[i].getAttribute('default_on'),
							categories[i].getAttribute('display_column'));
					var types = categories[i].getElementsByTagName("type");
					if (types != null && types.length > 0) {
						subcategories[catid] = new Array();
						for (var j = 0; j < types.length; j++) {
							if (types[j].getAttribute('selected') == 'true') {
								defaults[types[j].getAttribute('crimeid')] = true;
								defaultIsSet = true;
							}
							subcategories[catid].push({id:types[j].getAttribute('crimeid'),name:types[j].childNodes[0].nodeValue});
						}
					}
				}
                

				pushSubCategoriesToDisplay( useDefaults && !defaultIsSet ? -1 : defaults );
				categoriesInited = true;
				
				if(!crimefiltersLoaded) {
				    crimefiltersLoaded = true;
					//TMR loadMap was interfering with alert links.
					if(a_mapid == null) /**alert('loading map');/**/ loadMap();
				}
			}
		
			//adjustCrimeTypes(areasForCrimeTypeAdjusting);
		} catch (e) {
			/*
			alert(e.name+" : "+e.message + " --- "+e);
			//*/
		}
	}
	if (o.argument[0] == 'crimesubtypes') {
		return;
	}
		crimesXMLObj = anXMLObj;
		if(o.argument[0] == 'singlecrime') {
            
			newCrimesXMLArray = crimesXMLObj.getElementsByTagName("crime");
			if(newCrimesXMLArray.length==1) {
			    addressCoords = new GLatLng(newCrimesXMLArray[0].getAttribute('lat'),newCrimesXMLArray[0].getAttribute('lng'));
				//map.setCenter(addressCoords,14);
	            a_lat = newCrimesXMLArray[0].getAttribute('lat');
	            a_lng = newCrimesXMLArray[0].getAttribute('lng');
				changeObjectDisplay("instructionDiv","none");
				//changeObjectDisplay("filterdiv","block");
			}
		} else {
			
			interruptAddRemove = true;

			var crimesNodeValue = "";
			var offendersNodeValue = "";
			try {
				crimesNodeValue = crimesXMLObj.getElementsByTagName('crimes')[0].childNodes[0].nodeValue;
			} catch (e) {}
			try {
				var offendersNode = crimesXMLObj.getElementsByTagName('offenders')[0];
				//hide sex offender button for any address outside the US
				try {
					if(String(offendersNode.getAttribute('showsocheckbox')).toLowerCase()=='true' || offendersNode.getAttribute('showsocheckbox')=='1')
						showingSoData = true; //used throughout the reponse success function
					if(showingSoData) {
						document.getElementById('socheckbox').style.display="block";
					} else {
						document.getElementById('socheckbox').style.display="none";
					}
				} catch(e) {
					document.getElementById('socheckbox').style.display="none";
				}

				offendersNodeValue = offendersNode.childNodes[0].nodeValue;
			} catch (e) {}
			newCrimesXMLArray = crimesXMLObj.getElementsByTagName("crime");
            //alert(crimesNodeValue);
			
			//Handle how to render results based on if crimeData or soData is empty
			
			if(o.responseText=="Error" || crimesNodeValue =='Error' || offendersNodeValue == 'Error') {
				if (o.responseText=="Error" || crimesNodeValue =='Error')
					crimesXMLObj = parseXML("<crimes></crimes>");
				errMessage = t("There was an error");
				errType = "ERROR";
			} else if(o.responseText=="Out Of Area" || crimesNodeValue =="Out Of Area" || newCrimesXMLArray.length==0) {
				//isInvited();
				if (o.argument.length >= 5 && o.argument[4]) { // o.argument[4] is the fromNewSearch value
					var c = new CookieHandler(); //see utility.js for usage
					cookie = c.getCookie('askDept');
					//Added && false temporarily till this logic can be fixed
					if (!cookie && false) {
						if (typeof(showThematicView)=='undefined' || !showThematicView || !thematicShapefileId) { // if they have seleced thematic view, it means the pd is already participating or else they wouldnt have uploaded shapefiles
							//errMessage = sprintf(t("Why isn't there any crime data?  Your local PD isn't providing us any data.  Ask them to %s join %s"), "<a href='javascript:void(0);' onclick='lightbox.prototype.showme(\"askdept\", 0);'>", "</a>");
							//errType = "DISPLAY";
							lightbox.prototype.showme("askdept", 0);
						}
					}
				}
				
				if(offendersNodeValue == "Out Of Area" && crimesNodeValue =="Out Of Area") {
					crimesXMLObj = parseXML("<crimes></crimes>");
					var noDataMessage = '<div style="padding:10px;padding-right:25px;">';
					noDataMessage += '<h5 class="blue_text">'+t('Why are there no crimes listed for my search?')+'</h5>';
					noDataMessage += '<p>'+t('The law enforcement agency for this area is not yet providing data. We are working to collect crime data as soon as possible. You can help by inviting the police department to participate.')+'</p>';
					noDataMessage += '<p style="text-align:right;"><a href="'+htmlbase+'company/askDept" class="mediumActiveText"><img src="'+htmlbase+'img/btn_invite-department.gif" border="0" alt="'+t('Invite Department')+'" /></a></p>';
					noDataMessage += '<h5 class="blue_text" style="padding-top:10px;">'+t('How will I know when my department is participating?')+'</h4>';
					noDataMessage += '<p>'+t("Join CrimeReports now (it's free) and we will notify you when your department starts providing data.")+'</p>';
					noDataMessage += '<p style="text-align:right;"><a href="'+htmlbase+'user/register" class="mediumActiveText"><img src="'+htmlbase+'img/btn_join-now-for-free.gif" border="0" alt="'+t('Join Now for Free')+'" /></a></p>';
					noDataMessage += '</div>';
					searchResultsCrimes.innerHTML = noDataMessage;
					outOfArea = true;
				}
				
				//Out of Area seems to be an unreliable indicator if you consider both crimeData and SOData
				//use newCrimesXMLArray.length to determine if there is no crime Data but there is SO Data
				//show disclaimer if this is the case. 
			    //FB 104 ENDED UP DISABLED
				//if(newCrimesXMLArray.length==0 && showingSoData){
					//soDataWithoutCrimeDataTerms();
				//}
			}

			
			changeObjectDisplay("filterdiv","block");
			
			if(newCrimesXMLArray.length == 500) {
				errMessage = t("You are currently viewing the most recent 500 incidents that match your preferences.")+" <br>"+t("You may need to narrow your search.");
				errType = "DISPLAY";
			}

			newSOXMLArray = crimesXMLObj.getElementsByTagName("offender");
			
		}
		//var areas = crimesXMLObj.getElementsByTagName("area");
		//adjustCrimeTypes(areas);

		if(crimesXMLObj) {
			try {
				var states = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('state');
				statesArr = states.split(',');
				var wasFound = false;
				if (statesArr.length) {
					for (var k = 0; k < statesArr.length; k++) {
						if (statesArr[k].toUpperCase() == 'UT') {
							wasFound = true;
							document.getElementById('UTAttorney').style.display='block';
							document.getElementById('headerSeoText').style.display='none';
							break;
						}
					}
					
					if (!wasFound){
						document.getElementById('UTAttorney').style.display='none';
						document.getElementById('headerSeoText').style.display='block';
					}
				}
			} catch(e) {}
		}

		if (typeof(areaShapeIds)!='undefined' && !areaShapeIds) {
			var hasShapefiles = false;
			try {
				hasShapefiles = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('hasShapefiles').toLowerCase() == 'true';
			} catch (e) {}
			var areaFilter = document.getElementById('areaFilterContainerAll');
			if (areaFilter) {
				var thematicChecked = (typeof(showThematicView)!='undefined' && showThematicView && thematicShapefileId);
				areaFilter.style.display = hasShapefiles || thematicChecked || areaShapeIds ? 'block':'none';
				var thematicCheckbox = document.getElementById('thematicContainerAll');
				if (thematicCheckbox) {
					thematicCheckbox.style.display = hasShapefiles ? 'block':'none';
					document.getElementById('thematicChecked').checked = thematicChecked;
				}
			}

		}

		try {
			var doIt = false;
			var link = document.getElementById('downloadDataLink');
			try {
				var tabularAllowAccess = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('tabularDataAccess').toLowerCase() == 'true';
				var area_id = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('id');
				var startDate = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('startDate');
				var endDate = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('endDate');
				doIt = (tabularAllowAccess && startDate && endDate && area_id);
				if (doIt) {
					link.href = "/analytics/incidentData?startdate="+startDate+"&enddate="+endDate+"&areaid="+area_id+"&crimetypes="+getCrimeTypeFiltersInString(displayed_categories, ',');
				}
			} catch (e) { }
			link.style.display = doIt ? 'block' : 'none';
		} catch(e) {}
	
	searchResultsCrimes.setAttribute('outofarea', outOfArea ? 'true' : 'false');

	///NEW STUFF

	temp = newCrimesXMLArray.length;
	function CrimeObject(_obj){
		this.obj = _obj;
	}
	CrimeObject.prototype.toString = function str1() {
		return this.obj.getAttribute('occurrenceid');
	}

	//function for sorting crime arrays by tracking number.  speeds up the search

	var tempNewMixed = new Array();
	var tempMixedXML = new Array();
	crimelistXMLArray = new Array();
	solistXMLArray = new Array();

	for(i=0;i<newCrimesXMLArray.length;i++){  //turn object into array to assist in removal of stuff.
		tempNewMixed[i] = new CrimeObject(newCrimesXMLArray[i]);
		crimelistXMLArray[i] = new CrimeObject(newCrimesXMLArray[i]);
	}
	for(i=0;i<newSOXMLArray.length;i++) {
		tempNewMixed.push(new CrimeObject(newSOXMLArray[i]));
		solistXMLArray[i] = new CrimeObject(newSOXMLArray[i]);
	}

	for(i=0;i<mixedXMLArray.length;i++){  //turn object into array to assist in removal of stuff.
		tempMixedXML[i] = new CrimeObject(mixedXMLArray[i]);
	}
	
	setChangingOverlays(tempNewMixed,tempMixedXML);

	//document.getElementById('searchResults').innerHTML = t("Loading...");
	if (!outOfArea) {
		document.getElementById('searchResultsCrimes').innerHTML = "<img src='" + htmlbase + "images/loading.gif'>&nbsp;"+t('Loading')+" . . . ","DISPLAY";
	}
	interruptAddRemove = false;
	mixedXMLArray = new Array(); 
	for (i=0;i<newCrimesXMLArray.length;i++) {
		mixedXMLArray.push(newCrimesXMLArray[i]);  //save the crime array as a global variable.
	}
	for (i=0;i<newSOXMLArray.length;i++) {
		mixedXMLArray.push(newSOXMLArray[i]); //save the crime array as a global variable.
	}
	
	//alert(o.responseText);
	
	if(mixedXMLArray.length==0 && !outOfArea){
		changeObjectDisplay("instructionDiv","block");
	} else {
		changeObjectDisplay("instructionDiv","none");
	}
	addRemoveMarkers(10);
	if (typeof(showThematicView)=='undefined' || !showThematicView || !thematicShapefileId)
		window.setMessage(errMessage,errType);
	
	if(crimesXMLObj.getElementsByTagName("area")[0].getAttribute('totalcount')!=-1) {
		//window.setMessage("Total area crime count: "+crimesXMLObj.getElementsByTagName("area")[0].getAttribute('crimecount')+" of "+crimesXMLObj.getElementsByTagName("area")[0].getAttribute('totalcount')+" (based on current date and crime type selection)", "DISPLAY");
		document.getElementById('crimesnum').innerHTML=crimesXMLObj.getElementsByTagName("area")[0].getAttribute('crimecount');
	}
	startDateText = fromYYYYMMDDtoMMDDYYYY(a_startdate);
	endDateText = fromYYYYMMDDtoMMDDYYYY(a_enddate);
	
	if(a_mapid) {
		if(a_startdate == a_enddate) {
			dateText = sprintf(t("You are viewing a crime map based on your alert dated %s."), fromYYYYMMDDtoMMDDYYYY(a_startdate));
		} else {
			dateText = sprintf(t("You are viewing a crime map based on your alert dated %s through %s."), fromYYYYMMDDtoMMDDYYYY(a_startdate), fromYYYYMMDDtoMMDDYYYY(a_enddate));
		}
		setMessage(dateText, "DISPLAY");
	}
	
} // end responseSuccess

function getMarkerColorSpecial(color) {
	return color;
}
function getCrimeTypePretty(crimeType) {
	return t(crimeType);
}
/*
// for renaming crime types depending on pd
function getMarkerColorSpecial(color) {
	if (useCanadaCrimeTypes && color == 'aqua') {
		return 'aqua2';
	}
	return color;
}

function getCrimeTypePretty(crimeType) {
	if (useCanadaCrimeTypes)
		return t(getCanadaVersion(crimeType));
	else return t(crimeType);
}

function getCanadaVersion(crimeType) {
	if (crimeType=='BURGLARY') {
		return 'BREAKING & ENTERING';
	} else if (crimeType=='VEHICLE BURGLARY') {
		return 'THEFT FROM VEHICLE';
	} else return crimeType;
}

var useCanadaCrimeTypes = false;
var canadianPDids = {310:true, 331:true}; //  ottawa,Ontario and Brandon, Manitoba

// areas can be an array of areaids or it can be an array of xml objects that have an 'id' attribute
function adjustCrimeTypes(areas) {
	var showCanadian = false;
	var numReg = 0;
	for (var i = 0; i < areas.length; i++) {
		try {
			id = areas[i].getAttribute('id');
		} catch(e) {
			id = areas[i];
		}
		if (canadianPDids[id]) {
			showCanadian = true;
		} else {
			numReg++;
		}
	}
	useCanadaCrimeTypes = (showCanadian && !numReg);
	$('category_sub_101_1').style.display = useCanadaCrimeTypes?'none':'block'; // hide or show Rape
	$('category_main_84').innerHTML = useCanadaCrimeTypes?t('Breaking & Entering'):t('Burglary');
	$('category_main_106').innerHTML = useCanadaCrimeTypes?t('Theft From Vehicle'):t('Vehicle Burglary');
	
}
// */

var responseFailure = function(o) {
	//document.getElementById('loadingDiv').style.display='none';
	//window.setMessage( window.serverAddr, "ERROR");
	/* str = "in response error, \n";
	for (var i in o) {
		str += " o["+i+"] = "+o[i]+"\n";
	}
	alert(str); */

	if (typeof o.argument[1] == 'function') {
		o.argument.shift();
		var fn = o.argument.shift();
		typeof fn.apply(null, o.argument);
	}
}
Array.prototype.binarySearch = function(item) {
	var left = -1,
	right = this.length,
	mid;

	while(right - left > 1) {
		mid = (left + right) >>> 1;
		//if(parseInt(this[mid]) < parseInt(item))
		if(compareItem(this[mid], item) > 0) {
            left = mid;
		} else {
            right = mid;
        }
	}
	//if(parseInt(this[right]) != parseInt(item))
	if(compareItem(this[right], item) != 0) {
        return -(right + 1);
    }
	return right;
}

// compareItem returns -1 if left > right,
//		1 if right > left, and 0 if they are equal
function compareItem(left, right) {
	if (left+'' == right+'') {
		return 0;
	}
    var kindLeft = '';
    if ((left+'').indexOf('so') == 0) {
        kindLeft = 'so';
    }

	var kindRight = '';
    if ((right+'').indexOf('so') == 0) {
        kindRight = 'so';
    }

    if (kindLeft == kindRight) {
        var numLeft = left;
		var numRight = right;
		if (kindLeft == 'so') {
			numLeft = (numLeft+'').substring(3);
			numRight = (numRight+'').substring(3);
		}
		numLeft = parseInt(numLeft);
		numRight = parseInt(numRight);
        return (numLeft > numRight) ? -1 : 1;
    }
	if (kindRight == 'so') {
		return 1;
	}
	return -1; // it means kindLeft == 'so' and kindRight == ''
} // end function compareItem


//This function is to return an array of markers that need to be added.  Markers that already are overlayed are removed from the array
function setChangingOverlays(newCrimes, currCrimes) {
    
	oldI = 0;
	times = 3;

	//newCrimes.reverse();
	//currCrimes.reverse();

	//remove any addcrimes that might be queued that we don't need because of dragging
	for(i=addCrimeArray.length-1;i>=0;i--){
		crimeIndex = newCrimes.binarySearch(addCrimeArray[i].obj.getAttribute("occurrenceid"));
		if(crimeIndex<0){
			addCrimeArray.splice(i,1);
			//newCrimes.splice(crimeIndex,1);
		}
	}
	for(j=0;j<currCrimes.length;j++) {
		//we want to see if this marker already exists
		crimeIndex = newCrimes.binarySearch(currCrimes[j].obj.getAttribute("occurrenceid"));
		if(crimeIndex >= 0) { //we have found an old marker in the new list, so we don't want to add it again.
			//we already have this marker in the array and we want to keep it
			newCrimes.splice(crimeIndex,1);  //remove the element so we don't have to go through it again.
			//found = 1;
			//oldI = i;  //start where we left off.
		} else {
			removeCrimeArray.push(currCrimes[j]);
		}
	}

	//search through remove crime list for new crimes that maybe tagged for deletion
	times = 0;
	for(i=removeCrimeArray.length-1;i>=0;i--) {
		crimeIndex = newCrimes.binarySearch(removeCrimeArray[i].obj.getAttribute("occurrenceid"));
		///alert('crimeIndex = ' + crimeIndex);
		if(crimeIndex>=0) {
			times++;
			removeCrimeArray.splice(i,1);
			//newCrimes.splice(crimeIndex,1);
		}
	}
	//document.getElementById("debugdiv").innerHTML = times;
	//add whats left of our new crimes to the add list
	addCrimeArray = newCrimes.concat(addCrimeArray);

} // end function setChangingOverlays()


function zzz(a,b){
	return 10000;
	//return a.Zindex;
}

var multipleObj = Array();

function addRemoveMarkers(loadNum) {
	//do the add first.  if these are all done, then go on to removes

	zoomlevel = map.getZoom()<MIN_ZOOM_WITH_MARKERS;
	
	addAmount = Math.min(loadNum,addCrimeArray.length);
	if(interruptAddRemove) { return };
	for(i=0;i<addAmount;i++) {
		var kind = '';
		if (addCrimeArray[i].obj.nodeName == 'crime') {
			if(addCrimeArray[i].obj.getAttribute("precision1")==1 || addCrimeArray[i].obj.getAttribute("precision1")==0) {
				kind = addCrimeArray[i].obj.nodeName;
			}
		} else if (addCrimeArray[i].obj.nodeName == 'offender') {
				kind = addCrimeArray[i].obj.nodeName;
		}
		if (kind != '') {
            var trackingNum = addCrimeArray[i].obj.getAttribute("occurrenceid");
			if(window.crimesObj['marker_'+trackingNum]) continue;
		
			var lat = addCrimeArray[i].obj.getAttribute("lat");
			var lng = addCrimeArray[i].obj.getAttribute("lng");
			var markerColor = 'sex-offender';
			if (kind == 'crime') {
                markerColor = getMarkerColorSpecial(addCrimeArray[i].obj.getAttribute("marker_color"));
			}
            var point = new GLatLng(lat,lng);
		
			window.crimesObj['marker_'+trackingNum] = createCrimeMarker(point, markerColor, trackingNum);
			window.crimesObj['marker_'+trackingNum].isMarker=true;
		
			map.addOverlay(window.crimesObj['marker_'+trackingNum]);
			if(zoomlevel) {
                window.crimesObj['marker_'+trackingNum].hide();
            }
		}
	}

	if(addAmount) {
        addCrimeArray.splice(0,addAmount);
	}
	if(interruptAddRemove) { return };
	//actual removal
	removeAmount = 0;
	if(addAmount < loadNum) {
		removeAmount = Math.min(loadNum-addAmount,removeCrimeArray.length);
		for(i=0;i<removeAmount;i++) {
			var trackingNum = removeCrimeArray[i].obj.getAttribute("occurrenceid");
			if(window.crimesObj['marker_'+trackingNum]){
				map.removeOverlay(window.crimesObj['marker_'+trackingNum]);
				window.crimesObj['marker_'+trackingNum] = null;
			}
		}
	}

	if(removeAmount) {
        removeCrimeArray.splice(0,removeAmount);
	}

	//DEBUG
	//document.getElementById("debugdiv").innerHTML = "A: "+addCrimeArray.length+" R: "+removeCrimeArray.length;
	//start the timer over again if necessary
	if(interruptAddRemove) {
        return;
	}
	if(addCrimeArray.length || removeCrimeArray.length) {
		setTimeout(function(){addRemoveMarkers(10);},100);
	} else {
        loadCrimeList(crimelistXMLArray);
		loadSOList(solistXMLArray);
		updateResultsTabs();
		
		//TMR MULTIPLE MARKERS
		var multipleArray = {};
		var arrsToProcess = [crimelistXMLArray, solistXMLArray];
		for (j=0;j<arrsToProcess.length;j++) {
			for(i=0;i<arrsToProcess[j].length;i++) {
				var kind = '';
				if (arrsToProcess[j][i].obj.nodeName == 'crime') {
					if(arrsToProcess[j][i].obj.getAttribute("precision1")==1 || arrsToProcess[j][i].obj.getAttribute("precision1")==0){
						kind = arrsToProcess[j][i].obj.nodeName;
					}
				} else if (arrsToProcess[j][i].obj.nodeName == 'offender') {
						kind = arrsToProcess[j][i].obj.nodeName;
				}
				if (kind != '') {
					var lat = parseFloat(arrsToProcess[j][i].obj.getAttribute("lat")).toFixed(5);
					var lng = parseFloat(arrsToProcess[j][i].obj.getAttribute("lng")).toFixed(5);
					
					if(multipleArray[lat+","+lng]){
						multipleArray[lat+","+lng].push(arrsToProcess[j][i]);
					}else{
						multipleArray[lat+","+lng] = Array();
						multipleArray[lat+","+lng].push(arrsToProcess[j][i]);
					}
				}
			}
		}
		//remove all multiple objects and re-add
		if(multipleObj.length) {
			i=0;
			for(i=0;i<multipleObj.length;i++) {
				map.removeOverlay(multipleObj[i]);
			}
			multipleObj = Array();
		}
		j = 0;

		for(i in multipleArray) {
			// HACK to fix prototype for IE. element i = 'grep' and 'inject', remove prototype functionality from this loop
			if(multipleArray[i].length > 1 && i!='grep' && i!='inject') {
				//add a multiple marker
				
				var lat = parseFloat(multipleArray[i][0].obj.getAttribute("lat")).toFixed(5);
				var lng = parseFloat(multipleArray[i][0].obj.getAttribute("lng")).toFixed(5);
				point = new GLatLng(lat,lng);
				
				var icon = new GIcon(base_crime_icon);
				icon.image = htmlbase + "map-icon/map-icon_map1_multiple.gif";
				
				var marker = new GMarker(point,{icon:icon,zIndexProcess:zzz});
				
				marker.Zindex = 15000 + i;
				marker.mid = "multiple";
				marker.multipleIndex = multipleObj.length;
				
				multipleObj.push(marker);
				
				GEvent.addListener(marker, "click", function() {
					//tmr iterate multipleArray
					
					window.supressLoadingDiv = true;
					mpoint = this.getPoint();
					latlng = parseFloat(mpoint.lat()).toFixed(5) + "," + parseFloat(mpoint.lng()).toFixed(5);
					
					marray = multipleArray[latlng];
					
					var imgTagStart = "<img src='"+htmlbase+"bubble/bubble_title-bar_multiple_main.gif' style='border: 0px none ; margin: 0px; padding: 0px; position: absolute; left: ";
					var imgTagEnd = "px; top: 0px; width: 900px; height: 26px;' />";
					var headerStyles = "overflow: hidden; position: absolute; top: -15px; height: 26px; ";
					var infoWindowHtml = "<div class='bubble' >";
					infoWindowHtml += "	<div style='" + headerStyles + "left: -16px; width: 21px; '>\n";
					infoWindowHtml += "		" + imgTagStart + "0" + imgTagEnd + "\n";
					infoWindowHtml += "	</div>\n";
					infoWindowHtml += "	<div style='" + headerStyles + "left: 4px; width: 100%;'>\n";
					infoWindowHtml += "		" + imgTagStart + "-19" + imgTagEnd + "\n";
					infoWindowHtml += "	</div>\n";
					infoWindowHtml += "	<div style='" + headerStyles + "right: -17px; width: 21px;'>\n";
					infoWindowHtml += "		" + imgTagStart + "-881" + imgTagEnd + "\n";
					infoWindowHtml += "	</div>\n";
					infoWindowHtml += "	<div style='position: absolute; left: 0px; top: -14px; padding-top: 5px; color: white;'>\n";
					infoWindowHtml += "		<span style='font-weight:bold;' >"+t("MULTIPLE ITEMS")+"</span>\n";
					infoWindowHtml += "	</div>\n";
					infoWindowHtml += "	<div style='width:430px;height:9px;overflow:hidden;'></div>\n";
					infoWindowHtml += "<table cellpadding='0' cellspaceing='0' border='0' style='width: 430px; height: 200px;'><tr>";
					infoWindowHtml += "<td valign='top' style='width:135px;'><div id='bubbleList' style='height: 200px; overflow-y:scroll;'>";
//					infoWindowHtml += "<td valign='top' style='width:135px;'><div id='bubbleList' style='height: 200px; overflow-y:hidden;'>";
					j=0;
					for(j=0;j<marray.length;j++){
						offenseDate = marray[j].obj.getAttribute("offense_date");
						if (offenseDate) {
							offenseDate = offenseDate.substr(0,11);
						}
						infoWindowHtml += "<p><a href='javascript:void(0)' onclick='showinfo(\""+marray[j].obj.getAttribute("occurrenceid")+"\",\""+this.multipleIndex+"\")'>";
						
						if (marray[j].obj.nodeName == 'offender') {
							infoWindowHtml += t("SEX OFFENDER")+" &mdash;<br\> "+marray[j].obj.getAttribute("f_name")+" "+marray[j].obj.getAttribute("m_name")+" "+marray[j].obj.getAttribute("l_name")+"</a>";
						} else {
							var crType = getCrimeTypePretty(marray[j].obj.getAttribute("type"));
							infoWindowHtml += crType+"</a><br /> "+offenseDate;
						}

						infoWindowHtml += "</p>";
						
					}
					infoWindowHtml += "</td>";
//					infoWindowHtml += "<td valign='top' style='width: 11px; background: url("+htmlbase+"/img/rule_vertical-dotted.gif) repeat-y; background-position: 1px 0;'><img onmousedown=\"a_up = scrollWindowHandler(-6, 'bubbleList')\" onmouseup='clearInterval(a_up)' onmouseout='clearInterval(a_up)' src='"+htmlbase+"img/sm-icon_colapse.gif'><br/>";
//					infoWindowHtml += "<img onmousedown=\"a_up = scrollWindowHandler(6, 'bubbleList')\" onmouseup='clearInterval(a_up)' onmouseout='clearInterval(a_up)' src='"+htmlbase+"img/sm-icon_expand.gif' style='position:absolute; bottom:-10px;'></td>";
					infoWindowHtml += "<td valign='top'>";
					infoWindowHtml += "<div id='multiTarget' style='overflow:hidden; width: 100%;'>\n";
					infoWindowHtml += "<blockquote>"+t("Multiple items are being displayed at this location. Please use the navigation on the left to select an item.")+"</blockquote></div>\n";
					infoWindowHtml += "</td></tr></table>";
					this.openInfoWindowHtml(infoWindowHtml);
					
				})
				map.addOverlay(marker);
				if(zoomlevel) marker.hide();
			}
		} 
	}
} // end function addRemoveMarkers()

function scrollWindowHandler(move, target) {
	return setInterval('scrollWindow('+move+', "'+target+'")', 30);
}

function scrollWindow(move, target) {
	document.getElementById(target).scrollTop += move;
}

function showinfo(id,multipleid) {
	multiWindowHtml = '';
	//GEvent.trigger(window.crimesObj["marker_"+id],"click",multipleid);
	for(i=0;i<mixedXMLArray.length;i++){
		if(mixedXMLArray[i].getAttribute("occurrenceid") == id) {
			if (mixedXMLArray[i].getAttribute("occurrenceid").match(/so/)) { //sex offender data
				var pic_id = mixedXMLArray[i].getAttribute("pic_id");
				multiWindowHtml += "<div style='text-align: center; color: #FFF; padding-top: 3px; height: 20px; background-position: -17px 0; background-image: url("+htmlbase+"bubble/bubble_title-bar_sex-offender_main.gif);'><strong>"+t("REGISTERED SEX OFFENDER")+"</strong></div>";
				multiWindowHtml += "<table width='100%' height='100%' cellpadding='0' cellspacing='0' border='0'><tr>";
				if (pic_id && pic_id!='null') {
					multiWindowHtml += "<td valign='top' style='width:125px;'>";
					multiWindowHtml += "<img style='width: 120px; border: 0px;' src='"+htmlbase+"map/sopic/?pic_id="+pic_id+"'>";
					multiWindowHtml += "</td>";
				}
				multiWindowHtml += "<td valign='top'><strong>"+mixedXMLArray[i].getAttribute("f_name")+" ";
				multiWindowHtml += mixedXMLArray[i].getAttribute("m_name")+" ";
				multiWindowHtml += mixedXMLArray[i].getAttribute("l_name")+"</strong><br/>";
				var brs='<br>\n'; 
				var replaced= mixedXMLArray[i].getAttribute('add_info').replace(/\|/g, brs)
				multiWindowHtml += "<div id='add_info' style='overflow-y:scroll; height: 160px; width: 100%;'>"+mixedXMLArray[i].getAttribute("address")+"<br\>"+replaced;
//			multiWindowHtml += "<td valign='top' style='width: 11px; background: url("+htmlbase+"/img/rule_vertical-dotted.gif) repeat-y; background-position: 1px 0;'><img onmousedown=\"a_up = scrollWindowHandler(-6, 'add_info')\" onmouseup='clearInterval(a_up)' onmouseout='clearInterval(a_up)' src='"+htmlbase+"img/sm-icon_colapse.gif'><br/>";
//			multiWindowHtml += "<img onmousedown=\"a_up = scrollWindowHandler(6, 'add_info')\" onmouseup='clearInterval(a_up)' onmouseout='clearInterval(a_up)' src='"+htmlbase+"img/sm-icon_expand.gif' style='position:absolute; bottom:-10px;'></td>";	
				if (mixedXMLArray[i].getAttribute('orig_url')) {
					multiWindowHtml += "<p style='margin-bottom:2px;'> <a class='smallActiveText' href='" + mixedXMLArray[i].getAttribute('orig_url') + "' target='_blank' ><span class='smallActiveText'>"+t("Link")+"</span></a></p>";
				}
				multiWindowHtml += "</div></td>";
				multiWindowHtml += "</tr></table>";
			} else { //all other crimes types
				var crimeType = getCrimeTypePretty(mixedXMLArray[i].getAttribute("type"));
				var offenseDate = mixedXMLArray[i].getAttribute("offense_date");
				if (offenseDate) 
					offenseDate = offenseDate.substr(0,11);
				var distanceFromCenter = mixedXMLArray[i].getAttribute("distance_from_center");
				var address = mixedXMLArray[i].getAttribute("address");
				var narrative = mixedXMLArray[i].getAttribute("narrative");
				var ccn = mixedXMLArray[i].getAttribute("ccn");
				var agencyName = mixedXMLArray[i].getAttribute("name");
				var color = getMarkerColorSpecial(mixedXMLArray[i].getAttribute("marker_color"));
				var trackingNum = mixedXMLArray[i].getAttribute("occurrenceid");
				multiWindowHtml += "<div style='text-align: center; color: #FFF; padding-top: 3px; height: 20px; background-position: -17px 0; background-image: url("+htmlbase+"bubble/bubble_title-bar_"+color+"_main.gif); background-repeat: repeat-x;'><strong>"+crimeType+"</strong></div>";
				multiWindowHtml += "<table width='100%' height='100%' cellpadding='0' cellspacing='0' border='0'><tr><td valign='top'>";
//				multiWindowHtml += "<div id='add_info' style='overflow-y:hidden; height: 180px; width: 100%;'><p style='font-size:11px; '>" + offenseDate.replace(/ /g, '&nbsp;') + "</p>";
				multiWindowHtml += "<div id='add_info' style='overflow-y:scroll; height: 180px; width: 100%;'><p style='font-size:11px; '>" + offenseDate.replace(/ /g, '&nbsp;') + "</p>";
				multiWindowHtml += "<p>" + address + "</p>";
				multiWindowHtml += "<p><strong>"+t("Distance:")+"</strong> " + distanceFromCenter + t(" miles")+"</p>";
				multiWindowHtml += "<p>" + narrative + "</p>";
				multiWindowHtml += "<p><strong>"+t("Identifier:")+"</strong> " + ccn + "</p>";
				if(agencyName) {
					multiWindowHtml += " <p><strong>"+t("Agency:")+"</strong> " + agencyName + "</p>";
				}
				multiWindowHtml += "<p style='margin-bottom:2px;'><a class='smallActiveText' href='javascript:void(0);' onclick='lightbox.prototype.show(\"emailcrime\","+trackingNum+");' ><span class='smallActiveText'>"+t("Send to Friend")+"</span></a>";
				multiWindowHtml += "</div></td>";
//				multiWindowHtml += "<td valign='top' style='width: 11px; background: url("+htmlbase+"/img/rule_vertical-dotted.gif) repeat-y; background-position: 1px 0;'><img onmousedown=\"a_up = scrollWindowHandler(-6, 'add_info')\" onmouseup='clearInterval(a_up)' onmouseout='clearInterval(a_up)' src='"+htmlbase+"img/sm-icon_colapse.gif'><br/>";
//				multiWindowHtml += "<img onmousedown=\"a_up = scrollWindowHandler(6, 'add_info')\" onmouseup='clearInterval(a_up)' onmouseout='clearInterval(a_up)' src='"+htmlbase+"img/sm-icon_expand.gif' style='position:absolute; bottom:-10px;'></td>";
				multiWindowHtml += "</tr></table>";
			}
			break;//don't bother looping through the rest after crime has been found
		}
	}
	document.getElementById('multiTarget').innerHTML = multiWindowHtml;
	//GEvent.trigger(window.multipleObj["multipleid"],"click");
} // end function showInfo()

//numtries is optional, defaults to 4
function getDataForNewFilter(clearExistingMarkers, numtries, fromNewSearch) {
	//doUTAGCheck();
	var themeView = (typeof(showThematicView)!='undefined' && showThematicView && thematicShapefileId);
	if (themeView) {
		if (lastThemeLoc != getThemeLocation())
			getLegendReady();
	}
	if(map.getZoom()>=MIN_ZOOM_WITH_MARKERS || themeView) {
		var center = map.getCenter();

		if (typeof numtries == 'undefined' || numtries===null) numtries = 4;
		if (typeof numtries != 'number') numtries = 0;
		if (typeof(fromNewSearch)=='undefined')
			fromNewSearch = false;
		if (numtries < 0) return;
	
		var callback =
		{
			success: responseSuccess,
			failure: responseFailure,
			argument: [clearExistingMarkers, getDataForNewFilter, clearExistingMarkers, numtries-1, fromNewSearch],
			timeout: 10000
		}

		YAHOO.util.Connect.setForm(document.getElementById('filters'));
		if(addressCoords) {
			//this.setMessage("<img src='" + htmlbase + "images/loading.gif'>&nbsp;"+t('Loading')+" . . . ","DISPLAY");

			if(document.getElementById('dayrange')!=null) {
				var postStr = createPostString(displayed_categories,
						document.getElementById('dayrange').value,
						document.getElementById('startdate').value,
						document.getElementById('enddate').value,
						document.getElementById('mapradius').value,
						getCoords());

				var countryCode = '?';
				if (map.getCenter().equals(lastGeoCoded.point)) {
					countryCode = lastGeoCoded.country;
				}

				postStr += '&countryCode='+countryCode+'&lat='+map.getCenter().lat()+'&lng='+map.getCenter().lng();
				var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'map/xmldata/isAjax/true/cb/'+100*Math.random(), callback, postStr );
			}
		}
	} else {
		// if we dont to an xmldata request, then we need to tell the mothership that the areaShapeIds changed, so it can put it in the session
		try {setSessionAreaShapeIds();} catch(e) {}
	}
} // end function getDataForNewFilter

//numtries is optional, defaults to 4
function getDataForCrimeID(clearExistingMarkers,crimeid, numtries) {
	if (typeof numtries == 'undefined' || numtries===null) numtries = 4;
	if (typeof numtries != 'number') numtries = 0;
	if (numtries < 0) return;

	var callback =
	{
		success: responseSuccess,
		failure: responseFailure,
		argument: ['singlecrime', getDataForCrimeID, clearExistingMarkers, crimeid, numtries-1],
		timeout: 7000
	}
	//this.setMessage("<img src='" + htmlbase + "images/loading.gif'>&nbsp;"+t('Loading')+" . . . ","DISPLAY");

	YAHOO.util.Connect.setForm(document.getElementById('filters'));
	
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'map/xmldata/isAjax/true/cb/'+100*Math.random(), callback, 'crimeid='+crimeid);
	//debugger
	if(addressCoords) {
	   drawHomeOverlayCircle(addressCoords.lat(),addressCoords.lng(),document.getElementById('mapradius').value,false);
    }
	//debugger
}

//numtries is optional, defaults to 4
function getDataForMapID(clearExistingMarkers,mapid, numtries){
	if (typeof numtries == 'undefined' || numtries===null) numtries = 4;
	if (typeof numtries != 'number') numtries = 0;
	if (numtries < 0) return;

	var callback =
	{
		success: responseSuccess,
		failure: responseFailure,
		argument: ['crimereport', getDataForMapID, clearExistingMarkers, mapid, numtries-1],
		timeout: 7000
	}
	//this.setMessage("<img src='" + htmlbase + "images/loading.gif'>&nbsp;"+t('Loading')+" . . . ","DISPLAY");

	YAHOO.util.Connect.setForm(document.getElementById('filters'));
	//alert(window.serverAddr +'/crimereports/map/xmldata/?isAjax=true&cb='+100*Math.random());
	
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'map/xmldata/isAjax/true/cb/'+100*Math.random(), callback, 'mapid='+mapid);
	
}

function getCoords(){
	coords = new Array();

	coords['center_lat'] = map.getCenter().lat();  //map center lat (for db search)
	coords['center_lng'] = map.getCenter().lng();  //map center lng (for db search)
	coords['address_lat'] = addressCoords.lat();    //address lat (for distance calc)
	coords['address_lng'] = addressCoords.lng();    //address lng (for distance calc)

	return coords;
}

/*
function changeStartEndDates(obj, today) {
	selStart = obj.options[obj.selectedIndex].value;
	if(selStart == 'custom') {
		//uncover the custom dates
		document.getElementById('customDateControl').className = 'customDateControlOff';
	} else {
		document.getElementById('customDateControl').className = 'customDateControlOn';
		document.getElementById('filter_start_date').value = selStart;
		document.getElementById('filter_stop_date').value = today;
		document.getElementById('cal1Container').style.display='none';
		document.getElementById('cal2Container').style.display='none';
		getDataForNewFilter(1);
	}
}

function toggleExtraCategories() {
	ec = document.getElementById('extraCategories');
	if(ec.className=='extraCategoriesOff') {
		ec.className = 'extraCategoriesOn';
	} else {
		ec.className = 'extraCategoriesOff';
	}
}

function showDateSelMenu() {
	pdm = document.getElementById('presetDatesMenu');
	pdm.style.display='inline';
	document.getElementById('cal1Container').style.display='none';
}

function selectPresetDate(obj) {
	if(obj.innerHTML=='Custom') {
		initCal();
	} else {
		document.getElementById('filter_start_date').value=obj.innerHTML;
		document.getElementById('filter_start_date').prettyDate=obj.getAttribute('thisRawDate');
		document.getElementById('startDate').innerHTML=obj.innerHTML;
	}
	document.getElementById('presetDatesMenu').style.display='none';
}


function checkAddressForm() {
	if(document.getElementById('filter_address').value!='Street address' && document.getElementById('filter_address').value!='' &&
	document.getElementById('filter_city').value!='City' && document.getElementById('filter_city').value!='' &&
	document.getElementById('filter_zip').value!='Zip code' && document.getElementById('filter_zip').value!=''){
		showAddress();
	}
}

function formKeyPress(e){}
*/
function selectAllCategories(checkBox) {
	frm = document.getElementById('filters');
	for(el=0;el<frm.elements.length;el++) {
		if(frm.elements[el].type=='checkbox' && frm.elements[el].name=='filter_category[]') {
			frm.elements[el].checked=checkBox;
		}
	}
	getDataForNewFilter(1);
}

function sortByDateDesc(a,b,direction) {
    var x = Date.parse(a.obj.getAttribute('offense_date'));
    var y = Date.parse(b.obj.getAttribute('offense_date'));
    return ((x > y) ? -1 : ((x < y) ? 1 : 0));
}

function sortByName(a,b) {
    var x = a.obj.getAttribute('type');
    var y = b.obj.getAttribute('type');
    return ((x > y) ? 1 : ((x < y) ? -1 : 0));
}

function sortByID(a,b) {
    var x = a.obj.getAttribute('occurrenceid');
    var y = b.obj.getAttribute('occurrenceid');
    return ((x > y) ? -1 : ((x < y) ? 1 : 0)); 	
}

function sortByDistance(a,b) {
    return a.obj.getAttribute('distance_from_center') - b.obj.getAttribute('distance_from_center');
}
var crimeSortBy = "date";

function loadSOList(sodata) {
	d1 = new Date().getTime();
	var soHTML = new Array();

	for(i=0;i<sodata.length;i++) {
		var trackingNum = sodata[i].obj.getAttribute("occurrenceid");

		var lat = sodata[i].obj.getAttribute("lat");
		var lng = sodata[i].obj.getAttribute("lng");
		var markerColor = 'sex-offender';
		var onclick = "onclick='getInfoWindowObj(\""+trackingNum+"\",\""+markerColor+"\");' onmouseover='toggleColor(\"crime_left_"+trackingNum+"\",\"on\");' onmouseout='toggleColor(\"crime_left_"+trackingNum+"\",\"off\");' ";
		var address = sodata[i].obj.getAttribute("address");
		var pic_id = sodata[i].obj.getAttribute('pic_id');
		soHTML.push("<div id='crime_left_"+trackingNum+"' class='incident' "+onclick+" \n");
		soHTML.push(" >\n");
		soHTML.push("	<div class='incidentHeader'>\n");
		soHTML.push("		<div class='"+markerColor+"IconHeader' style='float:none;'>"+t("REGISTERED SEX OFFENDER")+"</div>");
		soHTML.push("	</div>\n");
		soHTML.push("	<div class='incidentLocation'>\n");
		soHTML.push("		" + address + "\n");
		soHTML.push("	</div>\n");
		
		soHTML.push("	<div>");
		soHTML.push("		" + sodata[i].obj.getAttribute('add_info').replace(/\|/g, '<br />'));
		soHTML.push("	</div>");
		//soHTML.push("	<div class='incidentDistance'>\n");
		//soHTML.push("		<span class='smallHeading'>"+t("Distance:")+"</span> " + sodata[i].obj.getAttribute("distance_from_center") + " miles\n");
		//soHTML.push("	</div>\n");
		if (sodata[i].obj.getAttribute('orig_url'))
			soHTML.push("<div style='padding-top:4px;'> <a class='smallActiveText' href='" + sodata[i].obj.getAttribute('orig_url') + "' target='_blank' ><span class='smallActiveText'>"+t("Link")+"</span></a></div>");
		soHTML.push("</div>");
	}

	soHTMLer = soHTML.join('');
	d2 = new Date().getTime();
	var outOfArea = false;
	try {
		outOfArea = document.getElementById('searchResultsSexOffenders').getAttribute('outofarea') == 'true';
	} catch (e) {}
	if (!outOfArea) {
		document.getElementById('searchResultsSexOffenders').innerHTML = soHTMLer;
	}
	d3 = new Date().getTime();
	//alert((d2-d1)+" "+(d3-d2));
	return 1;
} // end function loadSOList()


function loadCrimeList(crimes) {	
	d1 = new Date().getTime();
	//var crimes = xmlObj.getElementsByTagName("crime");
	var crimeHTML = new Array();
	//GLog.write("Crimes:"+crimes.length);
	//CRIMELIST SORTING should probably happen here CODEGREENE
	//crimes is an array of CrimeObjects.
	 //   debugger;
	switch(crimeSortBy) {
		case "date":
	    	crimes.sort(sortByDateDesc);
	    	break;
	  	case "type":
		case "crime":
	    	crimes.sort(sortByName);
	    	break;
	  	case "distance":
	    	crimes.sort(sortByDistance);
	    	break;
	  	default:
	    	break;
	}
	for(i=0;i<crimes.length;i++){
		var trackingNum = crimes[i].obj.getAttribute("occurrenceid");
		var markerColor = getMarkerColorSpecial(crimes[i].obj.getAttribute("marker_color"));
		var narrative = crimes[i].obj.getAttribute("narrative");
		if(!narrative) narrative = "";
		if(narrative=='') narrative = "";
		onclick = "";
		noaddress = "";
		if(crimes[i].obj.getAttribute("precision1") == 1 || crimes[i].obj.getAttribute("precision1") == 0) {
			onclick = "onclick='getInfoWindowObj("+trackingNum+",\""+markerColor+"\");' onmouseover='toggleColor(\"crime_left_"+trackingNum+"\",\"on\");' onmouseout='toggleColor(\"crime_left_"+trackingNum+"\",\"off\");'";
			address = crimes[i].obj.getAttribute("address");
		}else{
			address = t("(Address could not be mapped)");
		}
		crimeHTML.push("<div id='crime_left_"+trackingNum+"' class='incident' "+onclick+" \n");
		crimeHTML.push(" >\n");
		crimeHTML.push("	<div class='incidentHeader'>\n");
		crimeHTML.push("		<div style='padding-left:0px;'><div class='iconHeader' style='padding-left:0px;'>");
		crimeHTML.push("			<img border='0' src='"+htmlbase+"map-icon/map-icon_list_"+markerColor+".gif'></div>");
		crimeHTML.push(getCrimeTypePretty(crimes[i].obj.getAttribute("type")));
		crimeHTML.push("</div>" + crimes[i].obj.getAttribute("offense_date").replace(/ /g, '&nbsp;') + "\n");
		crimeHTML.push("	</div>\n");
		crimeHTML.push("	<div class='incidentLocation'>\n");
		crimeHTML.push("		" + address + "\n");
		crimeHTML.push("	</div>\n");
		crimeHTML.push("	<div class='incidentDistance'>\n");
		crimeHTML.push("		<span class='smallHeading'>"+t('Distance:')+"</span> " + crimes[i].obj.getAttribute("distance_from_center") + t(" miles")+"\n");
		crimeHTML.push("	</div>\n");
		crimeHTML.push("	<div class='incidentDistance'>\n");
		crimeHTML.push("		<span class='smallHeading'>"+t('Identifier:')+"</span> " + crimes[i].obj.getAttribute("ccn") + "</div>\n");
		crimeHTML.push("	<div class='incidentDescription'>\n");
		crimeHTML.push("		" + narrative + "\n");
		crimeHTML.push("	</div>\n");
		crimeHTML.push("	<div class='incidentAgency'>\n");
		crimeHTML.push("		<span class='smallHeading'>"+t('Agency:')+"</span> " + crimes[i].obj.getAttribute("name") + "</div>\n");
		crimeHTML.push("	<a href='javascript:void(0);' onclick='lightbox.prototype.show(\"emailcrime\","+trackingNum+");'");
		//crimeHTML.push(" onclick='document.getElementById(\"emailcrimeid\").value=\""+trackingNum+"\";return !showPopup(\"emailcrime\", event);' class='smallActiveText ' rel='emailcrime'>\n");
		crimeHTML.push("		<span class='smallActiveText'>"+t("Send to Friend")+"</span>\n");
		crimeHTML.push("	</a>\n");
	//	crimeHTML.push("	<span style='font-size:75%;'> &nbsp;|&nbsp; </span>\n");
	//	crimeHTML.push("	<a href='javascript:void(0);' onclick='return false;' class='smallActiveText'><span class='smallActiveText'>Report Tip</span></a>\n");
		crimeHTML.push("</div>");
	}


	crimeHTMLer = crimeHTML.join('');
	d2 = new Date().getTime();
	var Area = false;
	try {
		outOfArea = document.getElementById('searchResultsCrimes').getAttribute('outofarea') == 'true';
	} catch (e) {}
	if (!outOfArea) {
		document.getElementById('searchResultsCrimes').innerHTML = crimeHTMLer;
	}
	
	d3 = new Date().getTime();
	//alert((d2-d1)+" "+(d3-d2));

	var areaProvider = "";
	var lastupdate = "";
	try { // sometimes, there is no crime data. so the area tag is not there
		var areaProvider = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('name');
		var lastupdate = crimesXMLObj.getElementsByTagName("area")[0].getAttribute('lastupdate');
	} catch (e) {}
	if(document.getElementById('provider')){
		if (areaProvider != '' && lastupdate != ''){
			document.getElementById('provider').innerHTML = sprintf(t("Data provided by: %s"), Base64.decode(areaProvider));
		} else {
			document.getElementById('provider').innerHTML = sprintf(t("Data provided by: %s"), '');
		}
	}
	if(document.getElementById('please')){
		var crimeSortByPretty = "";
		switch(crimeSortBy) {
			case 'type':
			case 'crime':
				crimeSortByPretty = t("Type");
				break;
			case 'distance':
				crimeSortByPretty = t("Distance");
				break;
			case 'date':
				crimeSortByPretty = t("Date");
				break;
		}
		document.getElementById('please').innerHTML = Base64.decode(areaProvider)+" | "+sprintf(t('sorted by %s'), crimeSortByPretty)+" | "+sprintf(t('%s to %s'), fromYYYYMMDDtoMMDDYYYY(document.getElementById('custom_date_start').value), fromYYYYMMDDtoMMDDYYYY(document.getElementById('custom_date_end').value));
	}
	
	return 1;
} // end function loadCrimesList()

var emailcrimeResponse = function (o){
	setMessage(t("The crime has been sent."),"DISPLAY");
	//alert(o.responseText);
}

var emailcrimemapResponse = function (o){
	setMessage(t("The crime map has been sent."),"DISPLAY");
}

function sendCrimeEmail(){
	var callback =
	{
		success: emailcrimeResponse,
		failure: emailcrimeResponse
	}
	YAHOO.util.Connect.setForm(document.getElementById('emailcrime_form'));
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'map/emailcrime', callback);
}

function sendCrimeMapEmail() {
	var callback = 
	{
		success: emailcrimemapResponse,
		failure: emailcrimemapResponse
	}
	YAHOO.util.Connect.setForm(document.getElementById('emailcrimes_form'));
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'map/emailcrimemap', callback);
}

function showCrimeEmailConfirmation() {
  var crimeForm = document.getElementById('emailcrime_form');
  crimeForm.innerHTML = t("<p>Thank you, your email has been sent.</p><p>Click anywhere to close this window.</p>");
}

/*** LOADING AND SAVING OF ALERTS/USER SAVED LOCATIONS  ***/

var saveAlertSuccessResponse = function (o){
	setMessage(t("The crime map has been saved."),"DISPLAY");
}

var saveAlertFailureResponse = function (o){
	setMessage(t("There was a problem saving your crime map."),"DISPLAY");
}

function saveAlert() {
	var callback = 
	{
		success: saveAlertSuccessResponse,
		failure: saveAlertFailureResponse
	}
	YAHOO.util.Connect.setForm(document.getElementById('savealert_form'));
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'user/addLocation', callback);
}

/*** CREATION OF NEW USER ALERT MODAL ***/
var createAlertSuccess = function(o) {
    var ca = parseXML(o.responseText);	
    if(ca.getAttribute('success')==1) {
	    var c = new CookieHandler(); //see utility.js for usage
	    c.setCookie('show_signup', 1, 60*60*24*365*2);
        lightbox.prototype.hide('showSignup');
        lightbox.prototype.show('signupThanks');
        setTimeout("lightbox.prototype.hide('signupThanks')", 10000);
    } else {        
        var reason = ca.getAttribute('reason');          
        if(reason=='LOGIN FAILED'){            
            alert(t('Email address already in use. Please supply the correct password or use a different email address.'));
        }else if(reason=='NOT MAPPED'){
            alert(t('Address could not be mapped. Please try again. For assistance please email support@crimereports.com'));
        }else{
            alert(t('Error: could not create alert'));
        }
    }    
}

var createAlertFailure = function(o) {
    //lightbox.prototype.showme('div',0);
    alert(t('Failed to create Alert'));
}

function createAlert() {
    //validate form input before attempting to submit
    if(CRValidator.validate(document.getElementById('createalert_form'),true)) {
	    var callback =
	    {
	        success: createAlertSuccess,
	        failure: createAlertFailure
	    }
	    YAHOO.util.Connect.setForm(document.getElementById('createalert_form'));
	    var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'user/createModalAlert', callback);
	}
}

var responseAlertSuccess = function (o){
	// set the lat, lng and mapid
	document.getElementById("searchtext").value = ''; // clear out the search bar first
	var data = eval('(' + o.responseText + ')');
	a_lat = data.lat;
	a_lng = data.lng;
	document.getElementById('alert_lat').value = data.lat;
	document.getElementById('alert_lng').value = data.lng;
	//alert(data.categories[0]['categoryid']);
	var main;
	var sub;
	for (var i in subcategories) {
		toggleMainCategory(i, false, '0');
	}
	for (var n in displayed_categories){
		main = document.getElementById('category_main_'+n);
		for (var m in displayed_categories[n]) {
			sub = document.getElementById('category_sub_'+n+'_'+m);
			for (i=0; i<data.categories.length;i++) {
				if(data.categories[i]['categoryid'] == n) {
					main.className = 'crimeTypeMain crimeTypeMainCheck';
					sub.className = 'crimeTypeSub crimeTypeSubCheck';					
					displayed_categories[n][m] = true;
					break;
				}
				else {
					main.className = 'crimeTypeMain';
					sub.className = 'crimeTypeSub';
					displayed_categories[n][m] = false;
				}
			}
		}
	}

	loadMap();
	setMessage(sprintf(t("Your saved location %s has been loaded."), data.location_nm),"DISPLAY");
}

var responseAlertFailure = function (o){
	setMessage(t("There was a problem saving your crime map."),"DISPLAY");
}

function askDept() {
	lightbox.prototype.showme("askdept", 0);
	//setMessage("Invited Chief.","DISPLAY");
}

function isInvited() {
	var callback = 
	{		
		success: isInvitedSuccessResponse,
		failure: isInvitedFailureResponse
	}
	var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'index/invited', callback);
}

var isInvitedSuccessResponse = function (o){
	var pattern=/.*not_invited.*/;
	var invited = o.responseText.replace(pattern,"not_invited");
	if(invited=='not_invited'){	
		// comment test
		askDept();		
	}
}

var isInvitedFailureResponse = function (o){
	setMessage(t("Can't invite."),"DISPLAY");
}

function getAlert(aid, uid) {
	//alert('Alert ID: '+aid+" User ID: "+uid);
	var callback =
	{
		success: responseAlertSuccess,
		failure: responseAlertFailure
	}
	if(aid != 0) {
		var postdata = 'alertid='+aid+'&userid='+uid;
		var transaction = YAHOO.util.Connect.asyncRequest('POST', htmlbase + 'user/getuserSavedLocations/isAjax/true/cb/'+100*Math.random(), callback, postdata);	
	}
}

/* check to see if we need to pop up the invitation modal */
function checkSignup() {
    var c = new CookieHandler(); //see utility.js for usage
    cookie = c.getCookie('show_signup');
    if(!cookie && showSignupModal) {
        c.setCookie('show_signup', 1, 60*60*24*7);
        showSignupSuccess();
    }
}

var showSignupSuccess = function (o) {
	lightbox.prototype.showme("showSignup", 0);
	if(searchAddress.address) {
	    $('address').value = searchAddress.address;
	}
	if(searchAddress.city) {
	    $('city').value = searchAddress.city
	}
	$('state').style.visibility = "visible"; //lightbox hides selects... so we re-enable this one.
	state = $('state');
	for(i=0; i<=state.options.length-1; i++) {
	    if(state.options[i].value == searchAddress.state || state.options[i].innerHTML.toLowerCase() == searchAddress.state.toLowerCase()) {
	        state.options[i].selected = true;
	    }
	}
}

var showSignupFailure = function(o) {
    //error
}

function hideAllMarkers(){

	if(document.getElementById('searchResults')){
		for(i=0;i<mixedXMLArray.length;i++){
			trackingNum = mixedXMLArray[i].getAttribute("occurrenceid")
			if(window.crimesObj['marker_'+trackingNum]) window.crimesObj['marker_'+trackingNum].hide();
		}
		for(i=0;i<removeCrimeArray.length;i++){
			trackingNum = removeCrimeArray[i].getAttribute("occurrenceid")
			if(window.crimesObj['marker_'+trackingNum]) window.crimesObj['marker_'+trackingNum].hide();
		}
		//TMR  Why was this inserted?  It breaks the zoom.
		//document.getElementById('mapAndDetails').style.visibility='hidden';
		for(i=0;i<jurisdictionArray.length;i++){
			trackingNum = jurisdictionArray[i].jurisdictionid
			window.crimesObj['juris_'+trackingNum].show();
		}
		for(i=0;i<multipleObj.length;i++){
			multipleObj[i].hide();
		}
	}
}

function showAllMarkers(){
	if(document.getElementById('searchResults')){
		for(i=0;i<mixedXMLArray.length;i++){
			trackingNum = mixedXMLArray[i].getAttribute("occurrenceid")
			if(window.crimesObj['marker_'+trackingNum]) window.crimesObj['marker_'+trackingNum].show();
		}
		document.getElementById('mapAndDetails').style.visibility='visible';
		for(i=0;i<jurisdictionArray.length;i++){
			trackingNum = jurisdictionArray[i].jurisdictionid;
			window.crimesObj['juris_'+trackingNum].hide();
		}
		for(i=0;i<multipleObj.length;i++){
			multipleObj[i].show();
		}
	}
}

/*==========================================================================================
							SOffender section
==========================================================================================*/ 

function toggleSOData() {
    if(showSO) {
        showSO=0;
    } else {
        showSO=1;
    }
    getDataForNewFilter();
}

var responseSOSuccess = function(o) {
//  alert(o.responseText);
	if(o.responseText!="Out of Area") {
		
		sXMLObj = parseXML(o.responseText);
		//GLog.write(o.responseText);
		SOXMLArray = sXMLObj.getElementsByTagName("offender");
		
		for(i=0;i<SOXMLArray.length;i++) {
			var trackingNum = SOXMLArray[i].getAttribute('id');
			if(window.crimesObj['so_'+trackingNum]) {
                continue;
            }
			var lat = SOXMLArray[i].getAttribute('lat');
			var lng = SOXMLArray[i].getAttribute('lng');
			var orig_url = "<table><tr><td height=150><img width=100 src='"+htmlbase+"map/sopic/?pic_id="+SOXMLArray[i].getAttribute('pic_id')+"'></td></tr></table>";
			var point = new GLatLng(lat,lng);
	
			soMarker = SOMarker(point,trackingNum,orig_url);

			window.crimesObj['so_'+trackingNum] = soMarker;
			soMarker.isMarker=true;
	
			map.addOverlay(soMarker);
			//window.crimesObj['juris_'+trackingNum].hide();
		}
	}
}

var responseSOFailure = function(o){}

//tests to see if a point is inside a polygon
function myWithin($myPolygon,$point) {
$counter = 0;
// get rid of unnecessary stuff
$myPolygon = str_replace("POLYGON","",$myPolygon);
$myPolygon = str_replace("(","",$myPolygon);
$myPolygon = str_replace(")","",$myPolygon);
$point = str_replace("POINT","",$point);
$point = str_replace("(","",$point);
$point = str_replace(")","",$point);
// make an array of points of the polygon
$polygon = explode(",",$myPolygon);
// get the x and y coordinate of the point
$p = explode(" ",$point);
$px = $p[0];
$py = $p[1];
// number of points in the polygon
$n = count($polygon);
$poly1 = $polygon[0];
for ($i=1; $i <= $n; $i++) {
$poly1XY = explode(" ",$poly1);
$poly1x = $poly1XY[0];
$poly1y = $poly1XY[1];
$poly2 = $polygon[$i % $n];
$poly2XY = explode(" ",$poly2);
$poly2x = $poly2XY[0];
$poly2y = $poly2XY[1];
if ($py > min($poly1y,$poly2y)) {
if ($py <= max($poly1y,$poly2y)) {
if ($px <= max($poly1x,$poly2x)) {
if ($poly1y != $poly2y) {
$xinters = ($py-$poly1y)*($poly2x-$poly1x)/($poly2y-$poly1y)+$poly1x;
if ($poly1x == $poly2x || $px <= $xinters) {
$counter++;
}
}
}
}
}
$poly1 = $poly2;
} // end of While each polygon
if ($counter % 2 == 0) {
return(false); // outside
} else {
return(true); // inside
}
}



/*
 * Sends result of geocode to the server for logging. We want to record every successful search made on the map page.
 * @param info - The result object obtained from the geocode and passed to the getLocations callback
 */
function logSearch(info) {
	try {
		var transaction = YAHOO.util.Connect.asyncRequest('GET', htmlbase + 'map/logSearch?'
			+'nocache='+(new Date()).getTime()+':'+(100*Math.random())
			+'&lat='+info.Placemark[0].Point.coordinates[1]+'&lng='+info.Placemark[0].Point.coordinates[0]
			+'&search='+info.name
			+'&pretty='+info.Placemark[0].address
			, null, '');
	} catch(e) {}
}

/**
 * This is a helper function that ensures that the print page gets the information it needs to be exactly the same as the map page.
 * The Distance Guide gets turned on and also the sorting matches.
 *
*/
function openPrintWindow(theurl){
	theurl += '?crimeSortBy=' + crimeSortBy;
	theurl += '&zoom=' + map.getZoom();
	if(showBullseye)
		theurl += '&showBullseye=1';
	
	window.open(theurl,'printview','width=820,menubar=0,resizable=1,scrollbars=1');
}
