PTRFPlaceSearchBox = function(searchContainer, searchTypes, options) {
	this.eventTypes = new Object();
	this.eventTypes.submit = 'submit';
	this.eventTypes.response = 'response';
	this.eventTypes.dd_initialized = 'dd_initialized';
	
	// Set the default text for the search box. This varies by page.
	this.defaultText = "Enter Address, City, County, State, or Zip";
	this.defaultTextTitle = "Address, City, County, State, Zip";
	if(PEnvironment.pageName == "dataloader") {
		this.defaultText = "Enter City, County, State, or Zip";
		this.defaultTextTitle = "City, County, State, Zip";
	}

	this.eventManager = new _eventManager();
	for (var ev in this.eventTypes)
		this.eventManager.registerEventID(ev);

	this.container = searchContainer;
	$(this.container).addClass("searchContainer");
	if (!options)
		this.options = {};
	else
		this.options = options;

	// build and add the html needed to set up the search and options
	this.buildSetLocation();
	var node = this.node;
	var typeNode = this.typeNode;

	this.type = null;
	this.defaultType = null;
	this.searchTypes = null;

	this.textbox = document.createElement("input");
	this.textbox.type = "text";
	this.textbox.style.width = "97%";
	this.textbox.style.height = "100%";

	//this.textboxState = document.createElement("input");
	//this.textboxState.type = "text";
	//this.textboxState.style.width = "20%";
	//this.textboxState.style.height = "100%";
	//this.textboxState.style.display = "none";
	//this.textboxState.style.marginRight = "10px";

	var usStates = document.createElement('select');
	usStates.id = 'states'; 
	usStates.name = 'states';
	usStates.style.display = "none";
	usStates.style.width = "30%";
	//usStates.style.height = "50%";
	usStates.style.marginRight = "10px";

	this.addState = function(stateName, fips, abbrev) {		
		var o = document.createElement('option');
		o.value = fips;
		o.title = abbrev
		o.innerHTML = stateName;
		if (stateName == "California") o.selected = true;
		usStates.appendChild(o);
	};

	 this.addState("Alabama", '01', 'AL');
	 this.addState("Alaska", '02', 'AK');
	 //this.addState("American Samoa", 60, 'AS');
	 this.addState("Arizona", '04', 'AZ');
	 this.addState("Arkansas", '05', 'AR');
	 this.addState("California", '06', 'CA');
	 this.addState("Colorado", '08', 'CO');
	 //this.addState("Commonwealth of the Northern Mariana Isla", 69, 'MP');
	 this.addState("Connecticut", '09', 'CT');
	 this.addState("Delaware", 10, 'DE');
	 this.addState("District of Columbia", 11, 'DC');
	 this.addState("Florida", 12, 'FL');
	 this.addState("Georgia", 13, 'GA');
	 //this.addState("Guam", 66, 'GU');
	 this.addState("Hawaii", 15, 'HI');
	 this.addState("Idaho", 16, 'ID');
	 this.addState("Illinois", 17, 'IL');
	 this.addState("Indiana", 18, 'IN');
	 this.addState("Iowa", 19, 'IA');
	 this.addState("Kansas", 20, 'KS');
	 this.addState("Kentucky", 21, 'KY');
	 this.addState("Louisiana", 22, 'LA');
	 this.addState("Maine", 23, 'ME');
	 this.addState("Maryland", 24, 'MD');
	 this.addState("Massachusetts", 25, 'MA');
	 this.addState("Michigan", 26, 'MI');
	 this.addState("Minnesota", 27, 'MN');
	 this.addState("Mississippi", 28, 'MS');
	 this.addState("Missouri", 29, 'MO');
	 this.addState("Montana", 30, 'MT');
	 this.addState("Nebraska", 31, 'NE');
	 this.addState("Nevada", 32, 'NV');
	 this.addState("New Hampshire", 33, 'NH');
	 this.addState("New Jersey", 34, 'NJ');
	 this.addState("New Mexico", 35, 'NM');
	 this.addState("New York", 36, 'NY');
	 this.addState("North Carolina", 37, 'NC');
	 this.addState("North Dakota", 38, 'ND');
	 this.addState("Ohio", 39, 'OH');
	 this.addState("Oklahoma", 40, 'OK');
	 this.addState("Oregon", 41, 'OR');
	 this.addState("Pennsylvania", 42, 'PA');
	 //this.addState("Puerto Rico", 72, 'PR');
	 this.addState("Rhode Island", 44, 'RI');
	 this.addState("South Carolina", 45, 'SC');
	 this.addState("South Dakota", 46, 'SD');
	 this.addState("Tennessee", 47, 'TN');
	 this.addState("Texas", 48, 'TX');
	 this.addState("Utah", 49, 'UT');
	 this.addState("Vermont", 50, 'VT');
	 //this.addState("Virgin Islands of the United States", 78, 'VI');
	 this.addState("Virginia", 51, 'VA');
	 this.addState("Washington", 53, 'WA');
	 this.addState("West Virginia", 54, 'WV');
	 this.addState("Wisconsin", 55, 'WI');
	 this.addState("Wyoming", 56, 'WY');

	this.textboxState = usStates;

	this.textboxCounty = document.createElement("input");
	this.textboxCounty.type = "text";
	this.textboxCounty.style.width = "39%";
	this.textboxCounty.style.height = "100%";
	this.textboxCounty.style.display = "none";
	this.textboxCounty.style.marginRight = "10px";
	
	this.textboxCensus = document.createElement("input");
	this.textboxCensus.type = "text";
	this.textboxCensus.style.width = "22%";
	this.textboxCensus.style.height = "100%";
	this.textboxCensus.style.display = "none";
	this.textboxCensus.style.marginRight = "10px";
	
	this.textboxBlock = document.createElement("input");
	this.textboxBlock.type = "text";
	this.textboxBlock.style.width = "12%";
	this.textboxBlock.style.height = "100%";
	this.textboxBlock.style.display = "none";
	this.textboxBlock.style.marginRight = "10px";

	this.textboxCong = document.createElement('select');
	this.textboxCong.style.display = "none";
	this.textboxCong.style.width = "66%";
	//this.textboxCong.style.height = "50%";
	this.textboxCong.style.marginRight = "10px";
	this.textboxCong.state = "";

	this.textboxSenate = document.createElement('select');
	this.textboxSenate.style.display = "none";
	this.textboxSenate.style.width = "98%";
	this.textboxSenate.style.marginRight = "10px";
	// populate the state senate drop down
	this.populateSenate();

	this.textboxStateDistOpts = document.createElement('select');
	this.textboxStateDistOpts.style.paddingLeft = "0px";
	this.textboxStateDistOpts.style.display = "none";
	this.textboxStateDistOpts.style.width = "27%";
	//this.textboxStateDistOpts.style.height = "50%";
	this.textboxStateDistOpts.style.marginRight = "10px";
	var option = document.createElement('option');
	option.innerHTML = "Upper House Districts";
	option.value = PPlaceType.SLD_UPPER.id;
	this.textboxStateDistOpts.appendChild(option);
	var option = document.createElement('option');
	option.innerHTML = "Lower House Districts";
	option.value = PPlaceType.SLD_LOWER.id;
	this.textboxStateDistOpts.appendChild(option);
	var box = this;
	PEvent.addListener(this.textboxStateDistOpts, 'change', function() {
		if (this.value == PPlaceType.SLD_UPPER.id)
			box.setType(PPlaceType.SLD_UPPER);
		else if (this.value == PPlaceType.SLD_LOWER.id)
			box.setType(PPlaceType.SLD_LOWER);
	});

	this.textboxStateDist = document.createElement('select');
	this.textboxStateDist.style.paddingLeft = "0px";
	this.textboxStateDist.style.display = "none";
	this.textboxStateDist.style.width = "38%";
	//this.textboxStateDist.style.height = "50%";
	this.textboxStateDist.style.marginRight = "10px";
	this.textboxStateDist.state = "";
	this.textboxStateDist.stateDistType = "";

	this.textboxCBSA = document.createElement('select');
	this.textboxCBSA.style.paddingLeft = "0px";
	this.textboxCBSA.style.display = "none";
	this.textboxCBSA.style.width = "66%";
	this.textboxCBSA.style.marginRight = "10px";
	this.textboxCBSA.state = "";
	
	var box = this;
	
	// Set the textboxes that we capture the enter key for.
	this.textboxArr = [this.textbox, this.textboxCBSA, this.textboxStateDist, this.textboxStateDistOpts, this.textboxCong, this.textboxCounty, this.textboxCensus, this.textboxBlock, this.textboxState, this.textboxSenate];
	
	// Set the textboxes that use autosuggest.
	this.autoSuggestBoxes = [this.textbox, this.textboxCounty];
	
	// Capture the enter key for all text boxes.
	for(var i=0; i<this.textboxArr.length; i++) {
		var enterKeyEvent = function(textbox) {
			return PEvent.addListener(textbox, 'keydown', function(e) {
				var e = e || window.event;
				if(e && e.keyCode == 13) {
					// Don't submit the search if a place is selected in autosuggest.
					// In that case, let autosuggest take care of loading the place.
					// If no place is selected, submit the search and remove the
					// autosuggest dropdown (if it exists).
					if(autosuggest.getSelectedItem() != null) {
						autosuggest.catchKey(textbox, "p", e);
					} else {
						box.submit();
						autosuggest.removeAutoSuggest();
					}
				}
			});
		}(this.textboxArr[i]);
	}
	
	// Capture all keyups and keydowns for all text fields that we offer autosuggest for,
	// except for the enter key, as that is specifically addressed above to prevent searches
	// from being initiated when the user hit enter while selecting an autosuggest item.
	for(var i=0; i<this.autoSuggestBoxes.length; i++) {
		var keyupEvent = function(textbox) {
			return PEvent.addListener(textbox, 'keyup', function(e) {
				var e = e || window.event;
				if(e && e.keyCode != 13) {
					autosuggest.catchKey(textbox, "p", e);
				}
			});
		}(this.autoSuggestBoxes[i]);
		var keydownEvent = function(textbox) {
			return PEvent.addListener(textbox, 'keydown', function(e) {
				var e = e || window.event;
				if(e && e.keyCode != 13) {
					autosuggest.catchKey(textbox, "p", e);
				}
			});
		}(this.autoSuggestBoxes[i]);
	}
	
	var geocoder = new PClientGeocoder();
	PEvent.addListener(this.textboxState, 'change', function(e) {
		this.style.color = '#7a7a7a';
		if (box.type[0] == PPlaceType.CENSUSTRACT || box.type[0] == PPlaceType.BLOCKGROUP)
			box.textboxCounty.focus();
		else if (box.type[0] == PPlaceType.CONGRESSIONAL)
			box.populateCongressional();
		else if (box.type[0] == PPlaceType.SLD_UPPER || box.type[0] == PPlaceType.SLD_LOWER)
			box.populateStateDistricts();
		else if (box.type[0] == PPlaceType.CBSA_07)
			box.populateCBSA07();
	});
	
	PEvent.addListener(this.textboxCong, 'change', function() {
		this.style.color = '#7a7a7a';
	});
	PEvent.addListener(this.textboxSenate, 'change', function() {
		this.style.color = '#7a7a7a';
	});

	node.appendChild(this.textboxState);
	node.appendChild(this.textboxCong);
	node.appendChild(this.textboxStateDistOpts);
	node.appendChild(this.textboxStateDist);
	node.appendChild(this.textboxCounty);
	node.appendChild(this.textboxCBSA);
	node.appendChild(this.textboxCensus);
	node.appendChild(this.textboxBlock);
	node.appendChild(this.textboxSenate);
	node.appendChild(this.textbox);

	// applies a focus event for the textboxes that helps keep track of which value to display
	this.setFocusEvents();
	this.setUp();
	
	// Store the provided place types we'll be offering searching for.
	this.storeSearchTypes(searchTypes);

	// Check if a typenode was provided.
	if(typeNode) {
		if (!this.options.typeStyle) {
			this.addSearchTabs(typeNode, searchTypes);
		}
		else if (this.options.typeStyle == 'dropdown') {
			// Build the dropdown of search options.
			this.addSearchDropdown(typeNode);
		}
		
		// Select the first search type.
		this.selectType(0);
	}
};

PTRFPlaceSearchBox.prototype.addSearchTabs = function(tabNode) { 
	var tabTypes = this.searchTypes;
	this.tabs = []; 
	var box = this; 
	for (var i=0; i<tabTypes.length; i++) { 
		var tab = document.createElement('a'); 
		var b = document.createElement('b'); 
		tab.appendChild(b); 
		tab.tabType = tabTypes[i];
		tab.tabNum = i; 
		if (tabTypes[i] == 'Default') { 
			b.innerHTML = "Search the Map"; 
			tab.className = "highlightTab"; 
			PEvent.addListener(tab, 'click', function() { 
				box.setType(); 
				box.selectTab(this.tabNum); 
				box.setSearchValue(); 
				for (var i=0; i<box.textboxArr.length; i++) { 
					if (box.textboxArr[i].style.display == "inline") { 
						// give focus to the textbox if default value isn't still set. 
						// this is so enter key will work when the tab is selected 
						if (box.textbox.value.search("Enter Address") != 0) 
							box.textboxArr[i].focus(); 
						break;
					}
				}
			});
		}
		else { 
			b.innerHTML = tabTypes[i].displayName; 
			tab.className = "searchboxTabs";
			PEvent.addListener(tab, 'click', function() { 
				box.setType(this.tabType); 
				box.selectTab(this.tabNum); 
				box.setSearchValue(this.tabType); 
				for (var i=0; i<box.textboxArr.length; i++) { 
					if (box.textboxArr[i].style.display == "inline") { 
						if (this.tabType == PPlaceType.SCHOOL) { 
							if (box.textbox.value != 'e.g., "Los Angeles Unified School District"') { 
								box.textboxArr[i].focus(); 
							}
						} else { 
							// Don't automatically focus the census tract or block group tab 
							// on any particular textbox. This maintains the prior behavior. 
							if(this.tabType != PPlaceType.CENSUSTRACT && this.tabType != PPlaceType.BLOCKGROUP) { 
								box.textboxArr[i].focus(); 
							}
						}
						break; 
					}
				}
			});
		}
		this.tabs.push(tab); 
		tabNode.appendChild(tab); 
	} 
};

PTRFPlaceSearchBox.prototype.storeSearchTypes = function(types) {
	// Stores the provided place types we're going to offer searching for. Adds a
	// 'Display Name' attribute to each place type for types where we display the
	// name slightly differently.
	
	// Loop through each of the provided types.
	for(var i=0; i<types.length; i++) {
		if(types[i] != "Default") {
			if(types[i] == PPlaceType.SLD_UPPER) {
				types[i].displayName = "State District";
			} else if(types[i] == PPlaceType.CBSA_07) {
				types[i].displayName = "Metro";
			} else if (!this.options.typeStyle && types[i] == PPlaceType.BLOCKGROUP) {
				types[i].displayName = "BG";
			} else {
				types[i].displayName = types[i].getName();
			}
		}
	}
	
	// Store the array of place types.
	this.searchTypes = types;
}

PTRFPlaceSearchBox.prototype.disableTab = function(tabNum) { 
	var tab = this.tabs[tabNum]; 
	tab.disabled = true; 
	tab.className += " searchboxDisableTab"; 
	PEvent.clearInstanceListeners(tab); 
}
	 	 
PTRFPlaceSearchBox.prototype.enableTab = function(tabNum) { 
	var tab = this.tabs[tabNum]; 
	tab.disabled = false; 
	tab.className = "searchboxTabs"; 
	var box = this;
	PEvent.addListener(tab, 'click', function() { 
		box.setType(box.tabTypes[tabNum]);
		box.selectTab(tabNum); 
		box.setSearchValue(box.tabTypes[tabNum]); 
	}); 
};
PTRFPlaceSearchBox.prototype.buildSetLocation = function(node) {
	// The reset function can vary slightly by page.
	var resetFunction = "resetMapAlert();";
	if(PEnvironment.pageName == "tables") {
		resetFunction = "clearChartAlert();";
	}
	var container = this.container;
	var className = "";
	// add class name so we can if needed apply different style for the different options
	if (this.options.typeStyle == 'dropdown')
		className = "searchWithDropDown";
	else
		className = "searchWithTabs";	

	// This will only be used on the widget page
	// If the body is too small to fit the search tabs then don't bother adding them since the layout will be screwy
	if (PEnvironment.pageName == 'widget') {
		var topMenuWidth = this.options.topMenuWidth;
		var maxWidth = 770;
		if (this.options.altlayout && $('body').width() < topMenuWidth+maxWidth)
			this.options.noSearchTypes = true;
		else if ($('body').width() < maxWidth)
			this.options.noSearchTypes = true;
	}

	var table = $('<table />');
	$(table).addClass(className);
	$(table).css({width:'100%'});

	// in order for the tabs layout to not break we have to add a min-width to the table
	// but if the tabs aren't on then no need
	if (!this.options.noSearchTypes)
		$(table).css({minWidth:'800px'});

	var tr = $('<tr />');

	// if any option is added then we'll add the row to the table
	var addRow = false;
	// option to remove the icon if specified
	if (!this.options.noSetLocationIcon) {
		var td = $('<td />');
		$(td).addClass('setLocationIconTD');
		$(td).attr({rowspan:"2", valign:"bottom", align:"right"});
		var div = $('<div />');
		$(div).addClass('setLocationIcon');
		$(td).append(div);
		$(tr).append(td);
		addRow = true;
	}
	if (!this.options.noSearchTypes || !this.options.noStartOver) {
		var td = $('<td />');
		addRow = true;
		// option to remove search types if specified
		if (!this.options.noSearchTypes) {
			var td = $('<td />');
			var span = $('<span />');
			$(span).addClass('searchboxSetLocationLabel');
			var b = $('<b />');
			$(b).html('Set Location');
			$(span).append(b);
			var typeNode = $('<span />');
			$(typeNode).addClass('searchboxtypes');
			this.typeNode = typeNode[0];
			$(td).append(span);
			$(td).append(typeNode);
		}

		// option to remove start over button if specified
		if (!this.options.noStartOver) {
			var so = $('<a />');
			$(so).addClass('startover');
			$(so).html('Start Over');
			// The reset link can vary slightly by page.
			if(!PEnvironment.pageName == "dataloader")
				$(so).attr('href', '#');

			$(so).click(function() {
				// The reset function can vary slightly by page.
				if(PEnvironment.pageName == "tables")
					clearChartAlert();
				else
					resetMapAlert();

				return false;
			});
			$(td).append(so);
		}
		$(tr).append(td);
		var td = $('<td />');
		$(tr).append(td);
	}
	if (addRow)
		$(table).append(tr);

	var tr = $('<tr />');
	var td = $('<td />');
	var searchdiv = $('<div />');
	$(searchdiv).addClass('searchboxDiv');
	// Add custom width to the searchbox if specified
	if (this.options.width)
		$(searchdiv).css('width',this.options.width);
	this.node = searchdiv[0];
	$(td).append(searchdiv);
	$(tr).append(td);
	var td = $('<td />');
	$(td).attr('align','left');
	var div = $('<div />');
	$(div).addClass('gobutton');
	$(div).click(function() {
		search.submit();
	});
	$(td).append(div);
	$(tr).append(td);
	$(table).append(tr);
	$(container).append(table);
}

PTRFPlaceSearchBox.prototype.addSearchDropdown = function(node) {
	// Builds the dropdown that allows the user to switch what kind of place they want
	// to search for (replacing the old tabs that we used to use). Expects node to be
	// the div the dropdown will be placed into.
	
	// Build the elements that make up the search dropdown.
	var containingDiv = document.createElement("div");
	containingDiv.className = "MyDropDowns SearchType";
	var containingUl = document.createElement("ul");
	containingUl.onclick = this.dropdownClick;
	containingUl.className = "firstlevel";
	var innerLi = document.createElement("li");
	innerLi.innerHTML = "Search By: ";
	var searchTypeSpan = document.createElement("span");
	searchTypeSpan.id = "SearchTypeDisplay";
	searchTypeSpan.className = "searchType";
	var innerUl = document.createElement("ul");
	innerUl.id = "searchdropdown";
	innerUl.className = "secondlevel";
	
	// Put the elements together.
	innerLi.appendChild(searchTypeSpan);
	innerLi.appendChild(innerUl);
	containingUl.appendChild(innerLi);
	containingDiv.appendChild(containingUl);
	node.appendChild(containingDiv);
	
	// Create a list item for each of the types that were specified.
	for(var i=0; i<this.searchTypes.length; i++) {
		// Get the current type's name.
		var typeName = "";
		if(this.searchTypes[i] == "Default") {
			typeName = this.defaultTextTitle;
		} else {
			typeName = this.searchTypes[i].displayName;
		}
		
		// Create the list item and put a div containing its name inside of it.
		var div = document.createElement("div");
		div.innerHTML = typeName;
		var li = document.createElement("li");
		li.id = "searchtype" + i;
		li.appendChild(div);
		
		// Create the click event for each list item. Use a closure to preserve
		// the item's position in the list.
		var s = this;
		PEvent.addListener(li, 'mousedown', function(num) {
			return function(e) {
				s.selectType(num);
			}
		}(i));
		
		// Put the list item into the list.
		innerUl.appendChild(li);
	}
};

PTRFPlaceSearchBox.prototype.dropdownClick = function() {
	// Called when the dropdown is clicked. Hides or shows it appropriately.
	var searchDropdown = document.getElementById("searchdropdown");
	if(searchDropdown.style.display == "none" || searchDropdown.style.display == "") {
		searchDropdown.style.display = "block";
	} else {
		searchDropdown.style.display = "none";
	}
}

PTRFPlaceSearchBox.prototype.selectTab = function(tabNum) {
	for (var i=0; i<this.tabs.length; i++) {
		if (i == tabNum)
			this.tabs[i].className = "highlightTab"; 
		else if (this.tabs[i].disabled == true) 
			this.tabs[i].className = "searchboxTabs searchboxDisableTab";
		else 
			this.tabs[i].className = "searchboxTabs"; 
	} 
}
PTRFPlaceSearchBox.prototype.selectType = function(typeNum) {
	if (this.options.typeStyle == 'dropdown')
		this.selectTypeDropDown(typeNum);
	else
		this.selectTab(typeNum);
}
PTRFPlaceSearchBox.prototype.selectTypeDropDown = function(typeNum) {
	// Called when a specific item is clicked in the dropdown.
	
	// Get the search type that was clicked.
	searchType = this.searchTypes[typeNum];
	
	// Get the span that displays the search type.
	var typeDisplay = document.getElementById("SearchTypeDisplay");
	
	// Check if we have a place type, or just the default search was clicked.
	if(searchType == "Default") {
		// The default search was clicked. Display it.
		this.setType();
		this.setSearchValue();
		for(var i=0; i<this.textboxArr.length; i++) {
			if(this.textboxArr[i].style.display == "inline") {
				// Give focus to the textbox if default value isn't still set.
				// This is so enter key will work when the tab is selected.
				if(this.textbox.value != this.defaultText) {
					this.textboxArr[i].focus();
				}
				break;
			}
		}
		// Display the default search's name in the dropdown title.
		typeDisplay.innerHTML = this.defaultTextTitle;
	} else {
		// A specific place type was clicked. Display it.
		this.setType(searchType);
		this.setSearchValue(searchType);
		for(var i=0; i<this.textboxArr.length; i++) {
			if(this.textboxArr[i].style.display == "inline") {
				if(searchType == PPlaceType.SCHOOL) {
					if(this.textbox.value != 'e.g., "Los Angeles Unified School District"') {
						this.textboxArr[i].focus();
					}
				} else {
					// Don't automatically focus the census tract or block
					// group tab on any particular textbox. This maintains
					// the prior behavior.
					if(searchType != PPlaceType.CENSUSTRACT && searchType != PPlaceType.BLOCKGROUP) {
						this.textboxArr[i].focus();
					}
				}
				break;
			}
		}
		// Display the place type's name in the dropdown title.
		typeDisplay.innerHTML = searchType.displayName;
	}
}

PTRFPlaceSearchBox.prototype.getCurrentType = function() {
	return this.type;
}

PTRFPlaceSearchBox.prototype.getType = function(typeNum) {
	return this.searchTypes[typeNum];
}

PTRFPlaceSearchBox.prototype.getTypes = function() {
	return this.searchTypes;
};

/*
When the search bar used tabs to switch between the different types of searches,
we used to have the ability to enable/disable any tab on the fly. By the time we
switched to using a dropdown instead of tabs, we no longer used that
functionality anywhere. Equivalent dropdown functionality has yet to be written.

PTRFPlaceSearchBox.prototype.disableType = function(typeNum) {

};

PTRFPlaceSearchBox.prototype.enableType = function(typeNum) {

};
*/

PTRFPlaceSearchBox.prototype.setSearchValue = function(tabType) {
	var search = this;
 	if (!tabType) {
		search.textbox.id = "as_searchthemap";

 		if (search.searchthemap && search.searchthemap.search("Enter Address") != 0) {
 			search.textbox.style.color = "#7a7a7a";
 			search.textbox.value = search.searchthemap;
 			search.tab = "searchthemap";
 		}
 		else {
 			search.textbox.style.color = "#fff";
 			search.textbox.value = search.defaultText;
 			search.tab = "searchthemap"
 		}
 	}
 	else if (tabType == PPlaceType.CONGRESSIONAL) {
 		if (search.congressional) {
	 		search.textbox.style.color = "#7a7a7a";
	 		search.tab = "congressional";
	 	}
	 	else {
 			search.textbox.style.color = "#fff";
 			search.tab = "congressional";
 		}
 	}
 	else if (tabType == PPlaceType.SCHOOL) {
		search.textbox.id = "as_school";

 		if (search.school && search.school.search("e.g.,") !=0) {
 			search.textbox.style.color = "#7a7a7a";
			search.textbox.value = search.school;
			search.tab = "school";
		}
		else {
 			search.textbox.style.color = "#fff";
 			search.textbox.value = 'e.g., "Los Angeles Unified School District"';
 			search.tab = "school";
 		}
 	}
 	else if (tabType == PPlaceType.CENSUSTRACT) {
		search.textbox.id = "as_census";

 		if (search.census && search.census.search("Enter 6-digit tract") != 0) {
 			search.textboxCensus.style.color = "#7a7a7a";
			search.textboxCensus.value = search.census;
		} else {
			search.textboxCensus.style.color = "#fff";
			search.textboxCensus.value = 'Enter 6-digit tract';
 		}
 		search.tab = "census"
 	}
 	else if (tabType == PPlaceType.BLOCKGROUP) {
 		search.textbox.id = "as_block";
 		if(search.census && search.census.search("Enter 6-digit tract") != 0) {
 			search.textboxCensus.style.color = "#7a7a7a";
			search.textboxCensus.value = search.census;
		} else {
			search.textboxCensus.style.color = "#fff";
			search.textboxCensus.value = 'Enter 6-digit tract';
 		}
		if(search.block && search.block.search("e.g.,") != 0) {
			search.textboxBlock.style.color = "#7a7a7a";
			search.textboxBlock.value = search.block;
		} else {
			search.textboxBlock.style.color = "#fff";
			search.textboxBlock.value = 'e.g., "1"';
		}
		search.tab = "block";
 	}
 	else if (tabType == PPlaceType.SLD_UPPER) {
 		if (search.statedistricts)
	 		search.textbox.style.color = "#7a7a7a";
	 	else
 			search.textbox.style.color = "#fff";
		search.tab = "statedistricts";
 	}
 	else if (tabType == PPlaceType.CBSA_07) {
 		if (search.cbsa)
	 		search.textbox.style.color = "#7a7a7a";
	 	else
 			search.textbox.style.color = "#fff";
		search.tab = "cbsa";
 	}
 	else if (tabType == PPlaceType.SENATE) {
 		if (search.senate) {
	 		search.textbox.style.color = "#7a7a7a";
	 		search.tab = "senate";
	 	}
	 	else {
 			search.textbox.style.color = "#fff";
 			search.tab = "senate";
 		}
 	}
 };

PTRFPlaceSearchBox.prototype.setFocusEvents = function() {
	var search = this;
	PEvent.addListener(search.textbox, 'focus', function() {
		this.style.color = '#7a7a7a';
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		if (!search.tab)
		search.tab = "searchthemap";
		this.value = "";	
	});
	PEvent.addListener(search.textboxState, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "census";
	});
	PEvent.addListener(search.textboxBlock, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "block";
	});
	PEvent.addListener(search.textboxCong, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "congressional";
	});
	PEvent.addListener(search.textboxSenate, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "senate";
	});
	PEvent.addListener(search.textboxStateDistOpts, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "statedistricts";
	});
	PEvent.addListener(search.textboxStateDist, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "statedistricts";
	});
	PEvent.addListener(search.textboxCBSA, 'focus', function() {
		if (this.wasClicked == true) return;
		this.wasClicked = true;
		search.tab = "cbsa";
	});
	// focus event that clears textbox if value is the default value
 	PEvent.addListener(search.textbox, 'focus', function() {
		var s = search.textbox.value;
		search.textbox.style.color = "#7a7a7a";
		if (s == search.defaultText) {
			search.tab = "searchthemap";
			this.value = "";
		}
		else if (s == 'e.g., "Los Angeles Unified School District"') {
			search.tab = "school";
			this.value = "";	
		}
	});
	// focus event that clears textbox if value is the default value
	PEvent.addListener(search.textboxCounty, 'focus', function() {
		search.textboxCounty.style.color = "#7a7a7a";
		var c = search.textboxCounty.value;
		if (c == 'Enter County') {
			this.value = "";
		}
		this.wasClicked = true;
	});
	// focus event that clears textbox if value is the default value
	PEvent.addListener(search.textboxCensus, 'focus', function() {
		search.textboxCensus.style.color = "#7a7a7a";
		var c = search.textboxCensus.value;
		if (c == 'Enter 6-digit tract') {
			this.value = "";
		}
		this.wasClicked = true;
	});
	// focus event that clears textbox if value is the default value
	PEvent.addListener(search.textboxBlock, 'focus', function() {
		search.textboxBlock.style.color = "#7a7a7a";
		var c = search.textboxBlock.value;
		if (c == 'e.g., "1"') {
			search.tab = "block";
			this.value = "";
		}
		this.wasClicked = true;
	});
};

PTRFPlaceSearchBox.prototype.reset = function() {
	this.setType(null);
	this.selectType(0);
	this.setSearchValue(null);

	// Set the default values for textboxes
	search.census = 'Enter 6-digit tract';
	search.block = 'e.g., "1"';
	search.school = 'e.g., "Los Angeles Unified School District"';
	search.searchthemap  = this.defaultText;
	search.textbox.value = search.searchthemap;
	search.textboxCounty.value = 'Enter County';
	search.textboxCounty.wasClicked = "";
};

PTRFPlaceSearchBox.prototype.setUp = function() {
	this.textbox.className = "searchbox";
	this.textbox.value = this.defaultText;
	this.textboxState.className = "searchbox";
	this.textboxCounty.className = "searchbox";
	this.textboxCounty.id = "as_county";
	this.textboxCounty.name = "as_county";
	this.textboxCounty.value = 'Enter County';
	this.textboxCong.className = "searchbox";
	this.textboxStateDistOpts.className = "searchbox";
	this.textboxStateDist.className = "searchbox";
	this.textboxCensus.className = "searchbox";
	this.textboxBlock.className = "searchbox";
	this.textboxCBSA.className = "searchbox";
	this.textboxSenate.className = "searchbox";
};

PTRFPlaceSearchBox.prototype.addListener = function(eventId, func) {
	this.eventManager.registerForEvent(eventId, [], func);
};

PTRFPlaceSearchBox.prototype.setDefaultTypes = function(types) {
	this.defaultType = types;
};

PTRFPlaceSearchBox.prototype.getSearchString = function() {
	return this.textbox.value;
};

PTRFPlaceSearchBox.prototype.getCountyString = function() {
	return this.textboxCounty.value;
};

PTRFPlaceSearchBox.prototype.getCensusString = function() {
	return this.textboxCensus.value;
};

PTRFPlaceSearchBox.prototype.setTypes = function(types) {
	if (types) {
		this.type = types;
	}
	else
		this.type = this.defaultType;
};

PTRFPlaceSearchBox.prototype.setType = function(type) {
	if (type)
		this.type = [type];
	else
		this.type = this.defaultType;

	// toggle input boxes
	if (type && type == PPlaceType.CENSUSTRACT) {
		this.textboxCong.style.display = "none";
		this.textboxState.style.display = "inline";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "inline";
		this.textboxCounty.style.width = "39%";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "inline";
		this.textboxBlock.style.display = "none";
		this.textbox.style.display = "none";
		this.textboxCBSA.style.display = "none";
		this.textboxSenate.style.display = "none";
	} 
	else if (type && type == PPlaceType.BLOCKGROUP) {
		this.textboxCong.style.display = "none";
		this.textboxState.style.display = "inline";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "inline";
		this.textboxCounty.style.width = "24%";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "inline";
		this.textboxBlock.style.display = "inline";
		this.textbox.style.display = "none";
		this.textboxCBSA.style.display = "none";
		this.textboxSenate.style.display = "none";
	} 
	else if (type && type == PPlaceType.CONGRESSIONAL) {
		this.textboxState.style.display = "inline";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "none";
		this.textbox.style.display = "none";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "none";
		this.textboxBlock.style.display = "none";
		this.textboxCong.style.display = "inline";
		this.textboxCBSA.style.display = "none";
		this.textboxSenate.style.display = "none";
		this.populateCongressional();
	} 
	else if (type && type == PPlaceType.SCHOOL) {
		this.textboxCong.style.display = "none";
		this.textboxState.style.display = "inline";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "none";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "none";
		this.textboxBlock.style.display = "none";
		this.textbox.style.display = "inline";	
		this.textbox.style.width = "65%";
		this.textboxSenate.style.display = "none";
		this.textboxCBSA.style.display = "none";
	}
	else if (type && (type == PPlaceType.SLD_UPPER || type == PPlaceType.SLD_LOWER)) {
		this.textboxState.style.display = "inline";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "none";
		this.textbox.style.display = "none";
		this.textboxCong.style.display = "none";
		this.textboxStateDistOpts.style.display = "inline";
		this.textboxStateDist.style.display = "inline";
		this.textboxCensus.style.display = "none";
		this.textboxBlock.style.display = "none";
		this.textboxCBSA.style.display = "none";
		this.textboxSenate.style.display = "none";
		this.populateStateDistricts();
	} 
	else if (type && type == PPlaceType.CBSA_07) {
		this.textboxState.style.display = "inline";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "none";
		this.textbox.style.display = "none";
		this.textboxCong.style.display = "none";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "none";
		this.textboxBlock.style.display = "none";
		this.textboxCBSA.style.display = "inline";
		this.textboxSenate.style.display = "none";
		this.populateCBSA07();
	} 
	else if (type && type == PPlaceType.SENATE) {
		this.textboxState.style.display = "none";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "none";
		this.textbox.style.display = "none";
		this.textboxCong.style.display = "none";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "none";
		this.textboxBlock.style.display = "none";
		this.textboxCBSA.style.display = "none";
		this.textboxSenate.style.display = "inline";
	}
	else {
		this.textboxState.style.display = "none";
		this.textboxState.style.paddingLeft = "0px";
		this.textboxCounty.style.display = "none";
		this.textbox.style.display = "inline";
		this.textbox.style.width = "97%";
		this.textboxCong.style.display = "none";
		this.textboxStateDistOpts.style.display = "none";
		this.textboxStateDist.style.display = "none";
		this.textboxCensus.style.display = "none";
		this.textboxBlock.style.display = "none";
		this.textboxCBSA.style.display = "none";
		this.textboxSenate.style.display = "none";
	}
};

PTRFPlaceSearchBox.prototype.populateDropDowns = function(placetypes, elem) {
	var geocoder = new PClientGeocoder();
	var d = this.textboxState;
	var stateText = d.options[d.selectedIndex].innerHTML;
	var stateId = d.options[d.selectedIndex].value;
	if (stateId != elem.state || (elem.stateDistType && placetypes[0] != elem.stateDistType)) {
		// clear dropdown
		while(elem.hasChildNodes())
			elem.removeChild(elem.firstChild);
		// find districts and populate dropdown
		var box = this;
		if (placetypes[0] == PPlaceType.CBSA_07) {
			// because some cbsa places overlap different states it needs to check places within the state
			geocoder.getPlace(stateText, function(stateplaces) {

				// Kluge to add a cbsa to drop down for DC since technically DC doesn't contain a cbsa but a cbsa contains DC
				// REMOVE this when db is fixed and the cbsa is returned as being contained by DC
				if (stateplaces[0].label == "District of Columbia") {
					var cdoption = document.createElement('option');
					// place id and label
					cdoption.value = 616030;
					cdoption.text = "Washington-Arlington-Alexandria, DC-VA-MD-WV Metropolitan Statistical Area";
					try {
						elem.add(cdoption,null);
					}
					catch (ex) {
						elem.add(cdoption);
					}
					return;
				}

				var state = stateplaces[0];
				// check so Arkansas isn't used instead of Kansas and make sure place is in US
				if (stateplaces.length > 1) {
					for (var j=0; j<stateplaces.length; j++) {
						if (stateplaces[j].getLabel() == stateText && stateplaces[j].country == "United States")
							state = stateplaces[j];
					}
				}
				state.getPlacesWithin(placetypes[0], function(places) {
					for (var i=0; i<places.length; i++) {
						var cdoption = document.createElement('option');
						cdoption.value = places[i].id;
						cdoption.text = places[i].getLabel().replace(stateText + " ", "");
						try {
							elem.add(cdoption,null);
						}
						catch (ex) {
							elem.add(cdoption);
						}
					}
					box.eventManager.triggerEvent('dd_initialized', places);
				}, 5, 200, PPlaceOrder.LABEL);
			}, 200, "geo_boundary_identifier", [PPlaceType.STATE]);
		}
		else {
			geocoder.getPlace(stateText, function(places) {
				var stext = "";
				// Congressional districts now have an added apostrophe s added to the state name
				// so remove that along with the state name when populating the district drop down
				if (placetypes[0]  == PPlaceType.CONGRESSIONAL)
					stext = "'s";
				for (var i=0; i<places.length; i++) {
					// Kluge: Currently places are populated based on the state string, so Arkansas places are appearing in Kanas dropdown
					// TODO: Use getPlacesWithin instead of getPlace, but need to get the state pplace object first
					if (stateText == "Kansas" && places[i].getState() == "AR")
						continue;
					var cdoption = document.createElement('option');
					cdoption.value = places[i].id;

					cdoption.text = places[i].getLabel().replace(stateText + stext + " ", "");
					try {
						elem.add(cdoption,null);
					}
					catch (ex) {
						elem.add(cdoption);
					}
				}
				// need to hard code 3 state house districts since PA has 203 in it and 200 is the max
				if (stateText == "Pennsylvania" && placetypes[0] == PPlaceType.SLD_LOWER) {
					var allplaces = places;
					PPlaceLoader.load([1884717, 1884718, 1884711], function(places) {
						for (var i=0; i<places.length; i++) {
							var cdoption = document.createElement('option');
							cdoption.value = places[i].id;
							cdoption.text = places[i].getLabel().replace(stateText + " ", "");
							try {
								elem.add(cdoption,null);
							}
							catch (ex) {
								elem.add(cdoption);
							}
							allplaces.push(places[i]);
						}
						box.eventManager.triggerEvent('dd_initialized', allplaces);
					});
				}						
				else
					box.eventManager.triggerEvent('dd_initialized', places);
			}, 200, "geo_boundary_identifier", placetypes);
		}

		// keep track of state value to avoid reloading
		elem.state = stateId;
		// keep track of state district type(upper or lower)
		if (elem.stateDistType || elem.stateDistType == "") {
			elem.stateDistType = placetypes[0];
		}
	}
};

PTRFPlaceSearchBox.prototype.getSearchStateAbbr = function() {
	var d = this.textboxState;
	var stateText = d.options[d.selectedIndex].title;
	return stateText;
}
PTRFPlaceSearchBox.prototype.populateCongressional = function() {
	this.populateDropDowns(this.type, this.textboxCong);
};
PTRFPlaceSearchBox.prototype.populateStateDistricts = function() {
	this.populateDropDowns(this.type, this.textboxStateDist, this.stateDistState, this.stateDistType);
};
PTRFPlaceSearchBox.prototype.populateCBSA07 = function() {
	this.populateDropDowns(this.type, this.textboxCBSA, this.cbsaState);
};
PTRFPlaceSearchBox.prototype.populateSenate = function() {
	var elem = this.textboxSenate;
	var ptype = PPlaceType.SENATE;
	geocoder.getPlace("", function(places) {
		for (var i=0; i<places.length; i++) {
			var cdoption = document.createElement('option');
			cdoption.value = places[i].id;

			cdoption.text = places[i].getLabel();
			try {
				elem.add(cdoption,null);
			}
			catch (ex) {
				elem.add(cdoption);
			}
		}
	}, 200, "canonical_name", [ptype]);
};

PTRFPlaceSearchBox.prototype.cleanString = function(s) {
	if (s.search("e.g.,") == 0) {			
		return '';
	} else {
		return s.replace(/^\s+|\s+$/g,"");
	}
};

PTRFPlaceSearchBox.prototype.submit = function() {
	var geocoder = new PClientGeocoder();
	this.eventManager.triggerEvent('submit');
	var box = this;
	var text = this.getSearchString();
	var type = this.type;
	if (text.search("e.g.,") == 0) {
		 text = text.replace(/e.g., "/,"");
		 text = text.replace(/"/,"");
	}

	// explicit lat/lng
	var matches = /^(-?\d+(\.\d+)?),(-?\d+(\.\d+)?)$/.exec( text );
	if( matches ) {
		var lat = parseFloat(matches[1]);
		var lng = parseFloat(matches[3]);
		var address = new PAddress(lat+','+lng,lng,lat);
		box.eventManager.triggerEvent('response',address);
	}
	// Find census tracts or block groups.
	else if(this.type && (this.type[0] == PPlaceType.CENSUSTRACT || this.type[0] == PPlaceType.BLOCKGROUP)) {
		if(this.type[0] == PPlaceType.CENSUSTRACT) {
			var placeTypeDisplay = "census tract";
		} else {
			var placeTypeDisplay = "block group";
		}
		var d = this.textboxState;
		var stateText = d.options[d.selectedIndex].value;
		var countyText = this.textboxCounty.value;
		if (countyText.search("e.g.,") == 0) {
			countyText = countyText.replace(/e.g., "/,"");
			countyText = countyText.replace(/"/,"");
		}
		var censusText = this.textboxCensus.value;
		var blockText = this.textboxBlock.value;

		if(this.cleanString(countyText) == '') {
			this.textboxCounty.focus();
			return;
		} else if(this.cleanString(censusText) == '') {
			this.textboxCensus.focus();
			return;
		} else if(this.type[0] == PPlaceType.BLOCKGROUP && this.cleanString(blockText) == '') {
			this.textboxBlock.focus();
			return;
		}

		if (this.cleanString(text) != "") {
			var f = function(places) {
				if (places.length > 0)
					box.eventManager.triggerEvent('response', places);
				else {
					var alerter = new PAlerter();
					var errorLocation = d.options[d.selectedIndex].innerHTML + ", " + countyText + ", " + censusText;
					if(placeTypeDisplay == "block group") {
						errorLocation += ", " + blockText;
					}
					var content = "Location \"<b>" + errorLocation + "</b>\" was not found. For help finding the " + placeTypeDisplay + ",  <a class='pagelinks' href='" + PEnvironment.blogUrl + "/?p=3580' target='_blank'>click here</a>.";
					alerter.popup(content, null, null, "OK");
				}
			};

			if(this.type[0] == PPlaceType.CENSUSTRACT) {
				var path = ['states', 'fips', stateText, 'counties', 'names', countyText, 'censustracts', 'numbers', censusText];
			} else {
				var path = ['states', 'fips', stateText, 'counties', 'names', countyText, 'censustracts', 'numbers', censusText, 'blockgroups', 'numbers', blockText];
			}
			path = path.join('/');
                        PPlaceLoader.loadByPath(path, f, {ord:'geo_boundary_identifier asc'});
		}
	// get congressional district
	} else if (this.type && this.type[0] == PPlaceType.CONGRESSIONAL) {
		var d = this.textboxCong;
		var congid = d.options[d.selectedIndex].value;
		PPlaceLoader.load([congid], function(places) {
			box.eventManager.triggerEvent('response', places);
		});
	// find school district
	} else if (this.type && this.type[0] == PPlaceType.SCHOOL) {
		var d = this.textboxState;
		var stateText = d.options[d.selectedIndex].title;
		text += ', '+ stateText;
		if (this.cleanString(text) == '') {
			alert('Please enter School District name.');
			return;
		}
		if (this.cleanString(text) != "") {
			geocoder.getPlace(text,
				function(places) {
					if (places.length > 0)
						box.eventManager.triggerEvent('response',places);
					else {
						var alerter = new PAlerter();
						var content = "Location \"<b>" + search.getSearchString() + "</b>\" not found.";
						alerter.popup(content, null, null, "OK");
					}
					},
					5,
					PPlaceOrder.POPULATION,
					box.type
			);
		}
	// get upper house districts
	} else if (this.type && (this.type[0] == PPlaceType.SLD_UPPER || this.type[0] == PPlaceType.SLD_LOWER)) {
		var d = this.textboxStateDist;
		var statedistid = d.options[d.selectedIndex].value;
		PPlaceLoader.load([statedistid], function(places) {
			box.eventManager.triggerEvent('response', places);
		});
	// get cbsa
	} else if (this.type && this.type[0] == PPlaceType.CBSA_07) {
		var d = this.textboxCBSA;
		var cbsaid = d.options[d.selectedIndex].value;
		PPlaceLoader.load([cbsaid], function(places) {
			box.eventManager.triggerEvent('response', places);
		});
	// get senate district
	} else if (this.type && this.type[0] == PPlaceType.SENATE) {
		var d = this.textboxSenate;
		var senateid = d.options[d.selectedIndex].value;
		PPlaceLoader.load([senateid], function(places) {
			box.eventManager.triggerEvent('response', places);
		});
	// find all other places
	} else {
		var placetypes = null;
		// check for county subdivision text
		if (text.toLowerCase().indexOf(' county subdivision') != -1) {
			text = text.toLowerCase().replace(' county subdivision','');
			placetypes = [PPlaceType.COUNTY_SUBDIVISION];
		} else
			placetypes = box.type;

		if (this.cleanString(text) != "") {
			geocoder.getPlace(text,
				function(places) {
					if (places.length > 0)
						box.eventManager.triggerEvent('response',places);
					else
						geocoder.getLocations(text, function(address) {
							box.eventManager.triggerEvent('response',address);
						});
					},
					5,
					PPlaceOrder.POPULATION,
					placetypes
			);
		}
	}

	if (this.tab == "searchthemap") {
		this.searchthemap = this.textbox.value;
	} else if (this.tab == "county") {
		this.county = this.textbox.value;
	} else if (this.tab == "census") {
		this.census = this.textboxCensus.value;
	} else if (this.tab == "block") {
		this.census = this.textboxCensus.value;
		this.block = this.textboxBlock.value;
	} else if (this.tab == "school") {
		this.school = this.textbox.value;
	}

};

// Initiates the searchbox with all the tabs and sets the search event
function initSearchBox(options) {
	var searchTabTypes = [ 'Default', PPlaceType.CENSUSTRACT, PPlaceType.BLOCKGROUP,
	                       PPlaceType.CONGRESSIONAL, PPlaceType.SENATE, PPlaceType.SCHOOL, PPlaceType.SLD_UPPER,
	                       PPlaceType.CBSA_07];
	// search box
	search = new PTRFPlaceSearchBox(document.getElementById("SetLocation"), searchTabTypes, options);

	// limit types (e.g. so we don't end up searching for zcta types)
	search.setDefaultTypes( [ PPlaceType.COUNTRY, PPlaceType.STATE, PPlaceType.COUNTY,
	                          PPlaceType.COUNTY_SUBDIVISION, PPlaceType.CITY, PPlaceType.ZIP ]);
	search.setTypes(null);

	search.addListener('response', function(places) {
		var html = null;

		if (places instanceof PAddress) {
			if (places.wasFound()) {
				session.placeName = '"' + places.addr + '"';
				// TODO: remove old session code
				session2.put('place', places.addr);
				session2.put('lng', places.x);
				session2.put('lat', places.y);

				html = "" + places.addr + "<br /><br />";
				addMarkerWindow(html, new PLatLng(places.y, places.x));
			} else {
				var alerter = new PAlerter();
				var content = "Location \"<b>" + places.addr + "</b>\" not found. For help finding your address or city:  <a class='pagelinks' href='" + PEnvironment.blogUrl + "/?p=200' target='_blank'>click here</a>";
				alerter.popup(content, null, null, "OK");
			}
		} else {
			// KLUGE: filter out non US places
			var l = places.length;
			var full = places;
			places = [];
			var p;
			for ( var i = 0; i < l; i++) {
				p = full[i];
				if (p.country == "United States") {
					places.push(p);
				}
			}

			if (places.length == 0) {
				var alerter = new PAlerter();
				alerter.popup("Location \"<b>" + search.getSearchString() + "</b>\" not found.", null, null, "OK");
			} else {
				var html = createPlacesDiv(places, search.getSearchString());
				addMarkerWindow(html, places[0]);
				session2.put('p', places[0].id);
			}
		}
	});
}

