var map;
var markers = {};

function initialize() {
	var initialLatlng = readPermalink();
	var do_not_forget_call_changehash_event_manually = false;

	if (initialLatlng == null) {
		try {
			// sometimes ClientLocation is unreliable (documented by google) and sometimes null
			initialLatlng = new google.maps.LatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude);
		}
		catch (ex) {
			initialLatlng = new google.maps.LatLng(50.0815151, 14.427007);
		}

		var searchtip = "New York, NY";

		try {
			if (google.loader.ClientLocation.address.country_code == "CZ") {
				searchtip = "Václavské nám, Praha";
			}
			else {
				searchtip = google.loader.ClientLocation.address.city + ", " + google.loader.ClientLocation.address.country;
			}
		}
		catch (ex) {
			if (window.console && window.console.error) console.error(ex);
		}

		$("#s").addClass("searchtip").val(searchtip);
	}
	else {
		do_not_forget_call_changehash_event_manually = true; // small trick: hash exists already, need to call event manually
	}

	var myOptions = {
		zoom: 14,
		center: initialLatlng,
		scaleControl: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

	google.maps.event.addListener(map, "dragend", function() {
		var latlng = map.getCenter();
		setPermalink(latlng);
	});

	var prefetchLoader = new Image();
	prefetchLoader.src = "design/ajax-loader.gif";

	$("body").bind("hashchange", function(e, then, now){
		hash_change();
	});	

	$("#s").focus(function() {
		if ($(this).hasClass("searchtip")) {
			$(this).removeClass("searchtip").val("");
		}
	});

	$("#searchbtn").click(function() {
		$("#searchform").trigger("submit");
		return false;	
	});

	$("#specials").change(function(){
		hash_change();
	});

	if (is_geolocation_supported()) {
		$("#locatebtn").show();

		$("#locatebtn").click(function() {
			geolocate_me();
			return false;	
		});
	}

	$("#searchform").submit(function() {
		var geocoder = new google.maps.Geocoder();
		var search = $("#searchform input").val();

		geocoder.geocode({"address":search}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				var latlng = results[0].geometry.location;
				if (window.console && window.console.info) console.info("Geocoded address to: " + latlng);

				map.panTo(latlng);
				if (map.getZoom() < 10 || map.getZoom() > 18)
					map.setZoom(14);

				setPermalink(latlng);
			}
			else
				if (window.console && window.console.error) console.error("Geolocation failed: " + status);
		});
		return false;
	});


	setPermalink(initialLatlng);

	// setting permaling invokes fetching appropriate data from server
	// problem is only if hash was set on 1st page of user session
	if (do_not_forget_call_changehash_event_manually) {
		hash_change();
	}
}

function clear_markers() {
	for (var marker in markers) {
		markers[marker].setMap(null);
	}

	markers = {};
}


function readPermalink() {
	var hash = window.location.hash;
	var lat, lng;

	var result = hash.match(/lat=(-?\d+\.\d+)/);
	if (result == null)
		return null;

	lat = result[1];

	var result = hash.match(/lng=(-?\d+\.\d+)/);
	if (result == null)
		return null;

	lng = result[1];

	return new google.maps.LatLng(lat, lng);
}


function setPermalink(latlng) {
	// Note: if you change permalink, new data are fetched automatically (there is no neccessary to call fetch manually)
	var newhash = "lat=" + latlng.lat() + "&lng=" + latlng.lng();
	if (window.location.hash != newhash)
		window.location.hash = newhash;

	$("#permalink a").attr("href", "#" + newhash);
	return newhash;
}


function hash_change()
{
	var newLatlng = readPermalink();
	if (newLatlng != null) {
		showAjaxLoader();
		map.panTo(newLatlng);
		fetch_and_show_data(newLatlng);
	}
}

function showAjaxLoader()
{
	$("#ajaxDataLoader").html("<img src=\"design/ajax-loader.gif\">");
}

function hideAjaxLoader()
{
	$("#ajaxDataLoader").html("");
}

function easy_round(numb) {
	return Math.round(numb * 10000) / 10000;
}


function fetch_and_show_data(latlng) {
	var url = "fsreq/venues.php?lat=" + latlng.lat() + "&long=" + latlng.lng();

	if (show_only_specials())
		url += "&specials=1";

	$.getJSON(url, function(data, status) {
		if (status == "success") {
			clear_markers();

			if (data.meta && data.meta.code && data.meta.code == 200 && data.response && data.response.venues) {

				var venues = data.response.venues;
				$.each(venues, function(i, item) {
					var letter = String.fromCharCode("A".charCodeAt(0) + i);

					// See http://groups.google.com/group/google-chart-api/web/chart-types-for-map-pins for maps pins API
					var icon = "http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + letter + "|73bdd6|000000";

					var image = new google.maps.MarkerImage(
						icon,
						new google.maps.Size(21, 34),
						new google.maps.Point(0, 0),
						new google.maps.Point(10, 34)
					);

					var shadow = new google.maps.MarkerImage(
						"http://chart.apis.google.com/chart?chst=d_map_pin_shadow",
						new google.maps.Size(40, 37),
						new google.maps.Point(0, 0),
						new google.maps.Point(11, 37)
					);

					if (!item.location.address) item.location.address = "";

					var marker = new google.maps.Marker({
						position: new google.maps.LatLng(item.location.lat, item.location.lng), 
						map: map,
						icon: image,
						shadow: shadow,
						title:(item.name + ", \n" + item.location.address)
					});

					markers[item.id] = marker;
					/*
					var infowindow = new google.maps.InfoWindow({
						content: $('<div><div class="place-info"><a class="name" href="http://example.org/" target="_new">Name</a><div class="address">Address</div></div></div>')
						.item(item)
						.chain({
							".name": {href:"http://foursquare.com/venue/{id}", content:"{name}"}
						})
						.html()
					});

					google.maps.event.addListener(marker, 'click', function() {
						infowindow.open(map, marker);
					});
					*/
				});
			}
			$("#latlong .latitude").html(easy_round(latlng.lat()));
			$("#latlong .longitude").html(easy_round(latlng.lng()));
			$("#places")	
				.items('destroy')
				.items(venues)
				.chain({
					".name": {href:"http://foursquare.com/venue/{id}", "data-placeid":"{id}", content:"{name}"},
					".geo": {title:"{location.lat};{location.lng}"},
					".locate": {href:"#lat={location.lat}&lng={location.lng}"}
				});
		}
		else 
			if (window.console && window.console.error) console.error("Method getJSON failed.");

		hideAjaxLoader();
	});

/*
   	// active list items
	$('#places .item').live('mouseover', function() {
			var placeId = $(this).find(".name").attr("data-placeid")
			if (markers[placeId])
				markers[placeId].dosomething;
	});
*/

}

function show_only_specials() {
	return $('input[id=specials]').is(':checked');
}

function is_geolocation_supported() {
	var geosupport = false;

	try {
		if (navigator.geolocation || google.gears) {
			geosupport = true;
		}
	}
	catch (ex) {}

	return geosupport;
}

function geolocate_me() {
	if (navigator.geolocation) {
		navigator.geolocation.getCurrentPosition(
			function(geopos) {
				var latlng = new google.maps.LatLng(geopos.coords.latitude, geopos.coords.longitude);
				if (window.console && window.console.info) console.info("User geolocated: " + latlng);

				setPermalink(latlng);
			},
			function(err) {
				if (window.console && window.console.error) console.error("Geolocation of user failed: " + err);
			});
	}
	else if (google.gears) {
		google.gears.factory.create('beta.geolocation').getCurrentPosition(
			function(geopos) {
				var latlng = new google.maps.LatLng(geopos.coords.latitude, geopos.coords.longitude);
				if (window.console && window.console.info) console.info("User geolocated: " + latlng);

				setPermalink(latlng);
			},
			function(geopos) {
				if (window.console && window.console.error) console.error("Geolocation of user via Gears failed: " + err);
			});

	}
	else {
		alert("Sorry, no support for automatic geolocation found.");
	}
}

