
	var lastGeoCode = null ;

	var selectedAddresses = new Array();

	var colors = new Array('red',
					'green',
					'blue',
					'yellow',
					'cyan',
					'magenta',
					'light blue',
					'gray');
	/**
		Clear form, remove popup, and empty selected list
	*/
	function resetForm()
	{
		clearForm() ;
		hidePopup() ;
		clearDisplay() ;
		clearGlobalMap() ;
		
		selectedAddresses = new Array();
	}
	
	/**
		Send user input to server to validate address
	*/
	function addAddress()
	{
		if(document.forms['sortform'].address.value.length < 1 || 
			(document.forms['sortform'].zip.value.length < 1 && 
			 (document.forms['sortform'].city.value.length < 1 ||
			 document.forms['sortform'].state.value.length < 1))) {
			alert("The address must be specified and a zip code or city and state must be specified.") ;
			return false;
		}
		
		var mqg 	= new MQGeocode();
		var newLoc  = new MQLocation();
		
		newLoc.setAddress(document.forms['sortform'].address.value);
		newLoc.setStateProvince(document.forms['sortform'].state.value);
		newLoc.setCity(document.forms['sortform'].city.value);
		newLoc.setPostalCode(document.forms['sortform'].zip.value);
		
		mqg.doGeocode(newLoc, "addressRetrieve");
		
		return false;
	}
   
    /**
		Sort Selected Addresses 
	*/
    function sortAddresses() 
	{
		if(selectedAddresses.length == 0) 
		{
			alert("No addresses selected") ;
			return ;
		}
				
		var sortedList = new Array() ;
		sortedList.push(selectedAddresses.shift()) ; 
		
		while(selectedAddresses.length > 0) 
		{
			var foundLoc = getNextLocation(sortedList[sortedList.length - 1], selectedAddresses);
			
			//Remove the found location
			for(i = 0 ; i < selectedAddresses.length ; i++) 
			{
				if(foundLoc == selectedAddresses[i]) 
				{
					selectedAddresses.splice(i,1) ;
				}
			}
			
			sortedList.push(foundLoc) ;
		}
		
		selectedAddresses = sortedList ; 
		
		clearForm() ;
		clearDisplay() ;
		
		clearGlobalMap() ;
		generateGlobalMap() ;	
	}
	
	/**
		Create a MapQuest map with all the locations on it 
	*/
	function generateGlobalMap() {
		var mq1 = new MQMap("globalMap");
		
		//update the display
		for(i = 0 ; i < selectedAddresses.length ; i++) 
		{
			addLocationToDisplay(selectedAddresses[i], i);
			
			selectedAddresses[i].setIconId((i%8)+21);
			mq1.locations.add(selectedAddresses[i]);

		}
		mq1.setRolloverPopups(false);//To disable the popups
		mq1.getMap();
		
		populateRouting();
	}
	
	/**
		Find the next address 
	*/
	function getNextLocation(start, available) 
	{
		var minDistance = null ;
		var curr= null ;
		
		for(i = 0 ; i < available.length ; i++) 
		{
			var distance = getDistance(start, available[i]) ;
			
			if(curr == null || distance < minDistance) 
			{
				curr = available[i] ;
				minDistance = distance ;
			}
		}
		
		return curr ;
	}
	
	/**
		Get the distance between two locations
	*/
	function getDistance(one, two) 
	{
		var x = one.getLatitude() ;
		var y = one.getLongitude(); 
		
		var a = two.getLatitude() ;
		var b = two.getLongitude();
		
		return Math.sqrt(Math.pow(a - x, 2) + Math.pow(b - y, 2)) ;
	}
	
    /**
		Callback function for sending users address to the server
		Show popup of results found
	*/
	function addressRetrieve(geocode)
	{
		lastGeoCode = geocode ;
		var status = geocode.getGeocodeStatus() ;
		
		if(status >= 1022 && status != 1900 && status != 1100) {
			alert("Address not specific enough.");
			return;
		}
		
		var addressDiv = document.getElementById("selectAddress"); 
		
		addressDiv.innerHTML = "" ;
		
		//If an exact match is found, then add it
		if(geocode.locations.getSize() == 1) {
			addLocationToList(0);
		}
		else {
			for(var i = 0 ; i < geocode.locations.getSize() ; i++) 
			{
				var loc = geocode.locations.getAt(i);
				var linkDesc = loc.getAddress() + ", " + loc.getCity() + ", " + loc.getStateProvince() + ", " + loc.getPostalCode();
				addressDiv.innerHTML += "<a id=" + i + " href='javascript:addLocationToList(" + i + ")'>" + linkDesc + "</a>";
				addressDiv.innerHTML += "<br/>";
			}
			
			addressDiv.style.display = 'block';
		}
	}
	
	/**
		Function called from link in popup of found addresses
	*/
	function addLocationToList(locationId) 
	{
		hidePopup() ;
		
		var location = lastGeoCode.locations.getAt(locationId) ;
		
		addLocationToDisplay(location, selectedAddresses.length ) ;
		
		//Put location at end of list
		selectedAddresses.push(location) ; 
	}
	
	/**
		Remove an element from the display
	*/
	function deleteLocationFromDisplay(index) {
		selectedAddresses.splice(index, 1) ;
		
		clearDisplay() ;

		var gmDiv = document.getElementById("globalMap");
		
		if(gmDiv.innerHTML != "" && selectedAddresses.length > 0) {
			clearGlobalMap() ;
			generateGlobalMap() ;
		} 
		else {
			clearGlobalMap() ;
			
			for(i = 0 ; i < selectedAddresses.length ; i++) 
			{
				addLocationToDisplay(selectedAddresses[i], i);
			}
		}
	}
	
	/**
		Put a location in the selected addresses list
	*/
	function addLocationToDisplay(location, index) 
	{
		var selectedDiv = document.getElementById("selectedAddresses"); 
		
		colorStr = "style='background-color: " + colors[index%colors.length] + ";'" ;
		
		if(index == null) {
			loc = selectedAddresses.length - 1 ;
		}
		else {
			loc = index ;
		}
		
		link = "<a href='javascript:void(deleteLocationFromDisplay(" + loc + "))'>X</a>"
		
		selectedDiv.innerHTML += "<table cellpadding=0 cellspacing=0 class='selectedLocation'" + colorStr + "><tr><td>" + 
							location.getAddress() + " " + location.getCity() + ", " + 
							location.getStateProvince() + " " + location.getPostalCode() + 
							"</td><td width='15px'>" + link + "</td></tr></table>"
			
		clearForm();
		giveFocus();
	}

	/**
		Hide the popup window
	*/
	function hidePopup() 
	{
		var addressDiv	= document.getElementById("selectAddress"); 
		addressDiv.style.display = 'none';
	}
	
	/**
		Remove all addresses from the selected list
	*/
	function clearDisplay() 
	{
		var selectedDiv = document.getElementById("selectedAddresses");
		selectedDiv.innerHTML    = "";
	}
	
	/**
		Remove the previously generated map
	*/
	function clearGlobalMap() 
	{
		var selectedDiv = document.getElementById("globalMap");
		selectedDiv.innerHTML    = "";
	}
	
	/**
		Clear the form on the page
	*/
	function clearForm() 
	{
		document.forms['sortform'].address.value = "";
		document.forms['sortform'].state.value   = "";
		document.forms['sortform'].city.value    = "";
		document.forms['sortform'].zip.value     = "";
	}
	
	function giveFocus(address)
	{	
		document.getElementById('address').focus(); 	
	}
	
	/**
		Here we will do the routing 
	*/
	
	var currentAddress ;
	
	/* here we want to pass to the populate routing our hideDisplayStyleDiv function */
	function populateRouting(currAddress)
	{
		if(currAddress == null) {
			currAddress = 0 ;
			document.getElementById('directions').innerHTML = "" ;
		}

		if(currAddress < selectedAddresses.length - 1) {
			var i = currAddress ;
			currentAddress = currAddress ; 
			
			//Make routing call
			mqRoute = new MQRoute("hideme");
			
			mqRoute.origin  = selectedAddresses[i] ;
			mqRoute.destination = selectedAddresses[i+1] ;// i + 1 append to the last of the list
	
			mqRoute.doRoute("routeReturn");		
		}
	}
    /*  
		call back method   
	  */
	function routeReturn(mqRoute, status) { 
		var directions = document.getElementById('directions') ;
			
		var output = "<br/><table cellspacing=0 cellpadding=0>" ;
		
		output += "<tr class='header'><td colspan='2'>" + mqRoute.origin.getAddress() + " " + mqRoute.origin.getPostalCode() + " to <br/>" +
		           mqRoute.destination.getAddress() + " " + mqRoute.destination.getPostalCode() + "</td></tr>";
		
		for(var i = 0 ; i < mqRoute.maneuvers.getSize() ; i++) {
			var currentDir = mqRoute.maneuvers.getAt(i) ;
			
			output += "<tr class='" + (i % 2 == 0 ? "even" : "odd") + "'><td>" ; 
			output += currentDir.getNumber() +": " + currentDir.getText() + "</td><td class='distance'>" ;
			output += currentDir.getDistance() + currentDir.getDistanceUnit() ;			
			output += "</td></tr>" ;
		}
		
		output += "</table></br>" ;
		directions.innerHTML += output ;

		populateRouting(currentAddress + 1) ;
	}

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	 
