$j(function () {

	// Prepare tabbed panel.
	$j('#panelFindANursery').tabbedNav({
		activePanelClass:	'panelContentCurrent',
		activeTabClass:		'current'
	});

	// Initialise Nurseries Google Maps.
	NurseriesMap.init();

	// Prepare postcode lookup form for submission.
	PostcodeLookup.init();
});


var NurseriesMap = (function () {

	// Private members.
	var map;
	var nurseries;
	var markers = {};

	return {

		// Initialise Google Maps.
		init: function () {

			// If Google Maps is incompatiable, stop executing function.
			if (!GBrowserIsCompatible()) return;

			// Instantiate new map in #ourNurseries_mapCanvas div.
			map = new GMap2(document.getElementById('ourNurseries_mapCanvas'));
			map.setUIToDefault();
			map.enableContinuousZoom();

			// Set center so that all nursery icons are visible.
			map.setCenter(new GLatLng(52.15371445951162, -0.911865234375), 7);
			map.savePosition();
		
			// Get nursery data via XMLHttpRequest.
			$j.getJSON('../xhr/get-nursery-data.asp',
				function (data) {

					// Bind JSON nursery data to private 'nurseries' member, and plot data.
					nurseries = data.nurseries;
					NurseriesMap.plotNurseryData();
				}
			);
		},

		// Plot nursery data as GMarkers.
		plotNurseryData: function () {
			var nursery, point, marker;

			// Loop through all nurseries.
			for (var i = 0; i < nurseries.length; i++) {

				// Create the relevant marker, keep a reference and plot it.
				nursery	= nurseries[i];
				point		= new GLatLng(nursery.latitude, nursery.longitude);
				marker	= new GMarker(point);
				markers[nursery.name] = marker;
				map.addOverlay(marker);

				// Create closure so that nursery information can exist after parent function has exited.
				(function (marker, nursery) {

					// When a icon is clicked, show its Info Window.
					GEvent.addListener(marker, 'click', function () {
						NurseriesMap.showInfoWindow(marker, nursery);
					});
				})(marker, nursery);
			}
		},

		// Display a marker's GInfoWindow
		showInfoWindow: function (marker, nursery) {

			// Prepare GInfoWindow HTML.
			var infoWindowHtml =
				'<div class="ourNurseries_infoWindowContent">' +
					'<dl>';
						if (nursery.maponlydisplay == true) {
							infoWindowHtml +=
							'<dt>' + nursery.name + '</dt>';
						}
						else {
							infoWindowHtml +=
							'<dt><a href="../' + nursery.url + '/">' + nursery.name + '</a></dt>';
						}
						infoWindowHtml +=
						'<dd>' +
							'<address>' +
								nursery.address1 + '<br />' +
								((nursery.address2) ? nursery.address2 + '<br />' : '') +
								((nursery.address3) ? nursery.address3 + '<br />' : '') +
								nursery.city + '<br />' +
								nursery.county + '<br />' +
								nursery.postcode + '<br />';
								if (nursery.maponlydisplay == false) {
									infoWindowHtml +=
									'<a href="../' + nursery.url + '/">visit website &raquo;</a>';
								}
								infoWindowHtml +=
								nursery.telephone +
							'</address>' +
						'</dd>' +
					'</dl>' +
				'</div>';

			// Open info window.
			marker.openInfoWindowHtml(infoWindowHtml);
		},

		// Get a GMarker by it's nursery name and zoom and pan to it, showing it's GInfoWindow.
		showNurseryMarkerAndInfoWindow: function (nursery) {

			var marker = markers[nursery.name];
			map.setZoom(16);
			map.panTo(marker.getLatLng());
			NurseriesMap.showInfoWindow(marker, nursery);
		},

		// Return to map centre and hide any currently open GInfoWindows.
		returnToMapCentre: function () {
			map.returnToSavedPosition();
			map.closeInfoWindow();
		}
	};
})();


var PostcodeLookup = (function () {

	// Private members.
	var nurseries;
	var postcode;
	var postcodeSearch;
	var postcodeSearchResults;
	var activePanel;

	return {

		// Initialise form.
		init: function () {

			// Get DOM references.
			postcodeSearch = $j('#ourNurseries_postcodeSearch');
			postcodeSearchResults = $j('#ourNurseries_postcodeSearchResults');
			noNurseryFound = $j('#ourNurseries_noNurseryFound');
			activePanel = postcodeSearch;

			// When the form is submitted...
			var form = $j('#ourNurseries_postcodeLookupForm');
			form.submit(function (e) {

				// Prevent default form submission behaviour.
				e.preventDefault();

				// Get the postcode value.
				var $postcode = $j('#inputPostcode');
				postcode = $postcode.val();

				// Validate postcode.
				if (!validate($postcode[0], 'Please enter a postcode', hasSubstance(postcode))) return false;
				if (!validate($postcode[0], 'Please enter a valid UK postcode', isPostcode(postcode))) return false;

				// Send postcode to XHR page via GET request.
				$j.getJSON('../xhr/get-nursery-by-postcode.asp?postcode=' + postcode,
					function (data) {

						// Get nursery information from JSON data and keep a reference.
						nurseries = data.nurseries;

						// If no nurseries are found, show No Nursery Found panel and exit function by returning.
						if (nurseries[0] === null) {
							PostcodeLookup.showNoNurseryFound();
							return;
						}

						// Show marker of the nearest match.
						NurseriesMap.showNurseryMarkerAndInfoWindow(nurseries[0]);

						// Populate search results.
						PostcodeLookup.populatePostcodeSearchResults();
					}
				);
			});

			// Are we already searching via a GET?
			if ($j('body').is('.ourNurseriesPostcodeSearch_')) {

				// Submit the form.
				form.submit();
			}

			// When a 'Search Again' button is clicked...
			$j('.ourNurseries_searchAgainButton').click(function (e) {

				// Prevent default click behaviour.
				e.preventDefault();

				// If the active panel is the search results...
				if (activePanel == postcodeSearchResults) {

					// Return to the centre of the map.
					NurseriesMap.returnToMapCentre();
				}

				// Show the postcode search div.
				PostcodeLookup.showPostcodeSearch();
			});
		},

		// Populate postcode search results in panel content.
		populatePostcodeSearchResults: function () {
			var distance;

			// Loop through nurseries.
			for (var i = 0; i < nurseries.length; i++) {

				// If the nursery is less than or equal to a mile away...
				if (nurseries[i].distance <= 1) {

					// Calculate walking distance at 80 metres per minute, and call it an exact match if within 40 metres.
					distance = Math.round((nurseries[i].distance * 1609.344) / 80);
					distance = (distance === 0) ? 'exact match' : distance + ' minute walk';
				}

				// Otherwise, the nursery is over a mile away so just display distance in miles.
				else {
					distance = nurseries[i].distance + ' miles';
				}

				
				
				
				// Populate content.
				if (nurseries[i].maponlydisplay == true) {
					$j('#ourNurseries_localNursery' + (i + 1)).html(
						'' + nurseries[i].name + ' <span class="ourNurseries_nurseryDistance">(' + distance + ')</span>'
					);
				}
				else {
					$j('#ourNurseries_localNursery' + (i + 1)).html(
						'<a href="../' + nurseries[i].url + '/">' + nurseries[i].name + '</a> <span class="ourNurseries_nurseryDistance">(' + distance + ')</span>'
					);
				}
			}

			// Show postcode search results.
			PostcodeLookup.showPostcodeSearchResults();
		},

		// Show postcode search results in panel content.
		showPostcodeSearchResults: function () {

			// Fade out the active panel, and fade in the results div.
			activePanel.fadeOut(function () {
				postcodeSearchResults.fadeIn();
				activePanel = postcodeSearchResults;
			});
		},

		// Show postcode search in panel content.
		showPostcodeSearch: function () {

			// Fade out the postcode search results div, and fade in the search div.
			activePanel.fadeOut(function () {
				postcodeSearch.fadeIn();
				activePanel = postcodeSearch;
			});
		},

		// Show no nursery found in panel content.
		showNoNurseryFound: function () {

			// Fade out the postcode search results div, and fade in the search div.
			activePanel.fadeOut(function () {
				$j('strong', noNurseryFound).html(postcode);
				noNurseryFound.fadeIn();
				activePanel = noNurseryFound;
			});
		}
	}
})();