//------------------------------------
//	FINDMYNEAREST.JS
//	Author: 	Engage Interactive
//	Requires:	jquery 1.5 or later
//	Version:	5.0
//------------------------------------

////////////////////////////
// BEGIN JQUERY

(function($) {

	findMyNearest = function(searchTerm, options) {

		var geocoder = '', latlng = null, data = '', locations = '', db_locations = [], results = [];
		
		var defaults = {
			dataSource: '/dataSource',
			searchTotal: 5,
			searchRadius: 1000,
			logger: false,
			loggerUrl: '/loggerUrl',
			onError: function(error) {
				alert(error);	
			},
			onBlank: function() {},
			onNoResult: function() {},
			onResult: function(results) {}
		};

		var settings = $.extend({}, defaults, options);

		if(searchTerm == '') {
			settings.onBlank();
			return false;
		}
		
		if(searchTerm.toLowerCase() == 'london') {
			settings.onLondon(); 
			return false;
		}

		$.getJSON(settings.dataSource, function(locations) {
											 
			if(!locations) settings.onError('dataSource error');
			
			geocoder = new google.maps.Geocoder();
			
			geocoder.geocode({'address': searchTerm + ', UK'}, function(result, status) {
				
				if(status == google.maps.GeocoderStatus.OK) {
					
					// Merge london data
					for(var i in locations) {
										
						var lat = parseFloat(locations[i].lat);
						var lng = parseFloat(locations[i].lng)
						
						if(!isNaN(lat) && !isNaN(lng)) {
							
							var latlng = new google.maps.LatLng(lat, lng);
							
							db_locations.push({ 
								distance: latlng.distanceFrom(result[0].geometry.location), 
								name: locations[i].name, 
								slug: locations[i].slug,
								address_1: locations[i].address_1,
								address_2: locations[i].address_2,
								town_city: locations[i].town_city
							});
							
						}

					}
					
					db_locations.sort(function(a,b) { return (a.distance - b.distance); });

					var count = 1;
					
					for(var key in db_locations) {
						
						if(count > settings.searchTotal || db_locations[key].distance > parseInt(settings.searchRadius)) break;
												
						results.push({ 
							name: db_locations[key].name, 
							slug: db_locations[key].slug, 
							distance: db_locations[key].distance.toFixed(1),
							address_1: db_locations[key].address_1,
							address_2: db_locations[key].address_2,
							town_city: db_locations[key].town_city
						});
						
						count ++;
					}

					if(results.length) {

						settings.onResult(results);

						if(settings.logger) {
							$.post(settings.loggerUrl, { 
								term: searchTerm, 
								lat: result[0].geometry.location.lat(),
								lng: result[0].geometry.location.lng()
							});
						}
	
					}
					else settings.onNoResult();
				}
				else settings.onNoResult();
				
			});
		});
		
	};

})(jQuery);

////////////////////////////
// CALLBACK AFTER LOADING GOOGLE MAPS

function googleMapsApiLoaded() {
	/**
	* @param {google.maps.LatLng} newLatLng
	* @returns {number} Miles
	*/
	google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
	   // setup our variables
	   var lat1 = this.lat();
	   var radianLat1 = lat1 * ( Math.PI  / 180 );
	   var lng1 = this.lng();
	   var radianLng1 = lng1 * ( Math.PI  / 180 );
	   var lat2 = newLatLng.lat();
	   var radianLat2 = lat2 * ( Math.PI  / 180 );
	   var lng2 = newLatLng.lng();
	   var radianLng2 = lng2 * ( Math.PI  / 180 );
	   // sort out the radius, MILES or KM?
	   var earth_radius = 3959; // (km = 6378.1) OR (miles = 3959) - radius of the earth

	   // sort our the differences
	   var diffLat =  ( radianLat1 - radianLat2 );
	   var diffLng =  ( radianLng1 - radianLng2 );
	   // put on a wave (hey the earth is round after all)
	   var sinLat = Math.sin( diffLat / 2  );
	   var sinLng = Math.sin( diffLng / 2  ); 

	   // maths - borrowed from http://www.opensourceconnections.com/wp-content/uploads/2009/02/clientsidehaversinecalculation.html
	   var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0);

	   // work out the distance
	   var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));

	   // return the distance
	   return distance;
	}
	
	googleMapsEnabled = true;
}

////////////////////////////
// LOAD GOOGLE MAP ASYNC

$(function() { 
	
	googleMapsEnabled = false;
	searchBan = false;
		
	var script = document.createElement("script"); 
	script.type = "text/javascript"; 
	script.src = "http://maps.google.com/maps/api/js?sensor=false&region=GB&callback=googleMapsApiLoaded";
	document.body.appendChild(script);

});

////////////////////////////
// LOAD MAP WITH MARKER

function loadMapMarker(elementID, lat, lng, html) {
	
	gmPause = setInterval(function() {
		
		if(googleMapsEnabled) {
			
			clearInterval(gmPause);
			
			var location = new google.maps.LatLng(lat, lng);
			
			var mapOptions = {
			  zoom: 15,
			  center: location,
			  mapTypeId: google.maps.MapTypeId.ROADMAP
			};
			
			var map = new google.maps.Map(document.getElementById(elementID), mapOptions);
			
			var marker = new google.maps.Marker({
				position: location,
				map: map
			});
			
			var infoWindow = new google.maps.InfoWindow({
			    content: html
			});
			
			infoWindow.open(map, marker);

		}

	}, 100);
	
}
