//			
//		mapfunctions.js - Written by Max Miller for Carhartt Inc. 	 Last Modified: 7/23/07
//
//		Purpose: provides the functions that directly access the Google Map API 

	




	var currentMarker;	
	var geo = new GClientGeocoder();	
	var map = null;
	var sidebar='';
	var gdir;	 
	var htmlside =[];	// sidebar html
	var req;
	
	//reasons (array of geocoding status)
	var reasons=[];
	reasons[G_GEO_SUCCESS]            = "Success";
	reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
	reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
	reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
	reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
	

	function sortByDist(a, b) 
	//Purpose: returns values to the Javascript sort() function allowing it to sort in the correct order
	{
    	var x = a.Dist;
    	var y = b.Dist;
    	return ((x < y) ? -1 : ((x > y) ? 1 : 0));
	}

	
	

	function checkmap(required)
	//Purpose: gets the bounds of the map, and re-populates the map based on the markers that meet the correct criterion
	// passed the required number of markers to popMarkers, will zoom out until reaches
	{
			// bounds of map on screen
			var bounds = map.getBounds();
			var swpoint = bounds.getSouthWest();
			var nepoint = bounds.getNorthEast();
			var maxy = nepoint.lat();
			var maxx = nepoint.lng();
			var miny = swpoint.lat();
			var minx = swpoint.lng();
			var sidebar_html = "";
			popMarkers(minx, maxx, maxy, miny, required);	
	}
        

	function setDirections(fromAddress, toAddress) 
	//Purpose: load the directions in the sidebar (called from form populated in collectstoredetails.php)
	{
      
      //string parsing mash-up to directly call Google's printable directions
      var namesplit = toAddress.split('@');	
      var store_name = namesplit[0];
      document.getElementById('dest').value = toAddress.substring((toAddress.indexOf('@'))+1);
      var toparse = document.getElementById('dest').value;
      var temp = new Array();	
	  temp = toparse.split(',');
	  temp[1] = temp[1].substring(1);
	  toparse = temp[0]+",+"+temp[1]+"("+store_name+")&ie=UTF8&z=14&om=1&pw=2";
	  //end mash-up
	  
	  document.getElementById('dest').value = toparse;	//load printable directions URL for access
      gdir.load("from: " + fromAddress + " to: " + toAddress);	//call directions on map/sidebar
	}

	function onLoad()
	//Calls when page loads, sets all event Listeners and beginning state of map
	{
       
		map = new GMap2(document.getElementById("div_map"));
		map.addControl(new GLargeMapControl());
		map.setCenter(new GLatLng(42.290611, -83.715012), 7);
		
		//lat/lng that the address calculates from
		document.getElementById('latholder').value=42.290611;
		document.getElementById('lngholder').value=-83.715012;
		
		//lat/lng that hold the previous center when a marker moves the map 
		document.getElementById('lastlat').value=42.290611;
		document.getElementById('lastlng').value=-83.715012;
		
		
		//opening message, opens at center of map
		//map.openInfoWindowHtml(map.getCenter(), "You are now centered on the University of Michigan campus,<br > to search for POS organizations in your area, please enter <br in your zip code or country code above.");
		

		//where to set the directions when setDirections is called 
		gdir = new GDirections(map, document.getElementById("info"));
		

        // Listeners - call function on action
        
		//When done moving map (moveend), check the map bounds with no minimum required
		GEvent.addListener(map, "moveend", function()
		{
			checkmap(0);	
		});
		
          

		// Handles the click on opening/closing marker
		GEvent.addListener(map, "click", function(overlay, point)
		{
			if (overlay)	
			{
				if (overlay.openInfoWindow != 'undefined')  //if overlay not open, save current position and then load one 
				{
					var currentcenter = map.getCenter();
					var curlat = currentcenter.lat();
					var curlng = currentcenter.lng();
					document.getElementById('lastlat').value=curlat;
					document.getElementById('lastlng').value=curlng;
					currentMarker=overlay;
					loadStoreInfo(overlay.name);	// open InfoWindow
				}
			}
			else	
			{
			  	document.getElementById("allscholarsarea").innerHTML='';
			  	map.removeOverlay(overlay); 
			}
		});
		

		//If the user explicitly moves the map, update the center to fall back to 
		GEvent.addListener(map, "dragend", function()
		{
			var currentcenter = map.getCenter();
			var curlat = currentcenter.lat();
			var curlng = currentcenter.lng();
			document.getElementById('lastlat').value=curlat;
			document.getElementById('lastlng').value=curlng;
		});
		
		//When a marker closes, go back to where the user was before the marker was opened
		GEvent.addListener(map, "infowindowbeforeclose", function()
		{
			var lastlat=document.getElementById('lastlat').value;
			var lastlng=document.getElementById('lastlng').value;
			map.panTo(new GLatLng(lastlat,lastlng));
		});
		
		//On a change of zoom, update the saved lat/lng
		GEvent.addListener(map, "zoomend", function()
		{
			var currentcenter = map.getCenter();
			var curlat = currentcenter.lat();
			var curlng = currentcenter.lng();
			document.getElementById('lastlat').value=curlat;
			document.getElementById('lastlng').value=curlng;
		});
		
		checkmap(0);
			
		
	}
	//]]>





	
	function showAddress()
	//Purpose: makes a call to Google to try and geocode the users address
	{
		
		//add spaces and create one single variable to pass
	
		var search = document.getElementById("zip").value;

		
		//save the address for later access
		document.getElementById("search").value = search;


		// Does Geocoding of users input
		geo.getLocations(search, function (result)
		{
		// If that was successful
			if (result.Status.code == G_GEO_SUCCESS)
			{
				// center the map on the result
				var record = result.Placemark[0];
				var p = result.Placemark[0].Point.coordinates;
				map.setCenter(new GLatLng(p[1],p[0]),11);
				document.getElementById('latholder').value=p[1];
				document.getElementById('lngholder').value=p[0];
				map.clearOverlays();
					
				checkmap(1);	//new address, zoom out until finds >= 1 store
			}
			// If the geocoding fails, state reason from the array at the beginning of the file
			else
			{
				var reason="Code "+result.Status.code;
				if (reasons[result.Status.code])
				{
					reason = reasons[result.Status.code]
				}
				alert('Could not find "'+search+ '" ' + reason);
			}
		}  );
	}
	
	
	
		 

	function popMarkers(left, right, top, bottom, numberneeded)
	//Purpose: to send a request to getmarkers.php with the required variables, then load the markers and links
	//on the sidebar to the map, zooms out until finds >= numberneeded
	{
		//loading image to display on the map
		//document.getElementById("loading").innerHTML = "<img height ='100px' src='carharttloading.JPG'/>" ;
	
				  
	
		var urlstr = 'universitymapping.xml';	
		
		var request = GXmlHttp.create();
		// request XML from PHP with AJAX call
		request.open('GET', urlstr , true);
		request.onreadystatechange = function ()
		{
			if (request.readyState == 4)
			{
				var xmlDoc = request.responseXML;
				cleanWhitespace(xmlDoc);
				// locations = number of stores in xml doc
				var possloc = 	xmlDoc.documentElement.getElementsByTagName("university");
				
				var numlocations=0;
				locations = [];
				markers = [];
				gmarkers = [];

				
				//finds all stores in map area
				for (var k=0; k< possloc.length; k++)
				{				
						var lng = possloc[k].getElementsByTagName("lng");
						if (lng && lng[0])
						{
						if (	(possloc[k].getElementsByTagName("lat")[0].childNodes[0].nodeValue >bottom) &&
								(possloc[k].getElementsByTagName("lat")[0].childNodes[0].nodeValue <top)  &&
								(lng[0].childNodes[0].nodeValue >left) &&
								(lng[0].childNodes[0].nodeValue <right))
							{						
								locations[numlocations]=possloc[k];
								numlocations++;
							}
						}
				}

				
			

				//if correct number of stores (between 1 & 40), then make sidebar and add markers to map
				if ((locations.length>=numberneeded))
				{
					var tosort= new Array();
					for (var i = 0; i < locations.length; i++)
					{	
						markers[i] = new GMarker(new GLatLng(locations[i].getElementsByTagName("lat")[0].childNodes[0].nodeValue,locations[i].getElementsByTagName("lng")[0].childNodes[0].nodeValue));

					    // store, the name of the store, markpoint, where to add the markers, street is the street address
					    var store = locations[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
					    var markpoint = new GLatLng(locations[i].getElementsByTagName("lat")[0].childNodes[0].nodeValue,locations[i].getElementsByTagName("lng")[0].childNodes[0].nodeValue);
						var latfrom = document.getElementById('latholder').value;
						var lngfrom = document.getElementById('lngholder').value;
						var pointfrom = new GLatLng(latfrom,lngfrom);
						
						//markers[i].id =locations[i].getElementsByTagName("id")[0].childNodes[0].nodeValue;
						markers[i].name = store;

						//add the marker info to be opened when clicking on the sidebar
						//htmlside[i]= markers[i].infowindow;

						//add marker (Google maps command)
						gmarkers[i]=markers[i];
						map.addOverlay(markers[i]);
						
						//add all the information to an array so it can be sorted if necesary
						tosort[i] = {Name:store, Id:i, Dist:(pointfrom.distanceFrom(markpoint)*.000621371192)}; //distance calculated in lat/lng, must be converted to miles
					}
					
					tosort.sort(sortByDist);
					
					
					//make the sidebar, add a store that opens each marker, as well as the distance from the address given
					//sidebar+='<table width="185px">';
					//if (locations.length>=1)
					//	sidebar+='<tr><td><strong>Name</strong></td><td><strong>Distance</strong></td></tr>';
					//for (var j=0; j<locations.length; j++)
					//{
					//		sidebar+= '<tr><td><a href="javascript:myClick('+tosort[j].Id+') ">'+tosort[j].Name+'</a></td><td>'+tosort[j].Dist.toPrecision(4)+'</td></tr>';
						
					//}
					//sidebar+='</table>';
					//put sidebar up
					//document.getElementById("links").innerHTML = sidebar;
					//document.getElementById("loading").innerHTML = "" ; //clear the loading image in the map
					//sidebar='';	
					
				}
				// not enough stores, zoom out,  then try again 
				else if (locations.length < numberneeded)
				{
					map.zoomOut();
					checkmap(1);
				}
				// too many results, call again with tighter bounds
				else
				{
					alert("Too Many Results to Load - Zooming In");
					map.zoomIn();
					sidebar='';
				}
			}
		}
		request.send(null);
	}
	
	

	function myClick(i) 
	//Purpose: to define the current marker, and start the loading of the store information associated with the correct
	//store ID
	{
		currentMarker=gmarkers[i];
		loadStoreInfo(gmarkers[i].name);
     }


	
	function htmlAjaxCall(urlstr, action)
	//Purpose: runs through an AJAX call to the database with the URL urlstr
	// handles each case based on browser, then calls the correct action based on the function base passed
	{
		req = false;
		if(window.XMLHttpRequest) 
		{
			try 
			{
				req = new XMLHttpRequest();
			} catch(e) 
			{
				req = false;
			}
		// branch for IE/Windows ActiveX version
		} 
		else if(window.ActiveXObject) 
		{
			try 
			{
				req = new ActiveXObject("Msxml2.XMLHTTP");
			} 
			catch(e) 
			{
				try 
				{
                        req = new ActiveXObject("Microsoft.XMLHTTP");
				} 
				catch(e) 
				{
                        req = false;
				}
                }
		}
		else	//something funky (or browser without AJAX support)
		{
		}
		if(req) // found requirements to send request
		{
			req.onreadystatechange = action;
			req.open("GET", urlstr, true);
			req.send("");
		}
	}
	
	


	function loadStoreInfo(name) 
	//Purpose: gets the address, then calls a script to populate the window 'Start Directions' with the address
	//given and load the store window using an AJAX call 
	{
		currentscholars = [];
		var numcurscholars =0;
		var urlstr = 'commscholars.xml';		
		var request = GXmlHttp.create();
		var areatext='';
		// request XML from PHP with AJAX call
		request.open('GET', urlstr , true);
		var markertext='';
		request.onreadystatechange = function ()
		{
			if (request.readyState == 4)
			{
				var xmlDoc = request.responseXML;
				// locations = number of stores in xml doc
				scholars = 	xmlDoc.documentElement.getElementsByTagName("scholar");
				
				for (var k=0; k<scholars.length; k++)
				{
					if (scholars[k].getElementsByTagName("university")[0].childNodes[0].nodeValue==name)
					{
						currentscholars[numcurscholars] = scholars[k];
						numcurscholars++;
					}
				}
				markertext+='<b>'+name+'</b><br />';
				if (currentscholars.length<7)
				{
					for (var j=0; j<currentscholars.length; j++)
					{
						markertext+='<a href="Contributors/'+currentscholars[j].getElementsByTagName("linkpath")[0].childNodes[0].nodeValue+'">'+currentscholars[j].getElementsByTagName("first")[0].childNodes[0].nodeValue+' '+currentscholars[j].getElementsByTagName("last")[0].childNodes[0].nodeValue+'</a><br />';
					}
					areatext='';
						document.getElementById("allscholarsarea").innerHTML = areatext;

				}
				else
				{
					for (var j=0; j<currentscholars.length; j++)
					{
						areatext+='<a href="Contributors/'+currentscholars[j].getElementsByTagName("linkpath")[0].childNodes[0].nodeValue+'">'+currentscholars[j].getElementsByTagName("first")[0].childNodes[0].nodeValue+' '+currentscholars[j].getElementsByTagName("last")[0].childNodes[0].nodeValue+'</a><br />';
					}

					markertext+='Scroll down to see all '+currentscholars.length+' scholars affiliated with this university.';
					document.getElementById("allscholarsarea").innerHTML = areatext;
				}
				if (request.status == 200) 
				{
					openMarker(markertext,currentMarker);
				} 

			}
		}
		request.send(null);
	}
	
	function processReqChange(marker) 
	//Purpose: the action of the marker based on its AJAX call above
	{
    // only if req shows "loaded"
		if (req.readyState == 4) 
		{
		// only if "OK"
			if (req.status == 200) 
			{
				openMarker(req.responseText,currentMarker);
			} 
			else 
			{
				alert("There was a problem retrieving the data:\n" +req.statusText);
			}
		}
	}	

	function openMarker(obj, currentMarker)
	//Purpose: communicates to the map to finally open the marker, if the AJAX sequence completes successfully
	{
		if ((obj!='')&&(currentMarker!='undefined'))
		{
			currentMarker.openInfoWindowHtml(obj);
		}
		else
		{
		}
	}
	
	