/***************************************************************************************************************
/* Filename: headerCode.js
/* Author: Cara
/* Creation Date: June 29, 2006
/* Description: This file contains all of the JavaScript functions and global variables for indiecoffeeshops.com. 
/*				This file will load and will be cached as soon as the user arrives at the site.

/*** Global Variables ***/
var coffeeShops = new Array();  //This array contains all of the coffeeshops that have been loaded onto the site so far
var flag = false; //Used for whatever I need it for
var cityMode = false; //This is true when zoomed out enough to see only cities. False when coffeeshops are shown.
var undefined;

var map;

// Create our coffeeshop marker icon
var icon = new GIcon();
icon.image = "coffeepic.png";
icon.shadow = "mm_20_shadow.png";
icon.iconSize = new GSize(25, 33);
icon.shadowSize = new GSize(35, 32);
icon.iconAnchor = new GPoint(17, 33);
icon.infoWindowAnchor = new GPoint(17, 5);
// Create a dark icon for the coffeeshops outside of the search area
var iconDark = new GIcon();
iconDark.image = "coffeepicdark.png";
iconDark.shadow = "mm_20_shadow.png";
iconDark.iconSize = new GSize(25, 33);
iconDark.shadowSize = new GSize(35, 32);
iconDark.iconAnchor = new GPoint(17, 33);
iconDark.infoWindowAnchor = new GPoint(17, 5);

var cityPoint = new GIcon();
cityPoint.image = "citypoint.png";
cityPoint.iconSize = new GSize(20, 34);
cityPoint.iconAnchor = new GPoint(10, 33);

var iconStar = new GIcon();
iconStar.image = "star.png";
//iconDark.shadow = "mm_20_shadow.png";
iconStar.iconSize = new GSize(20, 20);
//iconDark.shadowSize = new GSize(35, 32);
iconStar.iconAnchor = new GPoint(10, 10);
//iconDark.infoWindowAnchor = new GPoint(17, 5);
/*** Functions ***/

function load() {
// This function is called when the site is loaded
	drawMap();
	if (zoom >= 9) {
		getShops();
		citymode = false;
	} else {
		//getCities();
		getCities();
		citymode = true;
	}
	if (searchaddress == true) {
		var point =  new GLatLng(lat,lng);
		var marker = new GMarker(point,{clickable:false, icon: iconStar, title:'You Are Here'});
		map.addOverlay(marker);
	}
	//printShopsToList();
	
}

function addLoadEvent(func) {
//Because of a bug in drupal, we can't set an onload property because it overwrites other onload properties. 
//This appends an onload property.
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}
 
function drawMap() {
//Draws map using the global values for lat, lng, and zoom
//Also contains the event handler for when the map is moved (getShops() is called)
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(lat, lng), zoom);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.addControl(new GScaleControl());
		map.enableDoubleClickZoom();
		GEvent.addListener(map, "moveend", function() {
		    oldzoom = zoom;
			zoom= this.getZoom();			
			if (zoom >= 9) {
				if (citymode == true) {
					clearCities();
					
				}
				getShops();
				citymode = false;
			} else {
				//getCities();
				if (oldzoom < 5) {
				    clearCities();
				    getCities();
				} else if (citymode == false) {
					clearShops();
				    getCities();
				    citymode = true;
				}
				
			}
			
			});
		
      }
}

function popUp(URL,objid) {
	day = new Date();
	id = objid;
	eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=680,height=500,left =100,top =100');");
	eval("page" + id + ".focus();");
}

function coffeeShopObject(objid, objlat, objlng, name, address, objcity, objstate, phone, website, node,filters) {
//This is a constructor for the object "coffeeShop"
	var point = new GLatLng(parseFloat(objlat),parseFloat(objlng));
	this.objid = objid;
	this.point = point;
	this.name = name;
	this.address = address;
	this.city = objcity;
	this.state = objstate;
	this.phone = phone;
	this.website = website;
	this.number = 0;
	this.distance = -.5;
	this.filters = filters;
	this.node = node;
	this.visible = false;
	
	//Check proximity to center
	if (radius == -1) {
		//radius -1 means that there is no address
		if (city != "") {
			//There is a city 
			//If this is in the state, it gets icon. If not, it gets iconDark
			if (objcity.toLowerCase() == city.toLowerCase()) {
					var marker = new GMarker(this.point, {clickable:true, icon:icon,
title:name});
					this.distance = -1;
			} else {
					this.distance = -.5;
					var marker = new GMarker(this.point,  {clickable:true, icon:iconDark,
title:name});
			}

		} else  {
				//There are no search criteria. Default to icon.
				var marker = new GMarker(this.point,  {clickable:true, icon:icon,
title:name});


		
			
		}
	} else {
		//there is an address that is being searched by. Use radius and lat and lng to determine if icon or iconDark
		var distance = returnDistanceInMiles(objlat, objlng, lat, lng);
		this.distance = distance;
		if (distance < radius) {
			var marker = new GMarker(this.point,  {clickable:true, icon:icon,
title:name});
		} else {
			var marker = new GMarker(this.point,  {clickable:true, icon:iconDark,
title:name});
		
		}
	}
	
	var infoWindow = "<b>" + name + "</b><br />" 
				+ address + "<br />" + objcity + "," + objstate + "<br />" + phone + "<br /> <a href=\"?q=node/" + node + "\">details</a>";
	if (website != "") { infoWindow+= " | <a target=\"_blank\" href=\""+ website + "\">website</a>"; }
	GEvent.addListener(marker, "click", function() {
				marker.openInfoWindowHtml(infoWindow);
			});
	this.marker = marker;
	this.infoWindow = infoWindow;
}


function getShops() {
//Uses a php file formatted like an xml file to get the coffeeshops that are found in the map and surrounding areas
//	and puts them in a multi-dimensional array called "coffeeShops"
	
	var bounds = map.getBounds();
	var southwest = bounds.getSouthWest();
	var south = southwest.lat();
	var west = southwest.lng();
	var northeast = bounds.getNorthEast();
	var north = northeast.lat();
	var east = northeast.lng();
	var nsdiff = (north - south)/2;
	var ewdiff = (east - west)/2;
	//These differences are put in here so we load shops slightly outside of the bounds of the map
	north += nsdiff;
	south -= nsdiff;
	east += ewdiff;
	west -= ewdiff;
	
	//Create the request string. This is how the bounds are passed to the SQL statement
	var xmlDataFile = 'icsShoplist.php?north=' + north +  '&east=' + east + '&south=' + south + '&west=' + west; 
	//alert(xmlDataFile);
	GDownloadUrl(xmlDataFile, function(data, responseCode) {
				var xml = GXml.parse(data);
				var shopRecords = xml.documentElement.getElementsByTagName("marker");
				var nextIndex = coffeeShops.length;
				
				for (var i = 0; i < shopRecords.length; i++) {
					var objid = "s" + shopRecords[i].getAttribute("objid");
					
					if (!coffeeShops[objid]) {
					//Using the hash, check to see if a coffeeshop is not in the array
					//If it isn't, add it to the multi-dimensional array full of coffee objects	
						coffeeShops[nextIndex] = new coffeeShopObject(objid,shopRecords[i].getAttribute("lat"), shopRecords[i].getAttribute("lng"), shopRecords[i].getAttribute("name"), shopRecords[i].getAttribute("address"), shopRecords[i].getAttribute("city"), shopRecords[i].getAttribute("state"), shopRecords[i].getAttribute("phone"), shopRecords[i].getAttribute("website"), shopRecords[i].getAttribute("node"), shopRecords[i].getAttribute("filters"));
						//Add it as a hash
						coffeeShops[objid] = coffeeShops[nextIndex];
									
						if (checkShopWithFilter(coffeeShops[nextIndex].filters)) {
							map.addOverlay(coffeeShops[nextIndex].marker);
							coffeeShops[nextIndex].visible = true;
						}
						nextIndex += 1;
					}
				}
				printShopsToList();
			});
	
}

function clearShops() {
	//alert("clearShops");	
	coffeeShops = null;
	coffeeShops = new Array();
	map.clearOverlays();
	document.getElementById("shoplist").innerHTML = "";
	if (searchaddress == true) {
		var point =  new GLatLng(lat,lng);
		var marker = new GMarker(point,{clickable:false, icon: iconStar, title:'You Are Here'});
		map.addOverlay(marker);
	}
}

function getCities() {
//Uses a php file that produces a list of cities from the database and reads them in
    var xmlDataFile = 'icsCitylist.php?zoom=' + zoom; 
	if (cityMode == false) {
		GDownloadUrl(xmlDataFile, function(data, responseCode) {
				var xml = GXml.parse(data);
				var cityStateRecords = xml.documentElement.getElementsByTagName("marker");
				for (var i = 0; i < cityStateRecords.length; i++) {
					var point =  new GLatLng(cityStateRecords[i].getAttribute("lat"), cityStateRecords[i].getAttribute("lng"));
					var name = cityStateRecords[i].getAttribute("city");
					
					var marker = new GMarker(point,{clickable:true, title:name, icon: cityPoint});
					GEvent.addListener(marker, "click", function () {
								 map.setCenter(this.getPoint(), 10);
						});
					map.addOverlay(marker);											  

				
				
				
				}
				
				
				
				
		});
	}
}

function clearCities() {
	map.clearOverlays();
	if (searchaddress == true) {
		var point =  new GLatLng(lat,lng);
		var marker = new GMarker(point,{clickable:false, icon: iconStar, title:'You Are Here'});
		map.addOverlay(marker);
	}
	//alert("Clear Cities");
}

function popupInfoWindow(objid) {
	
	coffeeShops[objid].marker.openInfoWindowHtml(coffeeShops[objid].infoWindow);
}

function sortByProximity(a, b) {
    var x = a.distance;
    var y = b.distance;
	
	if (x < y) {
		return -1;
	} else {
		return 1;
	}
    
}

function printShopsToList() {
//Prints out all of the marksers on the map
	coffeeShops.sort(sortByProximity);
	var numberInRange = 0;
	var shoplist = "<table class='shopsTable'>";
	//alert(coffeeShops.length);
	for (var i = 0; i < coffeeShops.length; i++) {
		var bounds = map.getBounds();
		var southwest = bounds.getSouthWest();
		var south = southwest.lat();
		var west = southwest.lng();
		var northeast = bounds.getNorthEast();
		var north = northeast.lat();
		var east = northeast.lng();
		//We need to check if the coffee shop in the array is in the bounds of the map and is visible(might not be with filters)
		if ((((coffeeShops[i].point.lat() < north) && (coffeeShops[i].point.lat() > south))
			&& ((coffeeShops[i].point.lng() < east) && (coffeeShops[i].point.lng() > west))) 
			&& (coffeeShops[i].visible)) 
		{
			
			shoplist += "<tr><td>";
			if (coffeeShops[i].distance >= 0) {
				shoplist += Math.round(coffeeShops[i].distance*100)/100 + "&nbsp;mi&nbsp";
			} 
			if (coffeeShops[i].distance < radius) {
				//shoplist += "<img height=\"17\" width=\"20\"  src=\"muglight.png\">";
				//numberInRange += 1;
			}
			shoplist += "</td><td width=\"300\"><a href='javascript:popupInfoWindow(\"" + coffeeShops[i].objid + "\");'>";
			
			shoplist += coffeeShops[i].name + "</a> </td></tr>";
			//<td> " + coffeeShops[i].address +
				//"</td><td>" + coffeeShops[i].phone + "</td></tr>";
		}
	}
	
	//popupInfoWindow(coffeeShops[coffeeShops.length-1].objid);
	shoplist += "</table>";
	
	document.getElementById("shoplist").innerHTML = shoplist;
}

function returnDistanceInMiles(point1y, point1x, point2y, point2x) {
// This function is borrowed from gmap-pedometer.com. It calculates the distance between two points		
		var point1 = new GLatLng(point1y, point1x);		
		var point2 = new GLatLng(point2y, point2x);
		var result = point1.distanceFrom(point2) * .000621371192;		

		return (result);
    
}

function validateSearchData(form) {
// This function checks the form data to ensure that all of the necessary fields have been filled out. If not
// the form is rejected and an error message is printed. If so, the form is submitted.
// Since this is the last chance before submission, I also have it up date the value of the hidden filters field
// so the filters are passed around.
	document.getElementById("hiddenFilters").value = filters;
	//alert(filters);
	var searchError = "";
	//Was an address entered?
		if (form.address.value != "") {
			//Was zip entered?
			if (form.zip.value != "") {
				//Process address + zip
				//searchError = address . ', ' . zip;
				return true;
			} else { 
				if (form.city.value != "") { 
					if (form.state.value != "") { 
						//Process address + city + state
						//$searchError = $address . ', ' . $city . ', ' . $state;
						return true;
					} else {
						searchError = "Please enter state or zip";
					}
				} else {
					if (form.state.value != "") { 
						searchError = "Please enter a city or zip";
					} else {
						searchError = "Please enter a city and state, or zip code";
					}
				}				
			} 
			} else {
				if (form.zip.value != "") {		
					//Process zip		
					return true;
				} else { 
					if (form.state.value != "") {
						if (form.city.value != "") {
							//Process city + state
							//searchError = city . ', ' . state;
							return true;
						} else {
							//Process state
							searchError = "Please enter a city or zip";
						}
					} else {
						if (form.city.value != "") {
							searchError = "Please enter a city or zip";
						} else {
							searchError = "Please enter a city and state, or zip";
						}
					}
				}
			}
	document.getElementById("searchError").innerHTML = searchError;
	return false;
	
}

function checkShopWithFilter(filterNum) {
// Given the filterNum of a coffeeshops, this function returns if that coffeeshop should be visible with the 
// current filter settings
	var filterResult = filters & filterNum;
	//alert(filterNum);
	if (filterResult == filters) {
		return true;
	} else {
		return false;
	}
}

function toggleFilter(filterNum, checked) {
// This function takes a filterNumber, which is the binary number associated with a filter (factors of 2). It also
// passes the true or false checked value. Using bitwise operators it changes the global variable filters to reflect the
// checkboxes and then calls the filterShops to reset the coffeeshops shown on the map and printed below it. 
		if (checked) {
			// A new filter has been added
			filters = filters ^ filterNum;
			for (var i = 0; i < coffeeShops.length; i++) {
				if ((coffeeShops[i].visible) && (checkShopWithFilter(coffeeShops[i].filters) == false)) {
				//It needs to be removed
				map.removeOverlay(coffeeShops[i].marker);
				coffeeShops[i].visible = false;

				} 
				
			}
		} else {
			// A filter has been taken away
			filters = filters & ~filterNum;
			for (var i = 0; i < coffeeShops.length; i++) {
				if ((coffeeShops[i].visible == false) && (checkShopWithFilter(coffeeShops[i].filters))) {
				//It needs to be added
				map.addOverlay(coffeeShops[i].marker);
				coffeeShops[i].visible = true;
				} 
			}
		}

		printShopsToList();
}

function showOnePoint() {

      if (GBrowserIsCompatible()) {
		//alert(document.getElementsByTagName("div")[19].id);
			
		var map = new GMap2(document.getElementById("map"));
		GEvent.addListener(map, "moveend", function() {
		  var center = map.getCenter();
		  //document.getElementById("message").innerHTML = center.toString();
		});	
        map.setCenter(new GLatLng(lat, lng), 15);
		//map.addControl(new GLargeMapControl());
		var point = new GLatLng(parseFloat(lat),
                          parseFloat(lng));
	    map.addOverlay(new GMarker(point));
      }
    }

function showOnePointTest() {
if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(lat, lng), 15);
      }


}

function processAddress_x(response) {
	//This is called by validateAdd1
			if (!response) {
				//No response - something went wrong
				alert("Sorry! We are unable to identify that address. Please provide more information (i.e. zip code, 'St.' or 'Ave.') or use a more specific city name.");
				flag = false;
			} else if (response.Status.code == G_GEO_SUCCESS) {
				// No errors ocurred; the address was successfully parsed and its geocode has been returned. (Since 2.55)
				//alert(response.Placemark.length);
				place = response.Placemark[0];
				flag = true;
				if (place.AddressDetails == undefined) {
					alert("Please provide more information");
					flag = false;
				} else if (place.AddressDetails.Country == undefined) {
					alert("Country could not be determined");
					flag = false;
				/*} else if (place.AddressDetails.AdministrativeArea.SubAdministrativeArea == undefined) {
				} else	if (place.AddressDetails.AdministrativeArea == undefined) { 
					alert("Administrative Area could not be determined:"+ place.AddressDetails.AdministrativeArea);
						
					if (place.Point.coordinates != undefined) {
						document.getElementById("hiddenLat").value = place.Point.coordinates[1];
						document.getElementById("hiddenLng").value = place.Point.coordinates[0];
						document.addingForm.submit();
					} else {
						alert("Administrative Area could not be determined:"+ place.Point.coordinates);
						flag = false;
					} */
		/*		} else if (place.AddressDetails.AdministrativeArea.SubAdministrativeArea == undefined) {
					alert("Locality could not be determined.");
					flag = false;
				} else if (place.AddressDetails.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName == undefined) {
					alert("Locality name could not be determined");
					flag = false; */
				} else {
					document.getElementById("stateAdd").value = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;			
					document.getElementById("cityAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;				
					document.getElementById("addressAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
					document.getElementById("zipAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
					document.getElementById("hiddenLat").value = place.Point.coordinates[1];
					document.getElementById("hiddenLng").value = place.Point.coordinates[0];
					document.addingForm.submit();
				}
							//alert(place.address);
				
				//window.location.href="../index.php?lat=" + lat + "&lng=" + lng +  "&filters=" + filters + "&radius=" + radius + "&zoom=" + zoom + "&address=" + "<?php echo(urlencode($address)); ?>" +  "&city=" + "<?php echo(urlencode($city)); ?>" +  "&state=" + "<?php echo($state); ?>" + "&zip=" + "<?php echo $zip; ?>";
			} else {
				//window.location.href="../?q=node/6&radius=" + radius + "&zoom=" + zoom + &address=" + "<?php echo urlencode($address) ?>" +  "&city=" + "<?php echo urlencode($city) ?>" +  "&state=" + "<?php echo $state; ?>" + "&zip=" + "<?php echo $zip; ?>" + "&error=" + response.Status.code;
				alert(response.Status.code + ": We are unable to identify that address. Please provide more information (i.e. zip code, 'St.' or 'Ave.') or use a more specific city name.");
				flag = false;

			}
		  
}

function processAddress(response) {
	//This is called by validateAdd1
	        
			if (!response) {
				//No response - something went wrong
				alert("We are unable to identify that address. Please provide more information (i.e. zip code, 'St.' or 'Ave.') or use a more specific city name.");
				flag = false;
			} else if (response.Status.code == G_GEO_SUCCESS) {
				// No errors ocurred; the address was successfully parsed and its geocode has been returned. (Since 2.55)
				//alert(response.Placemark.length);
				place = response.Placemark[0];
				flag = true;
				if (place.AddressDetails == undefined) {
					alert("Please provide more information");
					flag = false;
				} else if (place.AddressDetails.Country == undefined) {
					alert("Country could not be determined");
					flag = false;
				} else {
					if (place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName) {
						document.getElementById("stateAdd").value = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;	
					}
					if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea != undefined) {
					  if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality != undefined) {
						document.getElementById("cityAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;				
						if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName) {
							document.getElementById("addressAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
						}
						if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber != undefined) {
							document.getElementById("zipAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber;
						}
					  } else {
						if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Thoroughfare.ThoroughfareName) {
							document.getElementById("addressAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Thoroughfare.ThoroughfareName;
						}
						if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.PostalCode.PostalCodeNumber != undefined) {
							document.getElementById("zipAdd").value = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.PostalCode.PostalCodeNumber;
						}
					}
				  } else {
					//alert(place.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName);
				        document.getElementById("cityAdd").value = place.AddressDetails.Country.AdministrativeArea.Locality.LocalityName;				
						if (place.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName) {
							document.getElementById("addressAdd").value = place.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
						}
						if (place.AddressDetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber != undefined) {
							document.getElementById("zipAdd").value = place.AddressDetails.Country.AdministrativeArea.Locality.PostalCode.PostalCodeNumber;
						} 
				  }
					if (place.Point.coordinates) {
						document.getElementById("hiddenLat").value = place.Point.coordinates[1];
						document.getElementById("hiddenLng").value = place.Point.coordinates[0];
					}
					document.addingForm.submit();
				}
			} else {
				alert(response.Status.code + ": We are unable to identify that address. Please provide more information (i.e. zip code, 'St.' or 'Ave.') or use a more specific city name.");
				flag = false;

			}
		  
}


function validateAdd1(form) {
	//This function validates the contents of an "add" or "edit" address. It creates a search string and then runs "getLocations"
	//which sends the search string to the function processAddress

	var geocoder = new GClientGeocoder();
	if (form.address.value != "") {
		var searchString = form.address.value + "," + form.city.value + "," + form.state.value + "," + form.zip.value;
		geocoder.getLocations(searchString, processAddress);
		return false;
	} else {
		alert("Please provide an address.");
		return false;
	}
	//return flag;
}

function validateAdd1Debug(form) {
	//This function validates the contents of an "add" or "edit" address. It creates a search string and then runs "getLocations"
	//which sends the search string to the function processAddress

	var geocoder = new GClientGeocoder();
	if (form.address.value != "") {
		var searchString = form.address.value + "," + form.city.value + "," + form.state.value + "," + form.zip.value;
		geocoder.getLocations(searchString, processAddressDebug);
		return false;
	} else {
		alert("Please provide an address.");
		return false;
	}
	//return flag;
}

function validateAdd2(form) {
	//document.getElementById("hiddenLat").value = lat;	
	//document.getElementById("hiddenLng").value = lng;
	return true;
}

function validateAdd3(form) {
	
	return true;
}

