var Kyan = {

	office: null,
	map: null,
	icon: null,
	marker: null,
	directionsPanel: null,
	directions: null,

	debug: function(str) {
		var console = window.console || false;
		if(console) {
			if(console.debug) {
				console.debug(str);
			} else if(console.log) {
				console.log(str);
			}
		}
	},

	init: function() {
		Kyan.office = new GLatLng(51.236411,-0.570452); // 171 High Street
		Kyan.carpark = new GLatLng(51.235153,-0.570769); // Castle Car Park, Sydenham Road
		
    // Kyan.office = new GLatLng(51.1417, -0.53307); // 65 Smithbrook Kilns
	},


	load: function() {
		// Initialise the map data
		Kyan.map = new GMap2(
			document.getElementById("map"),
			{mapTypes:[G_HYBRID_MAP, G_NORMAL_MAP]}
		);
		with(Kyan.map) {
			addControl(new GSmallZoomControl());
			// addControl(new GMapTypeControl());
			enableContinuousZoom();
			enableScrollWheelZoom();
		}
		Kyan.icon = new GIcon(G_DEFAULT_ICON, '/images/marker.png');
		with(Kyan.icon) {
			shadow = '/images/marker_shadow.png';
			iconSize = new GSize(38,26);
			shadowSize = new GSize(52,27);
			iconAnchor = new GPoint(5, 26);
			transparent = null;
			mozPrintImage = null;
			printImage = null;
			printShadow = null;
		}
		Kyan.marker = new GMarker(Kyan.office, {icon: Kyan.icon})
		// Set the map to its initial state
		Kyan.resetMap(Kyan.map);

		Kyan.directionsPanel = document.getElementById("map_directions_text");
		Kyan.directions = new GDirections(Kyan.map, Kyan.directionsPanel);
		with(GEvent) {
			addListener(Kyan.directions, 'error', Kyan.directionsUnsuccessful);
			addListener(Kyan.directions, 'load', Kyan.directionsSuccessful);
		}
	},

	Google: {
		// Geocodes a UK location by performing a Google local search and taking the
		//     location of the first result.
		// 
		// The search is asynchronous and the result will be passed as a GLatLng to
		//     the supplied callback function. null will be passed if no matching result
		//     could be found.
		geocode: function(place, callback) {
			Kyan.debug("Geocoding");
			var localSearch = new GlocalSearch();
			localSearch.setSearchCompleteCallback(null,
				function() {
					if (localSearch.results[0]) {
						var resultLat = localSearch.results[0].lat;
						var resultLng = localSearch.results[0].lng;
						var point = new GLatLng(resultLat,resultLng);
						callback(point);
					} else {
						callback(null);
					}
				}
			);

			localSearch.execute(place + ", UK");
		}
	},

	// Recentre the map on the Kyanmedia office
	resetMap: function() {
		Kyan.debug("Resetting map");
		with(Kyan.map) {
			if(Kyan.directions) {
				Kyan.directions.clear();
			}
			checkResize();
			setCenter(Kyan.office, 16);
			setMapType(G_HYBRID_MAP);
			removeOverlay(Kyan.marker);
			addOverlay(Kyan.marker);
			// checkResize();
		}
	},
	
	// Expand the small map to fill a bigger space. Also moves other elements out of
	// the way. Calls the callback function when finished
	expandMap: function(callback) {
		Kyan.debug("Expanding map");
		// Need a bigger container to fit the expanded map and directions panel
		$("#map_container").css({width: "870px", marginLeft: "-590px"});

		// a) Grow the map to a bigger size
		$("#map").animate(
			{ width: "500px", height: "440px"},
			800,
			null,
			function() { Kyan.map.checkResize(); if(callback){callback()} }
			// Also make the directions panel the same height (although it should still
			//       be 0-width)
		).siblings('#map_directions').animate({ height: "450px" }, 800);

		// b) Push the left-hand side down so there's no overlap
		// 
		// This selector deals with the case when we've got errors from a form
		//     submission on screen
		$(".errorExplanation,#nature").eq(0).animate({ marginTop: "500px" }, 800);
	},

	// Shrink the map back into its small spot, and hide the directions panel if
	// required
	contractMap: function(callbackFunc) {
		Kyan.debug("Contracting map");
	 // If someone clicks on a directions waypoint the infowindow opens and
	 // doesn't close again by itself even when directions.clear is called
		Kyan.map.closeInfoWindow();
		Kyan.hideDirectionsPanel(function() {
			$("#map_directions").animate({ height: "200px" }, 500)
			$("#map").animate({ width: "270px", height: "190px" }, 500, null, function() {
				Kyan.resetMap();
				$("#map_container").css({width: "280px", marginLeft: "0px"});
				if(callbackFunc){callbackFunc();}
			});

			// This selector deals with the case when we've got errors from a form
			//     submission on screen
			$(".errorExplanation,#nature").eq(0).animate({ marginTop: "0px" }, 500, null, function() {
			});
		});
	},
	
	showDirectionsPanel: function(callback) {
		Kyan.debug("Showing directions panel");
		$("#map_directions_container").css("overflow", "hidden");
		$("#map_directions").animate({ width: "360px" }, 500, null, function() {
		  $("#map_directions_container").css("overflow", "auto");
		  if(callback) {
  		  callback();
		  }
		})
	},
	
	hideDirectionsPanel: function(callback) {
		Kyan.debug("Hiding directions panel");
    $("#map_directions_container").css("overflow", "hidden");
		$("#map_directions").animate({ width: "0px" }, 500, null, callback)
	},
	
	showLoading: function() {
		// TODO: Show a "loading" indicator
		// e.g. replace the Go button with a throbber
	},
	
	hideLoading: function() {
		// TODO: Hide the "loading" indicator
	},	
	
	hideError: function(callback) {
		$("#map_directions_error").slideUp(150, callback);
	},
	
	showError: function(msg) {
		Kyan.debug("Showing error " + msg);
		Kyan.hideError(function() {
			$("#map_directions_error p").html(msg);
			$("#map_directions_error").slideDown();
		})
	},
	
	// Called when the user enters a search term
	getDirectionsFrom: function(place) {
		Kyan.showLoading();
		Kyan.map.closeInfoWindow();
		Kyan.hideError();
		Kyan.debug("Searching for "+place);
		if(place == ""){
			Kyan.contractMap();
			Kyan.showError("Please enter something - I don't know where you're coming from!");
			return;
		};
		Kyan.hideDirectionsPanel(function() {
			Kyan.directions.clear();
			Kyan.Google.geocode(place, function(point) {
				if(point) {
					var directionsString = point.y+','+point.x + " to " + Kyan.carpark.y+','+Kyan.carpark.x;
					Kyan.directions.load(directionsString);
				} else {
					Kyan.directionsUnsuccessful();
				}
			});
		});
	},

	// Called when directions have successfully loaded 
	directionsSuccessful: function() {
		Kyan.hideLoading();
		Kyan.debug("Directions found");
		Kyan.map.setMapType(G_NORMAL_MAP);
		Kyan.expandMap(function() {
			Kyan.showDirectionsPanel();
			with(Kyan.directions) {
        // getMarker(1).hide();
				Kyan.map.setCenter(getBounds().getCenter());
				Kyan.map.setZoom(Kyan.map.getBoundsZoomLevel(getBounds()));
			}
		});
		window.location.hash = '#directions'
		$('#saddr').focus();
	},

	// Called when there's any problem loading directions 
	directionsUnsuccessful: function() {
		Kyan.hideLoading();
		error = "We couldn't find directions to Kyan from here. Please ensure you"+
		" have supplied a UK location &ndash; a postcode will give best"+
		" results.";

		Kyan.contractMap(function() {
			Kyan.showError(error);
		});
		
		$('#saddr').blur();
		$('#saddr').focus();
	}
};

Kyan.init();
$(function() {
	$("#directions_form").submit(function() {
		Kyan.getDirectionsFrom(this.elements['saddr'].value);
		return false
	})
})
