//Google Maps API v3
//http://code.google.com/apis/maps/documentation/v3/reference.html
//Calculate distance with Lat/Lng
//http://www.movable-type.co.uk/scripts/latlong.html
//Basic markers info
//http://www.svennerberg.com/2009/07/google-maps-api-3-markers/
//Minifyer Online
//http://www.minifyjavascript.com/

var POSTCODE = "postcode";
var ADDRESS = "address";

var pools = new Array();
var poolMarkers;
var populateMap = false;

var letters = new Array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
var errTxt = '<div class="error"><p class="reason">[REASON]</p><p class="description">[DESCRIPTION]</p></div>';

var poolSet_11 = new Array();
var poolSet_10 = new Array();
var poolSet_9 = new Array();
var poolSet_8 = new Array();
var poolSet_7 = new Array();

var directionsRenderer;
var localSearch = new GlocalSearch();
var geocoder = new google.maps.Geocoder();
var infowindow = null;
var map = null;
var myOptions = null;
var latlng = null;
var lastMarker = null;
var lastBounds = [0,0,0,0];
var lastLoc = null;

var mapFormatted = false;
var isDirecting = false;
var isComputing = false;
var beingDragged = false;
var isIdle = true;
var standardStart = true;
var firstLoad = true;
var phpStarted = false;
var mapInitialised = false;
var infoOpen = false;
var eventRunning = false;

var minZoom = 6;
var maxZoom = 16;
var lastZoom = null;
var idealPools = 2;

var zoomLvl = 5;
var lat = 54.326789;
var lng = -2.747578;
var fakeLat = 55.169416;
var fakeLng = -1.691428;
var startLoc = 'Kendal,UK';
var fakeStartLoc = 'Morpeth,UK';

var cToNorth = 0.08008506330146;
var cToWest = 0.1150131225585938;

var oldURL = 'home';


function popUpCheck(hash) {

	if (hash.match(/.php/) || hash.match(/.htm/)) {
		if (hash.match(/faq.php/) || hash.match(/how-it-works.php/) || hash.match(/terms-and-conditions.php/) || hash.match(/privacy-policy.php/) || hash.match(/poolInfo.php/) || hash.match(/hydration.php/) || hash.match(/heritage.php/) || hash.match(/social.php/)) {
		//alert(hash);
		var gotoV = hash.replace(/\?/,",");
		//var goto = window.location.hash.replace(/u=/,"");
			gotoV = gotoV.replace(/\?[.\?]*/,"");
			gotoV = gotoV.replace(/#/,"");
			popUp(gotoV);
		}
	}
}

function pageload(hash) {
		// alert("pageload: " + hash);
		// hash doesn't contain the first # character.
		if(hash) {
			// restore ajax loaded state
			if($.browser.msie) {
				// jquery's $.load() function does't work when hash include special characters like aao.
				hash = encodeURIComponent(hash);
			}
			
			if (hash.match(/home/) || hash.match(/location=/)) {
				$('#dialog').dialog('close');
				/*if (hash.match(/location=/)) {
					var loc = hash.replace(/location=/,'');
					
					
					var testLoc = URLDecode(lastLoc);
					testLoc = testLoc.replace(/\+/g," ");
					//alert(URLDecode(hash)+' --- '+testLoc);
					if (URLDecode(hash) != testLoc && lastLoc != null) {
						setStart(0,loc);
						startLoc = URLDecode(loc);
					}
				}*/
				//oldURL = window.location.hash.replace(/#/,"");
			} else {
				
				popUpCheck(hash);
			}
		} 
}

$(function(){
	
	initialize();
	
	$("#location").click(function () { 
		if ($(this).attr("value") == "Enter your postcode") {
    		$(this).val(''); 
		}
    });
	$("#location").blur(function () { 
		if ($(this).attr("value") == "") {
    		$(this).val('Enter your postcode'); 
		}
    });
	
	$("#location").focus(function () { 
		if ($(this).attr("value") == "Enter your postcode") {
    		$(this).val(''); 
		}
    });
	
	var settings = {
      tl: { radius: 20 },
      tr: { radius: 20 },
      bl: { radius: 20 },
      br: { radius: 20 },
      antiAlias: true
    }
	
    var divObj = jQuery(".ui-corner-all");
    curvyCorners(settings, ".ui-corner-all");
	
	setUpDialog();
	setUpClose();
	$.historyInit(pageload);
	var firstHash = window.location.hash.replace(/#/,"");
	//alert(firstHash);
	if (firstHash.length == '') {
	
		$.historyLoad(oldURL);	
	} else {
		
	$.historyLoad(firstHash);	
	}
	
	
	
	
});

function setUpClose() {
	$('a.ui-dialog-titlebar-close').click(function(event){
		$.historyLoad(oldURL);		
		$("#dialog").empty();
		setUpDialog();
	});	
}

function setUpDialog() {

	// Dialog			
	$('#dialog').dialog({
		autoOpen: false,
		width: 755,
		modal: true,
		height: 480
	});
	
	/*$('.dialog_link').each(function () {
		var theUrl = $(this).attr("href");
		
		$(this).attr("href",theUrl);
	});*/
	$('.dialog_link').unbind("click");

	// Dialog Link
	$('.dialog_link').click(function(event){
		event.preventDefault();
		
		// Get the data
		var urlSrc = $(this).attr("href");
		if (isIE && $(this).attr("xref") !== undefined) {
			urlSrc = $(this).attr("xref");
		}
		var hash = urlSrc;
		var urlText = "text";
		if (hash.match(/\?/)) {
			
			hash = hash.replace(/\?/,",");
		}
		hash.replace(/^.*#/, '');
			// moves to a new page. 
			// pageload is called at once. 
			// hash don't contain "#", "?"
			
			
		if (oldURL != window.location.hash.replace(/#/,"")) {	
			oldURL = window.location.hash.replace(/#/,"");	
		}
		
		//WHY IS ALL THIS RUNNING TWICE??
		
		//alert(oldURL);
		$.historyLoad(hash);
		popUpCheck(urlSrc);
		return false;
	});
	
	//hover states on the static widgets
	$('.dialog_link, ul#icons li').hover(
		function() { $(this).addClass('ui-state-hover'); }, 
		function() { $(this).removeClass('ui-state-hover'); }
	);	
}

function popUp(urlSrc) {
	
	
		// Get the data
		if (urlSrc.match(/,/)) {
			
			urlSrc = urlSrc.replace(/,/,"?");
		}
		if (!urlSrc.match(/ajax=true/)) {
			if (!urlSrc.match(/\?/)) {
				urlSrc = urlSrc + "?ajax=true";
			} else {
				urlSrc = urlSrc + "&ajax=true";	
			}
		}
		
		if (!urlSrc.match(/index.php/) && !urlSrc.match(/\//) && !urlSrc.match(/http:\/\//)) {
			var html = $.ajax({
				url: urlSrc,
				async: false
			}).responseText;
	
			$('#dialog').empty();
			$('#dialog').append(html);
			
			// open the dialog
			$('#dialog').dialog('open');
			
		
			
			if (urlSrc.match(/how-it-works/)) {
				
				
				swfobject.addDomLoadEvent(fn);
			}
		}
		//window.location.hash = 'u='+urlSrc;
	
}	

/***** GOOGLE MAP MANIPULATION *****/

function makeLatLng(a,b) {

	latlng = new google.maps.LatLng(a,b);
	
	return true;
}

//Ensure searches are within the UK
function doUKify(loc) {
	//Add UK to end of string if it is omitted
	if (!loc.match(/[,]?[ ]?[Uu][Kk]/)) {
		startLoc = loc+", UK";
	}
}

//See if search term is a postcode or not
function checkAddr(loc) {
	//Check whether address is a postcode or physical address
	 postcode = /[A-Za-z]{1,2}\d[A-Za-z\d]?[\s]?\d[ABD-HJLNP-UW-Zabd-hjlnp-uw-z]{2}/;
	 if (loc.match(postcode)) {
		return POSTCODE;
	 } else {
		return ADDRESS; 
	 }
}

//Center map on Postcode searched for
function showPostcode(postcode,zoom) {
	$('#errorHolder').hide();
  	localSearch.setSearchCompleteCallback(null,
    function() {
      	if (localSearch.results[0]) {    
			var resultLat = localSearch.results[0].lat;
			var resultLng = localSearch.results[0].lng;
			makeLatLng(resultLat,resultLng);
			if (!mapInitialised) {
				setMapOptions(latlng);
			}
			if (mapInitialised) {
				setCenter(latlng,zoom);
			} 
			phpStarted = true;
      	} else {
			var errDesc = "We've tried out best, but we can't find you anywhere on Earth. Sorry.<br /><br />You can still try a different search, make sure you input a properly formatted postcode or address (e.g. 'W6 9HQ' or 'Queen Caroline Street, London')";
			var errTitle = "We can't find you!";
			var thisErrTxt = errTxt.replace("[REASON]",errTitle);
			thisErrTxt = thisErrTxt.replace("[DESCRIPTION]",errDesc);
			$('#errorHolder').append(thisErrTxt);
			$('#errorHolder').fadeIn(400);
			phpStarted = false;
      	}
		if (firstLoad) {
			firstLoad = false;	
		}
    });  
    
  	localSearch.execute(postcode);
  
}

//Center map on address searched for
function showAddress(address,zoom) {
   	if (geocoder) {
		$('#errorHolder').hide();
      geocoder.geocode( { 'address': address}, function(results, status) {
		//status = google.maps.GeocoderStatus.ERROR;
        if (status == google.maps.GeocoderStatus.OK) {
			makeLatLng(results[0].geometry.location.lat(),results[0].geometry.location.lng())
			if (!mapInitialised) {
				setMapOptions(latlng);
			}
			if (mapInitialised) {
				setCenter(latlng,zoom);
			} 
			phpStarted = true;
        } else {
        	var errDesc = "Your search seems to have gone astray. Thanks for noticing, our maintenance crew have been alerted!";
			var errTitle = "There's been a problem";
			//There was a problem contacting the Google servers.
			if (status == google.maps.GeocoderStatus.ERROR) {
				errDesc = "We're having a problem getting hold of your map, please try and <a href=\"javascript:setStart("+zoomLvl+",'"+address+"')\">search again</a>.";
			}
			//The GeocoderRequest provided was invalid.
			if (status == google.maps.GeocoderStatus.INVALID_REQUEST) {
				$.post("maintEmail.php", { errorID: "j002", errorMessage: "The GeocoderRequest provided was invalid. google.maps.GeocoderStatus.INVALID_REQUEST" } );
			}
			//The webpage has gone over the requests limit in too short a period of time.
			if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
				$.post("maintEmail.php", { errorID: "j003", errorMessage: "The webpage has gone over the requests limit in too short a period of time. google.maps.GeocoderStatus.OVER_QUERY_LIMIT" } );
			}
			//The webpage is not allowed to use the geocoder.
			if (status == google.maps.GeocoderStatus.REQUEST_DENIED) {
				$.post("maintEmail.php", { errorID: "j004", errorMessage: "The webpage is not allowed to use the geocoder. google.maps.GeocoderStatus.REQUEST_DENIED" } );
			}	
			//A geocoding request could not be processed due to a server error. The request may succeed if you try again.
			if (status == google.maps.GeocoderStatus.UNKNOWN_ERROR) {
				errDesc = "We're having a problem getting hold of your map, please try and <a href=\"javascript:setStart("+zoomLvl+",'"+address+"')\">search again</a>.";
			}	
			//No route could be found between the origin and destination.
			if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
				errTitle = "We can't find you!";
				errDesc = "We've tried out best, but we can't find you anywhere on Earth. Sorry.<br /><br />You can still try a different search, make sure you input a properly formatted postcode or address (e.g. 'W6 9HQ' or 'Queen Caroline Street, London')";
			}
			//alert('Error: ' + status);
			var thisErrTxt = errTxt.replace("[REASON]",errTitle);
			thisErrTxt = thisErrTxt.replace("[DESCRIPTION]",errDesc);
			
			$('#errorHolder').append(thisErrTxt);
			$('#errorHolder').fadeIn(400);
		  	phpStarted = false;
       }
	   if (firstLoad) {
			firstLoad = false;	
		}
     });
  }
  phpStarted = false;
}
  
//If appropriate find map bounds
function reevaluateBounds() {
 	var theBounds = new Array();
	//if (zoomLvl < 6) {
	if (!beingDragged && !infoOpen && isIdle && !isDirecting && !areBoundsSame(lastBounds,theBounds = getBounds(map.getBounds()))) {
	
			if (zoomLvl >= minZoom) {
				lastZoom = null;
				var markerArray = getPoolsInBounds(pools,theBounds);
				//alert("bounds changed");
				//alert(markerArray.length);
				addPoolMarkers(markerArray);	
				
			} else {
				resetPoolMarkers();	
			}

	//} 
	}
	setTimeout('accessifyMarkers();',3000);
	
}

function areBoundsSame(a,b) {
	var i;
	var theSame = true;
	for (i in a) {
		if (a[i] != b[i]) {	
			theSame = false;
		}
	}
	return theSame;
}

//get current map boundaries
function getBounds(b) {
	var top = b.getNorthEast().lat();
	var right = b.getNorthEast().lng();
	var bottom = b.getSouthWest().lat();
	var left = b.getSouthWest().lng();
	var westToEastMargin = Math.abs((right - left)/5);
	var northToSouthMargin = Math.abs((top - bottom)/5);
	top = top-northToSouthMargin;
	bottom = bottom+northToSouthMargin;
	left = left+westToEastMargin;
	right = right-westToEastMargin;
	//alert(top+" : "+right+" : "+bottom+" : "+left);
	lastBounds = [top,left,bottom,right];
	return lastBounds;
}

function getPoolsInBounds(poolArr,arr) {
	var lastLat = -1;
	var firstLat = poolArr.length;
	
	var i;
	var p = new Array();
	//alert(poolArr.length);
	for (i in poolArr) {
		p[i] = poolArr[i];
		if (p[i].LATITUDE >= arr[2] && firstLat == poolArr.length) {
			//alert(pools[i].LATITUDE);
			firstLat = i;	
		}
		if (p[i].LATITUDE > arr[0] && lastLat == -1) {
			//alert(pools[i].LATITUDE);
			lastLat = i;
		}
	}
	
	//alert(firstLat+"   "+lastLat);
	if (lastLat != -1) {
		p.splice(lastLat,(p.length)-lastLat);
	}
	
	p.splice(0,firstLat);
	p.sort(function(a,b){return a.LONGITUDE - b.LONGITUDE});
	
	var lastLng = -1;
	var firstLng = p.length;
	for (i in p) {
		if (p[i].LONGITUDE >= arr[1] && firstLng == p.length) {
			//alert(p[i].LONGITUDE);
			firstLng = i;	
		}		
		if (p[i].LONGITUDE > arr[3] && lastLng == -1) {
			//alert(p[i].LONGITUDE);
			lastLng = i;
		}
	}
	//alert(firstLng+"   "+lastLng);
	if (lastLng != -1) {
		p.splice(lastLng,(p.length)-lastLng);
	}
	p.splice(0,firstLng);
	p.sort(function(a,b){
			a = findDistance(a.LATITUDE,a.LONGITUDE);
			b = findDistance(b.LATITUDE,b.LONGITUDE);
			return a - b;
	});
	//Only do zoom functions if user has searched, not general browsing.
	if (isComputing) {
		var finalArr = new Array();
		if ((lastZoom == null || lastZoom > zoomLvl) && p.length < idealPools && zoomLvl > minZoom) {
			lastZoom = zoomLvl;
			zoomLvl--;
			map.setZoom(zoomLvl);
			arr = getBounds(map.getBounds());
			finalArr = getPoolsInBounds(poolArr,arr);
						
		} else {
			//alert(lastZoom+" : "+zoomLvl);
			if ((lastZoom == null || lastZoom < zoomLvl) && zoomLvl < maxZoom && p.length >= idealPools) {
				lastZoom = zoomLvl;
				zoomLvl++;
				map.setZoom(zoomLvl);
				arr = getBounds(map.getBounds());
				finalArr = getPoolsInBounds(poolArr,arr);
				if (finalArr.length < idealPools) {
					zoomLvl--;
					map.setZoom(zoomLvl);
					finalArr = p;	
				}
			} else {
				
				finalArr = p;	
			
			}
		}
		isComputing = false;
		return finalArr;
	} else {
		return p;	
	}
	
	
	
}

//Find distance between defined current center location (not necessarily where center is after dragging) and pool location (in Km)
function findDistance(pLat,pLng) {
	var cLat = latlng.lat();
	var cLng = latlng.lng();
	
	var R = 6371; // km
    var dLat = toRad((pLat-cLat));
    var dLng = toRad((pLng-cLng));
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(toRad(pLat)) * Math.cos(toRad(cLat)) *
            Math.sin(dLng/2) * Math.sin(dLng/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
	return d;
	//document.getElementById("directionsPanel").innerHTML += d+"<br />";
}

function resetPoolMarkers() {
	$('#descriptions div.poolShortDesc').remove();
	for (i in poolMarkers) {
		poolMarkers[i].setMap(null);	
	}	
}

function addPoolMarkers(arr) {
	if (mapInitialised) {
		var i = 0;
		var x = 0;
		var markerShadow = "markers/shadow.png";
		var alternate = true;
		resetPoolMarkers();
		
		if (arr.length > 26) {
			arr.splice(26,arr.length-26);	
		}
		arr = arr.reverse();	
		x = arr.length;
		poolMarkers = new Array();
		$('#descriptions').hide();
		for (i in arr) {
			var markerIcon = "markers/blue_Marker"+(x)+".png";
			var point = new google.maps.LatLng(arr[i].LATITUDE,arr[i].LONGITUDE);
			var zDex = parseInt(i)+1;
			poolMarkers[i] = new google.maps.Marker({
				position: point, 
				map: map,
				icon: markerIcon,
				shadow: markerShadow,
				zIndex: zDex,
				title: arr[i].NAME
			}); 
			
			
			google.maps.event.addListener(poolMarkers[i], 'click', function() {
				infoOpen = true;
				var index = this.getZIndex()-1;
				infowindow.setContent(arr[index].contentString);
				infowindow.open(map);
				infowindow.setPosition(this.getPosition());
			});
						
			var poolSideDesc =  '<div class="poolShortDesc';
			if (alternate) {
					poolSideDesc +=		' alternate';
			}
			alternate = !alternate;
			var xhref='';
			if (isIE) {
				xhref= ' xref="poolInfo.php?id='+arr[i].ID+'"';
				var imageVal = '<img src="images/home/spacer.png" alt="'+letters[x-1]+'" class="markerImage" border="0" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+markerIcon+'\', sizingMethod=\'scale\'); width="20px; height: 34px" />';	
			} else {
				var imageVal = '<img src="'+markerIcon+'" alt="'+letters[x-1]+'" class="markerImage" border="0" />';	
			}
			var lengthEnd = ' metres';
			if (arr[i].LENGTH.toLowerCase() == 'free form') {
				lengthEnd = '';
			}
			poolSideDesc +=		'">'+
								'<a class="mapElement" href="javascript:google.maps.event.trigger(poolMarkers['+i+'], \'click\');">'+imageVal+'</a>'+
								'<p class="pName">'+arr[i].NAME+', ('+Math.round(findDistance(arr[i].LATITUDE,arr[i].LONGITUDE)*10)/10+' miles)</p>'+
								'<p class="additional"><span>'+arr[i].OPERATOR+'</span> ('+arr[i].CLASSIFICATION+')</p>'+
								'<p class="additional"><span>'+arr[i].TYPE+'</span> ('+arr[i].LENGTH+''+lengthEnd+')</p>'+
								'<p><a href="poolInfo.php?id='+arr[i].ID+'"'+xhref+' class="dialog_link">Opening times and more info</a>.</p>'+
								'</div>';
			$('#descriptions').prepend(poolSideDesc);
			
			x--;
			//findDistance(arr[i].LATITUDE,arr[i].LONGITUDE);
		}
		setUpDialog();
		$('#descriptions').fadeIn(600);
	
		
	
	}
}

//Tool integrating with PHP to add pool objects to javascript array
function addPool(arr) {

	arr.LONGITUDE = parseFloat(arr.LONGITUDE);
	arr.LATITUDE = parseFloat(arr.LATITUDE);
	arr.contentString = '<div id="content" style="height: 130px;"><h4 class="poolName">'+arr.NAME+',</h4>'+
						'<p class="address">'+arr.ADDR1+',<br />'+arr.ADDR2;
	var wholeAddress = arr.ADDR1+', '+arr.ADDR2;	
	if (arr.ADDR3.length != 0) {
		arr.contentString += ',<br />'+arr.ADDR3;
		wholeAddress += ', '+arr.ADDR3;
	}
	arr.contentString +=',<br />'+arr.REGION+',<br />'+arr.POSTCODE;
	wholeAddress += ', '+arr.REGION+', '+arr.POSTCODE;
	
	arr.contentString += '</p>';
	if (arr.CONTACT.length != 0) {
		arr.contentString +='<p><strong>Tel:</strong> '+arr.CONTACT+'</p>';
	}
	arr.contentString += '<p>';
	if (arr.URL.length != 0) {
		if (!arr.URL.match(/http:\/\//)) {
			arr.URL = 'http://'+arr.URL;	
		}
	arr.contentString += '<a href="'+arr.URL+'" target="_blank" title="Opens in a new tab/window">Website</a> - ';
	}
	arr.contentString += '<a href="javascript:getDirections('+arr.LATITUDE+','+arr.LONGITUDE+');">Directions to this pool</a></p>'+
						 '</div>';
	
	pools[pools.length] = arr;

}

//Center the map on a specific latitude/longitude
function setCenter(p,z) {
	if (!screenreader) {
		if (!standardStart) {
			var theHash = 'location='+URLEncode(startLoc);
			/*lastLoc = theHash;
			//alert(URLDecode(hash)+' --- '+testLoc);
			if (theHash != window.location.hash && lastLoc != null) {
				$.historyLoad(theHash);
			}*/
			
			window.location.hash = theHash;
			document.getElementById('location').value = URLDecode(startLoc);
			
		}
		
		map.setCenter(p);
		map.setZoom(z);
		zoomLvl = z;
		if (!firstLoad) {
			placeMarker(latlng);
			$('#mainPage').append('<img src="https://s1.srtk.net/www/delivery/ti.php?trackerid=620&cb=1487544381&_sr_amount=0&_sr_page='+URLEncode(startLoc)+'" width="1" height="1" border="0" class="hidden"/>');
		}
	}
}

//Place marker on the current search location (seperate from pools)
function placeMarker(point)
{
	if (lastMarker != null) { lastMarker.setMap(null); }
	var marker = new google.maps.Marker({
		position: point, 
		map: map,
		title: "Your location",
		zIndex: 1
	}); 
	lastMarker = marker;
}

//Take PHP variables and set the location of the google map from the URL. 
function setStart(z,l) {
	if (z == 0) {
		z = 14;	
		zoomLvl = 14;
	}
	if (!firstLoad) {
			removeDirections();
	}
	if (l != "Enter your postcode" && l.match(/[a-zA-Z0-9]/) && !l.match(/^[ ]?[,]?[ ]?[Uu][Kk]/)) {
		if (z == 11) {
			z = 14;
			zoomLvl = 14;
		}
		removeErrors();
		if (!firstLoad) {
			infoOpen = false;	
			infowindow.close();	
		}
		if (!l.match(startLoc) && !l.match(fakeStartLoc) ) {
			standardStart = false;
		}
		if (window.location.hash.match(/location=/) && firstLoad) {
			firstLoad = false;
			standardStart = false;
			z = 14;
			zoomLvl = 14;
			startLoc = window.location.hash.replace(/location=/,'');
			startLoc = startLoc.replace(/#/,'');
			startLoc = URLDecode(startLoc);
		} else {
			zoomLvl = z;
			startLoc = l;	
		}
		isComputing = true;
		doUKify(startLoc);
	
		if (checkAddr(startLoc) == POSTCODE) {
			showPostcode(startLoc,z);
		} else {
			showAddress(startLoc,z);
		}
	} else {
		
		zoomLvl = 5;
		startLoc = '';
		resetPoolMarkers();
		$('#errorHolder').hide();
		removeErrors();
		var thisErrTxt = errTxt.replace("[REASON]","There's been a problem...");
		thisErrTxt = thisErrTxt.replace("[DESCRIPTION]","Please enter a valid postcode or address (e.g. 'W6 9HQ' or 'Queen Caroline Street, London')");
		
		var reallatlng = new google.maps.LatLng(lat, lng);
		map.setCenter(reallatlng);
		map.setZoom(zoomLvl);
		window.location.hash = '#';
		var fakelatlng = new google.maps.LatLng(fakeLat, fakeLng);
		if (lastMarker != null) { lastMarker.setMap(null); }
		placeMarker(fakelatlng); 
		$('#errorHolder').append(thisErrTxt);
		$('#errorHolder').fadeIn(400);	
	}
}

//Define the map's basic options
function setMapOptions(ll) {
	myOptions = {
		zoom: zoomLvl,
		center: ll,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};	
}

//Set window size dependent on mobile device or screen device
function detectBrowser() {
  var useragent = navigator.userAgent;
  var mapdiv = document.getElementById("map_canvas");
    
  if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
    mapdiv.style.width = '335px';
    mapdiv.style.height = '400px';
  } else {
    mapdiv.style.width = '335px';
    mapdiv.style.height = '400px';
  }
}

function getDirections(toLat, toLng) {
	$('#descriptions').empty();
	removeErrors();
	isDirecting = true;
	directionsRenderer.setMap(map);    
	directionsRenderer.setPanel(document.getElementById('directionsPanel'));
	var toLatLng = new google.maps.LatLng(toLat, toLng);
	infoOpen = false;	
	infowindow.close();
	map.panTo(latlng);
	var directionsService = new google.maps.DirectionsService();
	var request = {
		origin: latlng, 
		destination: toLatLng,
		travelMode: google.maps.DirectionsTravelMode.DRIVING,
		unitSystem: google.maps.DirectionsUnitSystem.IMPERIAL,
		provideTripAlternatives: true
	};
	$('#errorHolder').hide();
	directionsService.route(request, function(response, status) {
		//status = google.maps.DirectionsStatus.UNKNOWN_ERROR;
		if (status == google.maps.DirectionsStatus.OK) {
			directionsRenderer.setDirections(response);
			$('#map_canvas').append('<p id="removeDirLink"><a href="javascript:removeDirections();">Close Directions</a></p>');
		} else {
			var errDesc = "Your search seems to have gone astray. Thanks for noticing, our maintenance crew have been alerted!";
			var errTitle = "There's been a problem";
			//The DirectionsRequest provided was invalid.
			if (status == google.maps.DirectionsStatus.INVALID_REQUEST) {
				$.post("maintEmail.php", { errorID: "j005", errorMessage: "The DirectionsRequest provided was invalid. google.maps.DirectionsStatus.INVALID_REQUEST" } );
			}
			//Too many DirectionsWaypoints were provided in the DirectionsRequest. The total allowed waypoints is 23, plus the origin, and destination.
			if (status == google.maps.DirectionsStatus.MAX_WAYPOINTS_EXCEEDED) {
				errTitle = "It's getting over-complicated";
				errDesc = "There are too many waypoints requested for this route, please try a different route search.";
				
			}
			//At least one of the origin, destination, or waypoints could not be geocoded.
			if (status == google.maps.DirectionsStatus.NOT_FOUND) {
				$.post("maintEmail.php", { errorID: "j008", errorMessage: "At least one of the origin, destination, or waypoints could not be geocoded. google.maps.DirectionsStatus.NOT_FOUND" } );
			}
			//The webpage has gone over the requests limit in too short a period of time.
			if (status == google.maps.DirectionsStatus.OVER_QUERY_LIMIT) {
				$.post("maintEmail.php", { errorID: "j006", errorMessage: "The webpage has gone over the requests limit in too short a period of time. google.maps.DirectionsStatus.OVER_QUERY_LIMIT" } );
			}
			//The webpage is not allowed to use the directions service.
			if (status == google.maps.DirectionsStatus.REQUEST_DENIED) {
				$.post("maintEmail.php", { errorID: "j007", errorMessage: "The webpage is not allowed to use the directions service. google.maps.DirectionsStatus.REQUEST_DENIED" } );
			}	
			//A directions request could not be processed due to a server error. The request may succeed if you try again.
			if (status == google.maps.DirectionsStatus.UNKNOWN_ERROR) {
				errDesc = "We're not quite sure what happened, please try and <a href=\"javascript:getDirections("+toLat+","+toLng+");\">find your directions again</a>.";
			}	
			//No route could be found between the origin and destination.
			if (status == google.maps.DirectionsStatus.ZERO_RESULTS) {
				errTitle = "We're a bit stuck!";
				errDesc = "We've tried out best, but we can't find a route between your search location and the pool you selected. Sorry.";
			}
			//alert('Error: ' + status);
			var thisErrTxt = errTxt.replace("[REASON]",errTitle);
			thisErrTxt = thisErrTxt.replace("[DESCRIPTION]",errDesc);
			
			$('#errorHolder').append(thisErrTxt);
			$('#errorHolder').fadeIn(400);
		}
	});	
}

function removeErrors() {
	$('#errorHolder').empty();	
}

function removeDirections() {
	$('#map_canvas p#removeDirLink').remove();
	directionsRenderer.setMap(null);
	directionsRenderer.setPanel(null);
	map.setZoom(zoomLvl);
	map.panTo(latlng);
	isDirecting = false;
	reevaluateBounds();
}

//Call google to generate google map  
function initialize() {
	if (standardStart) {
		document.getElementById('location').value = 'Enter your postcode';
	} else {
		//Ensure right location name is in the search box
		document.getElementById('location').value = URLDecode(startLoc);
	}
	
	//initialise map options
	if (!phpStarted) {
		makeLatLng(lat,lng);
		setMapOptions(latlng);
	}
	//set up map
	map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);	
	mapInitialised = true;
	
	//divert view to appear at Morpeth if needed
	if (standardStart) {
		var fakelatlng = new google.maps.LatLng(fakeLat, fakeLng);
		placeMarker(fakelatlng); 
	} else {
		placeMarker(latlng); 
	}
	
	//Ready the array for use by sorting North to South
	if (populateMap) {
		pools.sort(function(a,b){return a.LATITUDE - b.LATITUDE});
	}

	//Make info window
	var contentString = 'Loading...';

	infowindow = new google.maps.InfoWindow({
		content: contentString,
		maxWidth: 310
	});
	
	google.maps.event.addListener(infowindow, 'closeclick', function() {
		infoOpen = false;	
		map.panTo(latlng);
	});
			
	directionsRenderer = new google.maps.DirectionsRenderer();
		
	
	//Add user interaction listeners
	var dragListener = google.maps.event.addListener(map, 'dragstart', function() {
		beingDragged = true;	
		isIdle = false;
	});
	var dragListener = google.maps.event.addListener(map, 'dragend', function() {
		beingDragged = false;
		reevaluateBounds();
	});
	//setTimeout('GKeyboardPatch(map);',5000);
	//Zoom listener included by poxy 
	
	var boundsSetListener = google.maps.event.addListener(map, 'idle', function() {
		if (!eventRunning) {
			eventRunning = true;	
			setTimeout( function(){
				eventRunning = false
			},1000);
			isIdle = true;
			if (!isDirecting && !isComputing) {
			zoomLvl = map.getZoom();
			}
			reevaluateBounds();
		}
	});
	detectBrowser();
}


/*SUPPLEMENTARY FUNCTIONS*/

//http://www.mabaloo.com/Web-Development/Urlencode-and-Urldecode-with-JavaScript.html
function URLEncode(url) //Function to encode URL.
{
// The Javascript escape and unescape functions do not correspond
// with what browsers actually do...
var SAFECHARS = "0123456789" + // Numeric
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
"abcdefghijklmnopqrstuvwxyz" +
"-_.!~*'()"; // RFC2396 Mark characters
var HEX = "0123456789ABCDEF";

var plaintext = url;
var encoded = "";
for (var i = 0; i < plaintext.length; i++ ) {
var ch = plaintext.charAt(i);
if (ch == " ") {
encoded += "+"; // x-www-urlencoded, rather than %20
} else if (SAFECHARS.indexOf(ch) != -1) {
encoded += ch;
} else {
var charCode = ch.charCodeAt(0);
if (charCode > 255) {
alert( "Unicode Character '"
+ ch
+ "' cannot be encoded using standard URL encoding.\n" +
"(URL encoding only supports 8-bit characters.)\n" +
"A space (+) will be substituted." );
encoded += "+";
} else {
encoded += "%";
encoded += HEX.charAt((charCode >> 4) & 0xF);
encoded += HEX.charAt(charCode & 0xF);
}
}
}

return encoded;
};

function URLDecode(url) //function decode URL
{
// Replace + with ' '
// Replace %xx with equivalent character
// Put [ERROR] in output if %xx is invalid.
var HEXCHARS = "0123456789ABCDEFabcdef";
var encoded = url;
var plaintext = "";
var i = 0;
while (i < encoded.length) {
var ch = encoded.charAt(i);
if (ch == "+") {
plaintext += " ";
i++;
} else if (ch == "%") {
if (i < (encoded.length-2)
&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
plaintext += unescape( encoded.substr(i,3) );
i += 3;
} else {
alert( 'Bad escape combination near ...' + encoded.substr(i) );
plaintext += "%[ERROR]";
i++;
}
} else {
plaintext += ch;
i++;
}
} // while

return plaintext;
}; 

//From Degrees to Radians
function toRad(a) {  // convert degrees to radians
  return (a * Math.PI / 180);
}

/*Number.toDeg = function() {  // convert radians to degrees (signed)
  return this * 180 / Math.PI;
}

Number.toBrng = function() {  // convert radians to degrees (as bearing: 0...360)
  return (this.toDeg()+360) % 360;
}*/

function GKeyboardPatch(map) {
//<span class="hidden">for Google Maps</span>
  var button, button_style = 
  'width:100%;height:100%;padding:2px;margin:2px; \
  background:transparent ; border-width:0px;border-style:solid; \
  cursor: pointer;overflow:hidden ;text-indent:-100em; \
  position:absolute ;top:-2px;left:-2px;';
  var links = $('a');
  $.each(links,function() {
		 if ($(this).html() == "Terms of Use") {
			 $(this).html('<span class="hidden">Google Maps </span>Terms of Use');
		 }
	});
  

  var divs = $('#map_canvas').find('div');
  
  $.each(divs, function() {
    if ($(this).attr("title") != 'undefined' && $(this).attr("title") != '') {
		
		var theTitle = $(this).attr("title");
		if (theTitle == "Zoom in" || theTitle == "Zoom out" || theTitle == "Show street map" || theTitle == "Show satellite imagery" || theTitle == "Show imagery with street names" || theTitle == "Show street map with terrain" ) {

			if (theTitle == "Show street map with terrain") {
				$(this).parent().remove();	
			}
			
			if (theTitle == "Show street map" || theTitle == "Show satellite imagery" || theTitle == "Show imagery with street names") {
				var insideLink = $(this).find('div');
				$.each(insideLink, function() {
					var width = $(this).css('width');
					var height = $(this).css('height');
					var insideTxt = $(this).html();
					var fontWeight = "normal";
					var theCursor = $(this).css('cursor');
					if ($(this).css('font-weight') == "bold") {
						fontWeight = "bold";	
					}
					
					$(this).html('<button class="mapTypeSel mapElement" style="font-weight: '+fontWeight+'; cursor: '+theCursor+'; width:'+width+';">'+insideTxt+'</button>');
				});
				var typeButtons = $('button.mapTypeSel');
				$('button.mapTypeSel').click(function(event) {
					$.each(typeButtons,function() {
						$(this).css('font-weight','normal');
						$(this).css('cursor', '');
					});
					$(this).css('font-weight','bold');
					$(this).css('cursor','pointer');
				});
			}
			if (theTitle == "Zoom in" || theTitle == "Zoom out") {
				var width = $(this).css('width');
				var height = $(this).css('height');
				$(this).html('<button class="mapElement" title="'+theTitle+'" style="height: '+height+'; width:'+width+'; cursor: pointer;"></button>');
			}
		}
    }
  });
}

function accessifyMarkers() {
	if (!mapFormatted) {
		GKeyboardPatch(map);
		mapFormatted = true;
	}
	var divs = $('#map_canvas').children(":first").find('div');
	
		$.each(divs, function() {	
			
			//if ($(this).css('background-image').match(/blue_Marker/)) {
			if ($(this).attr("title") != 'undefined' && $(this).attr("title") != 'Your location' && $(this).attr("title") != '' && (!isIE && $(this).html().indexOf('button') < 0)) {
			//if($(this).html().match(/blue/)) {
				//if ($(this).attr("title") == "undefined") {
				var width = $(this).css('width');
				var height = $(this).css('height');
				//$(this).css('background-image','none');
				//$(this).css('opacity','1');
				var innerTxt= '';
				if ($(this).attr("title") == "Show satellite imagery") { innerTxt = "Satellite" };
				if ($(this).attr("title") == "Show imagery with street names") { innerTxt = "Hybrid" };
				if ($(this).attr("title") == "Show street map") { innerTxt = "Street Map" };
				$(this).html('<button class="mapElement" style="height: '+height+'; width:70px; cursor: pointer;">'+innerTxt+'</button>');
				//}
			}
	
	
	});
}
