	var multiAddrBorderPadding = 0.001;
	
	var zoomStartMin = 2;
	var zoomMax = 16;
	
	var addresses;
	var map;   
	
	var markers;
	var infoWindows;

	var directionsService;
	var directionsDisplay;
	
	var originalDirectionsAreaInnerHTML;
	var originalDirectionsAreaCssText;

	function Address(centerPt_, title_, address1_, address2_, city_, state_, zip_, phone_) {
		this.centerPt = centerPt_;
		this.title = title_;
		this.address1 = address1_; 
		this.address2 = address2_;
		this.city = city_;
		this.state = state_;
		this.zip = zip_;
		this.phone = phone_;

		this.determineDirectionsAddress = function() {
			var addressBreak = "";
		    
		    if (this.address2 != "") {
		    	addressBreak = ", "	
		    }
			
			return this.title + " (" + this.address1 + addressBreak + this.address2 + ", " + this.city + ", " + this.state + " " + this.zip + ", USA)"; 
		};

		this.determineDisplayAddress = function() {
		    var addressBreak = "";
		    
		    if (this.address2 != "") {
		    	addressBreak = "<br />"	
		    }
		
			return "<h1 style='font: 16px Arial; font-weight: bold; margin-top: 0px; margin-left: 0xp; margin-bottom: 4px; margin-right: 10px;'>" + this.title + "</h1><font style='font: 14px Arial;'>" + this.address1 + addressBreak + this.address2 + "<br />" + this.city + ", " + this.state + " " + this.zip + "<br />" + this.phone + "</font>"; 
		};

		this.determineMarkerHtml = function(addressIndex, markerIndex, prevValue) {
			var displayAddress = this.determineDisplayAddress();
      
			var directionForm = "<form style='margin-top: 2px; margin-bottom:2px; margin-left: 0px; margin-right: 0px; vertical-align: middle;' name=directions onsubmit='getDirections(" + addressIndex + ", " + markerIndex + ", this.fromAddress.value); return false;'><font style='font: 14px Arial;'>Directions From:</font> <input type=text name=fromAddress value=\"" + escapeHtml(prevValue) + "\" style='width: 190px;'> <input type=submit value=Go></form>";
			var markerHtml = displayAddress + directionForm;

			return markerHtml;
		};
	}


	function initializeMap(addresses_) {
		addresses = addresses_;
		
		directionsService = null;
		directionsDisplay = null;
		originalDirectionsAreaInnerHTML = null;
		originalDirectionsAreaCssText = null;	
		map = null;
		
		setupMap();
		addMarkers();
	}

    
	function reset() {
		if (directionsDisplay) {
			directionsDisplay.setMap(null);
			directionsDisplay.setPanel(null);
			
			var directionAreaElem = document.getElementById("directions_area");
		
			if (directionAreaElem && originalDirectionsAreaInnerHTML && originalDirectionsAreaCssText) {
				directionAreaElem.innerHTML = originalDirectionsAreaInnerHTML;
				directionAreaElem.style.cssText = originalDirectionsAreaCssText;
			}
		}
		
		removeMarkers();
		setupMap();
		addMarkers();
	}


	function addMarkers() {
		markers = new Array();
		infoWindows = new Array();
		
	    var openWindow = (addresses.length == 1);

		for (var i = 0; i < addresses.length; i++) {
			addMarker(i, openWindow);   
		}
	}     


	function removeMarkers() {
		while (markers.length > 0) {
			var marker = markers.pop();
			var infoWindow = infoWindows.pop();
	    
			infoWindow.close();
			marker.setMap(null);         
		}
	}

      
	function setupMap() {
		var bounds = null;
		
		var highLat;
		var lowLat;

		var highLng;
		var lowLng;

		for (var i = 0; i < addresses.length; i++) {
			if (!highLat || highLat < addresses[i].centerPt.lat()) {
				highLat = addresses[i].centerPt.lat();
			}

			if (!lowLat || lowLat > addresses[i].centerPt.lat()) {
				lowLat = addresses[i].centerPt.lat();
			}

			if (!highLng || highLng < addresses[i].centerPt.lng()) {
				highLng = addresses[i].centerPt.lng();
			}

			if (!lowLng || lowLng > addresses[i].centerPt.lng()) {
				lowLng = addresses[i].centerPt.lng();
			}
		}

		var centerLat = (highLat + lowLat) / 2;
		var centerLng = (highLng + lowLng) / 2;

        var zoomLevel;
        
        if (addresses.length > 1) {
			bounds = new google.maps.LatLngBounds(new google.maps.LatLng(lowLat - multiAddrBorderPadding, lowLng - multiAddrBorderPadding), new google.maps.LatLng(highLat + multiAddrBorderPadding, highLng + multiAddrBorderPadding));
			zoomLevel = zoomStartMin;
		}
		else {
			zoomLevel = zoomMax;
			centerLat += 0.00105;
		}

  		var mapOptions = {     
  			zoom: zoomLevel,     
  			center: new google.maps.LatLng(centerLat, centerLng),     
  			mapTypeId: google.maps.MapTypeId.ROADMAP,
  			panControl: true, 
  			zoomControl: true,   
  			mapTypeControl: false,   
  			scaleControl: false,   
  			streetViewControl: false,   
  			overviewMapControl: false
  		};

		if (map == null) {
			map = new google.maps.Map(document.getElementById("map_area"), mapOptions);
		}
		else {
			map.setOptions(mapOptions);
		}

		if (bounds != null) {
			map.fitBounds(bounds);
		}
	}


	function addMarker(addressIndex, open) {
		var address = addresses[addressIndex];
		var markerIndex = markers.length;      
      
		var marker = new google.maps.Marker({       
			position: address.centerPt,        
			map: map,        
			title: address.title,
			draggable: false,
			visible: true,
			clickable: true
		});   
      
      	var infoWindow = new google.maps.InfoWindow({     
      		content: address.determineMarkerHtml(addressIndex, markerIndex, "") 
      	});  
      	
      	google.maps.event.addListener(marker, 'click', function() {   
      		infoWindow.open(map, marker); 
      	});
      
		markers[markerIndex] = marker;
		infoWindows[markerIndex] = infoWindow;

		if (open) {
			infoWindow.open(map, marker);
		}
	}


	function getDirections(addressIndex, markerIndex, fromAddressStr) {
		if (directionsService == null) {
			directionsService = new google.maps.DirectionsService();
		}
		
		var markerHtml = addresses[addressIndex].determineMarkerHtml(addressIndex, markerIndex, fromAddressStr);
		
		if (!fromAddressStr.match(/^\s*$/)) {
			var directionsRequest = {   
				origin: fromAddressStr,   
				destination: addresses[addressIndex].centerPt,   
				travelMode: google.maps.DirectionsTravelMode.DRIVING,   
				unitSystem: google.maps.DirectionsUnitSystem.IMPERIAL,   
				provideRouteAlternatives: false
			};
			
			directionsService.route(directionsRequest, function(result, status) {     
				if (status == google.maps.DirectionsStatus.OK) {
					result.routes[0].legs[0].end_address = addresses[addressIndex].determineDirectionsAddress();   
					var directionAreaElem = document.getElementById("directions_area");
		
					if (directionAreaElem) {
						originalDirectionsAreaInnerHTML = directionAreaElem.innerHTML;
						originalDirectionsAreaCssText = directionAreaElem.style.cssText;		
					
						directionAreaElem.innerHTML = " ";
						directionAreaElem.style.textAlign = "left";
						directionAreaElem.style.width = "756px";
						directionAreaElem.style.height = "auto";
						directionAreaElem.style.marginTop = "5px";
						directionAreaElem.style.marginLeft = "10px";
						directionAreaElem.style.paddingBottom = "25px";
						directionAreaElem.style.verticalAlign = "top";
						directionAreaElem.style.backgroundColor = "#FFFFFF";
						directionAreaElem.style.color = "#000000";
							    
				    	removeMarkers();
					
						directionsDisplay = new google.maps.DirectionsRenderer({
							map: map,
							panel: directionAreaElem,
							draggable: false,
							directions: result
						});    						
					}
					else {
						openInfoWindowWithError(markerIndex, markerHtml);	
					}
				}   
				else {
					openInfoWindowWithError(markerIndex, markerHtml);
				}
			}); 

		}
		else {
			openInfoWindowWithError(markerIndex, markerHtml);
		}
	}   
	
	
	function openInfoWindowWithError(markerIndex, previousMarkerHtml) {
		var newMarkerHtml = previousMarkerHtml + "<font color=red style='font: 12px Arial;'>Please enter a starting address.<br />Example: 1600 Pennsylvania Ave, Washington, DC 20500</font>";        
			
		infoWindows[markerIndex].close();
		infoWindows[markerIndex].setContent(newMarkerHtml);
		infoWindows[markerIndex].open(map, markers[markerIndex]);	
	}
	
	
	function escapeHtml(str) {
	    if (!str || str.match(/^\s*$/)) {
	    	return str;
	    }
	    else {
			var div = document.createElement('div');
			var text = document.createTextNode(str);
		
			div.appendChild(text);
			var result = div.innerHTML.replace(/\"/, "&quot;");
		
			return result;
		}
	}
