// create map object
var map;
// create geocoder object
var geocoder;
// current region
// check the official documentation to change region
// http://code.google.com/apis/maps/documentation/v3/services.html#CountryCodes
// requires a ccTLD (county code top-level domain)
// for a list of ccTLD's visit: http://en.wikipedia.org/wiki/CcTLD
var region = 'uk';
// array of all markers on Map
var markers = new Array();

// on dom ready
$(document).ready(function() {
	
	// [W] behaviours to check and uncheck all checkboxes
	$('#collCheckAll').live('click', function() {
		$('#collections input[type=checkbox]').each(function() {
			$(this).attr('checked', true);
		});
		return false;
	});
	$('#collUncheckAll').live('click', function() {
		$('#collections input[type=checkbox]').each(function() {
			$(this).attr('checked', false);
		});
		return false;
	});
	
	// display map by default
	// if the map_canvas id exists
	if($('#map_canvas').length) {
		// set default lat/lng
		var lat = 53.4807125;
		var lng = -2.2343765;

		// create new geocoder object
		geocoder = new google.maps.Geocoder();
		// create new lat/long object
		var latlng = new google.maps.LatLng(lat,lng);

		// set map options
		var myOptions = {
			zoom: 6,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		// display map
		map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
		// show the map div
		$('#map_canvas').show();
	}


	// if the store locator form is on the page
	if($('#store_locator').length) {
		// take over submit action
		$('#store_locator').submit(function() {
			// get address
			var address = $('#address').val();
			var distance = $('#distance').val();

			// do lookup if address not empty
			if(address != '') {
				address_lookup(address, distance, region);
			} else {
				$('#ajax_msg').html("<ul class='flash_bad'><li>Please enter a full address or a Postcode</li></ul>");
			}
			
		return false;
		});
	}

	// display map on Add page
	if($('#add #map_canvas').length) {
		// set default lat/lng
		var lat = 54.622978;
		var lng = -2.592773;

		// get pre-populated value and focus map
		var display_marker = false;
		if($('#latitude').length) {
			val = $('#latitude').val()*1;
			if(val != '' && !isNaN(val)) {
				lat = val;
				display_marker = true;
			}
		}
		if($('#longitude').length) {
			val = $('#longitude').val()*1;
			if(val != '' && !isNaN(val)) {
				lng = val;
			}
		}

		// create new geocoder object
		geocoder = new google.maps.Geocoder();

		// create new lat/long object
		var latlng = new google.maps.LatLng(lat,lng);
		// set map options
		var myOptions = {
			zoom: 8,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		// display map
		map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

		if(display_marker) {
			// create a map marker
			var marker = new google.maps.Marker({
				map: map,
				position: latlng
			});
		}
	}

	// if store add form is on the page
	if($('#add #address').length) {
		// add an onBlur event
		$('#add #address').blur(function(){
			// get the entered address
			var address = $(this).val();
			// if address is not empty
			if(address != '') {
				// do the address lookup
				get_address(address,region);
			}
		});
	}
	
	// apply PNG fix
//	$(document).pngFix();
});


/**
 * Get a single address
 * @param string address
 * @param string region
 */
function get_address(address, region) {
	// set default region
	if(region==null || region == '') {
		region = 'uk';
	}

	// address not empty
	if(address != '') {
		$('#ajax_msg').html('<p>Loading...</p>');
		// lookup the address
		geocoder.geocode( {'address':address,'region':region}, function(results, status) {
			// if the address was found
			if(status == google.maps.GeocoderStatus.OK) {
				// [W] added global variable to hold current marker instance
				if (typeof (oneMarker) == "undefined") {
					oneMarker = null;
				} else if (typeof (oneMarker) != "undefined" && oneMarker != null) {
					// [W] remove previous marker from map
					oneMarker.setMap(null);
				}
				
				$('#ajax_msg').html('<p>Done</p>');
				// insert lat/long into form
				$('#latitude').val( results[0].geometry.location.lat() );
				$('#longitude').val( results[0].geometry.location.lng() );

				// set zoom option
				map.setZoom(10);
				// center the map on the new location
				map.setCenter(results[0].geometry.location);
				
				// create a map marker
				var marker = new google.maps.Marker({
					map: map,
					// [W] enable marker dragging
					draggable: true,
					title: 'Drag and drop me to correct my location.',
					position: results[0].geometry.location
				});
				
				// [W] update lat lng coordinates after marker drop
				google.maps.event.addListener(marker, "dragend", function() {
					var location = marker.getPosition();
					$('#latitude').val(location.lat());
					$('#longitude').val(location.lng());
				});
				
				// [W] assign current marker object to a global variable
				oneMarker = marker;
			} else {
				// display error
				$('#ajax_msg').html('<p>Geocoder failed to retrieve address: '+status+'</p>');
			}
		});
	}
}


/**
 * Lookup an address
 * @param string address
 * @param int distance
 * @param string region
 */
function address_lookup(address,distance,region) {
	// set default region
	if(region==null || region == '') {
		region = 'uk';
	}
	
	// address not empty
	if(address != '') {
		// show ajax loading image
		$('#map_canvas').html("<img src='./imgs/ajax-loader.gif' alt='Ajax Loading Image' />").show();
		$('#ajax_msg').hide();
		// create new geocoder object
		geocoder = new google.maps.Geocoder();
		// lookup the address
		geocoder.geocode( {'address':address,'region':region}, function(results, status) {
			// if the address was found
			if(status == google.maps.GeocoderStatus.OK) {
				// get lat/lng
				var lat = results[0].geometry.location.lat();
				var lng = results[0].geometry.location.lng();
				var location = results[0].geometry.location;
				// [W] created myLocationLatLng to add to "get directions" link in every points's bubble
				myLocationLatLng = new Array();
				myLocationLatLng['lat'] = lat;
				myLocationLatLng['lng'] = lng;
				
				// set map options
				var myOptions = {
					zoom: 11,
					center: location,
					mapTypeId: google.maps.MapTypeId.ROADMAP
				};
				// display map
				map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

				// create a map marker
				var marker = new google.maps.Marker({
					map: map,
					position: results[0].geometry.location,
					icon: 'imgs/you_are_here.png',
					title:'Your entered address'
				});

				// clear all markers
				jQuery.each(markers,function(k,v){
					v.setMap(null);
				});
				
				// [W] get collections list and add it to ajax query
				if ($('#collections input[name=collections[]]:checked').length > 0) {
					var collections = '&coll=';
					$('#collections input[name=collections[]]:checked').each(function() {
						collections += $(this).val()+',';
					});
				} else {
					var collections = '';
				}
				
				// do ajax request to find nearby stores
				$.ajax({
					type:"POST",
					url:$('#store_locator').attr('action'),
					data:"ajax=1&action=get_nearby_stores&distance="+distance+"&lat="+lat+"&lng="+lng+collections,
					success:function(msg) {
						// parse the JSON result
						var results = $.evalJSON(msg);

						// if request successful
						if( results.success ) {
							var infowindow;
							// [W] create methods for single infoWindow behaviour
							(function () {
								google.maps.Map.prototype.markers = new Array();
								google.maps.Map.prototype.addMarker = function(marker) {
									this.markers[this.markers.length] = marker;
								};
								google.maps.Map.prototype.getMarkers = function() {
									return this.markers
								};
								google.maps.Map.prototype.clearMarkers = function() {
									if(infowindow) {
										infowindow.close();
									}
									for(var i=0; i<this.markers.length; i++){
										this.markers[i].set_map(null);
									}
								};
							})();
							// [W] custom function to create markers with only one instance of infoWindow
							function createMarker(v) {
								var marker = new google.maps.Marker({
									map: map,
									position: new google.maps.LatLng(v.lat,v.lng),
									// [W] added icons for markers
									icon: v.img[0],
									title: v.name+' : '+v.address
								});
								google.maps.event.addListener(marker, "click", function() {
									if (infowindow) infowindow.close();
									infowindow = new google.maps.InfoWindow({
										content: build_content_string(v)
									});
									infowindow.open(map, marker);
								});
								
								return marker;
							}
							
							// loop through stores and display marker
							jQuery.each( results.stores,function(k,v){
								map.addMarker(createMarker(v));
							});
							//$('#ajax_msg').html("<p class='flash_good'>"+results.stores.length+" stores have been found</p>").fadeIn();
							
							// [W] compare shop's lat, lng with my location's lat, lng and set new max and/or min for bounds
							if (results.LatLngBounds.minLat > myLocationLatLng['lat']) {
								results.LatLngBounds.minLat = myLocationLatLng['lat'];
							}
							if (results.LatLngBounds.minLng > myLocationLatLng['lng']) {
								results.LatLngBounds.minLng = myLocationLatLng['lng'];
							}
							if (results.LatLngBounds.maxLat < myLocationLatLng['lat']) {
								results.LatLngBounds.maxLat = myLocationLatLng['lat'];
							}
							if (results.LatLngBounds.maxLng < myLocationLatLng['lng']) {
								results.LatLngBounds.maxLng = myLocationLatLng['lng'];
							}
							
							// [W] map view pans to contain all shops on one view
							var southWest = new google.maps.LatLng(results.LatLngBounds.minLat, results.LatLngBounds.minLng);
							var northEast = new google.maps.LatLng(results.LatLngBounds.maxLat, results.LatLngBounds.maxLng);
							var bounds = new google.maps.LatLngBounds(southWest,northEast);
							map.fitBounds(bounds);
						} else {
							// display error message
							$('#ajax_msg').html("<p class='flash_bad'>"+results.msg+"</p>").fadeIn();
						}
					}
				});
			}
		});
	}
}


/**
 * Builds the HTML for the popup marker window
 * @param object v
 * @return string
 */
function build_content_string(v) {
	// build content string
	var content_string = "<div class='maps_popup'>";

	// include title & address
	content_string += "<h1><nobr>"+v.name+"</nobr></h1><h2><nobr>"+v.address+"</nobr></h2>";
	
	// include image
	if(typeof(v.img[1]) != 'undefined') {
		content_string += "<img class='img' src='"+v.img[1]+"' alt='Store Image' />";
	} else {
		content_string += "<img class='img' src='"+v.img[0]+"' alt='Store Image' />";
	}

	// include additional info
	if(v.telephone != '') {
		content_string += "<p class='tel'>Telephone: "+v.telephone+"</p>";
	}
	if(v.email != '') {
		content_string += "<p class='email'>Email: <a href='mailto:"+v.email+"'>"+v.email+"</a></p>";
	}
	if(v.website != '') {
		content_string += "<p class='web'>Website: <a href='"+v.website+"'>"+v.website+"</a></p>";
	}
	
	// [W] include collections list
	var collectionNames = v.collectionNames.split(',');
	content_string += "<p>Available collections:<br/>";
	$(collectionNames).each(function(i, val) {
		content_string += ""+val+", ";
	});
	content_string += "</p>";
	
	if(v.description != '') {
		content_string += "<p class='desc'>"+v.description+"</p>";
	}
	
	// [W] get directons link
	content_string += "<p><a href=\"http://maps.google.com/maps?saddr="+myLocationLatLng["lat"]+","+myLocationLatLng["lng"]+"&daddr="+v.lat+","+v.lng+"\" onclick=\"target='new'\">Get directions</a></p>";
	
	content_string += "</div>";
	
	return content_string;
}

