var markers = [],
	bounds,
	map,
	infowindow,
	$bedroomsSlider,
	$rentSlider;

function showMapCityPage(mapContainer, details) {
	if(map) {
		return;
	}
	if(details && showMap.geocoder) {
		var $mapContainer = $(mapContainer),
			$loading = $('<span>Loading map...</span>').appendTo($mapContainer),
			mapElem = $mapContainer.get(0),
			mapOptions,
			eventListener,
			layer,
			city = $('#city-header h2').text();
		bounds = new google.maps.LatLngBounds();
		showMap.codeAddress(city, function(latLng) {
			mapOptions = {
				zoom: 12,
				//center: latLng,
				mapTypeId: google.maps.MapTypeId.ROADMAP
			};
			map = new google.maps.Map(mapElem, mapOptions);
			$(details).each(function(i, detail) {
				showMap.codeAddress(detail.postcode+", "+city, function(latLng) {
					var marker = new google.maps.Marker({
						position: latLng,
						map: map,
						title: detail.postcode
					});
					infowindow = new google.maps.InfoWindow({
					    content: detail.postcode
					});
					marker.bedrooms = detail.bedrooms;
					marker.rent = detail.rent;
					marker.postcode = detail.postcode;
					markers.push(marker);
					bounds.extend(latLng);
					google.maps.event.addListener(marker, 'click', function() {
						infowindow.setContent(detail.postcode);
						infowindow.open(map,marker);
						refreshPropertiesByPostcode(detail.postcode);
						
					});
					if(i===details.length-1) {
						eventListener = google.maps.event.addListener(map, 'bounds_changed', function() {
							map.origZoom = map.getZoom();
							google.maps.event.removeListener(eventListener);
						});
						map.fitBounds(bounds);
					}
				});
			});
		});
	}
}

function setupGMapsCityPage() {
	showMap.geocoder = new google.maps.Geocoder();
	showMap.codeAddress = function(address, callback) {
		showMap.geocoder.geocode( { 'address': address, 'region': 'UK' }, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				var latLng = results[0].geometry.location;
				callback(latLng);
			} else {
				alert("Geocode was not successful for the following reason: " + status);
			}
		});
	};
	$(document).bind('refreshMaps', function() {
		$('#map').each(function() {
			var propertyDetails = [],
				mapContainer = this;
			$('#properties .property').each(function() {
				propertyDetails.push({
					postcode: getPropertyPostcode(this),
					bedrooms: parseInt($(this).find('.bedrooms span').text(),10),
					rent: parseInt($(this).find('.rent span').text(),10)
				});
			});
			showMapCityPage(mapContainer, propertyDetails);
		});
	});
	// check for any maps that need showing immediately
	$(document).trigger('refreshMaps');
}
  
function loadGMapsScriptCityPage() {
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=setupGMapsCityPage";
	document.body.appendChild(script);
}

function getPropertyPostcode(elem) {
	return $(elem).find('h3').text();
}

function resetFilter() {
	var $bedroomsSlider = $('#bedroomsSlider').slider('enable'),
		$rentSlider = $('#rentSlider').slider('enable');

	$bedroomsSlider.slider('values', [
		$bedroomsSlider.slider('option','min'),
		$bedroomsSlider.slider('option','max')
	]);
	$rentSlider.slider('values', [
		$rentSlider.slider('option','min'),
		$rentSlider.slider('option','max')
	]);

	$(markers).each(function(i, marker) {
		if(!marker.getMap()) {
			marker.setMap(map);
		}
	});
	if(infowindow) {
		infowindow.close();
	}
	if(bounds) {
		if(map.getZoom()===map.origZoom) {
			map.panToBounds(bounds);
		} else {
			map.fitBounds(bounds);
		}
	}

	$('#properties .property').slideDown();
	
	$('#resetFilter').hide();
}

function refreshPropertiesByPostcode(postcode) {
	if(!postcode) {
		return;
	}
	
	$('#bedroomsSlider').slider('disable');
	$('#rentSlider').slider('disable');
	
	$(markers).each(function(i, marker) {
		if(marker.postcode!==postcode) {
			marker.setMap(null);
		} else {
			if(!marker.getMap()) {
				marker.setMap(map);
			}
		}
	});
	$('#properties .property').each(function(i, property) {
		if(getPropertyPostcode(property)!==postcode) {
			//$(property).hide();
			$(property).slideUp();
		} else {
			$(property).slideDown();
		}
	});
	$('#resetFilter').show();
}

function refreshPropertiesByValues(values) {
	var bedroomsMin = values.bedroomsMin,
		bedroomsMax = values.bedroomsMax,
		rentMin = values.rentMin,
		rentMax = values.rentMax,
		checkForNone = function() {
			if($('#properties .property:visible').length===0) {
				$('#noProperties').show();
			} else {
				$('#noProperties').hide();
			}
		};

	// refresh markers
	$(markers).each(function(i, marker) {
		var rent = marker.rent,
			bedrooms = marker.bedrooms;
		if(rent < rentMin || rent > rentMax || bedrooms < bedroomsMin || bedrooms > bedroomsMax) {
			marker.setMap(null);
		} else {
			if(!marker.getMap()) {
				marker.setMap(map);
			}
		}
	});
	
	// refresh property list
	$('#properties .property').each(function(i, property) {
		var $property = $(property),
			bedrooms = parseInt($property.find('.bedrooms span').text(),10);
			rent = parseInt($property.find('.rent span').text(),10);
		if(rent < rentMin || rent > rentMax || bedrooms < bedroomsMin || bedrooms > bedroomsMax) {
			$property.slideUp(checkForNone);
		} else {
			$property.slideDown(checkForNone);
		}
	});

	$('#resetFilter').show();
}

function getSlidersMinMax(ui) {
	var $slider = $(ui.handle).parent(),
		bedroomsMin,
		bedroomsMax,
		rentMin,
		rentMax,
		values = ui.values;
	if($slider.attr('id')==="bedroomsSlider") {
		bedroomsMin = values[0];
		bedroomsMax = values[1];
		values = $('#rentSlider').slider("values");
		rentMin = values[0];
		rentMax = values[1];
	} else {
		rentMin = values[0];
		rentMax = values[1];
		values = $('#bedroomsSlider').slider("values");
		bedroomsMin = values[0];
		bedroomsMax = values[1];		
	}
	return {
		bedroomsMin: bedroomsMin,
		bedroomsMax: bedroomsMax,
		rentMin: rentMin,
		rentMax: rentMax
	};
}

function refreshSliderLabels(e, ui) {
	var $handle = $(ui.handle),
		value = ui.value;
	$handle.find('.label').text(value);
}

var tmp_slider = $.fn.slider;
$.fn.slider = function(options) {
	var $slider = tmp_slider.apply(this,arguments);
	if(typeof options!=="string") {
		var $slider = $(this),
			values = options.values;
		$slider.find('.ui-slider-handle').each(function(i) {
			$('<span class="label">'+values[i]+'</span>').appendTo(this);
		});
	}	
	return $slider;
};

$(document).ready(function() {
	if($('#properties .property').length===0 || $('#map').length===0) {
		return;
	}
	loadGMapsScriptCityPage();

	var callback = function(e, ui) {
			if(!e.originalEvent || e.type==="slide") { // e.originalEvent not set when value changed by slider('values', ...)
				var values = getSlidersMinMax(ui);
				refreshPropertiesByValues(values);
				refreshSliderLabels(e, ui);
			}
		},
		options,
		maxBedrooms = 0,
		minBedrooms = 10,
		maxRent = 0,
		minRent = 1000;
	$('#properties .property').each(function() {
		var $property = $(this),
			bedrooms = parseInt($property.find('.bedrooms span').text(), 10),
			rent = parseInt($property.find('.rent span').text(), 10);
		maxBedrooms = Math.max(maxBedrooms,bedrooms);
		minBedrooms = Math.min(minBedrooms,bedrooms);
		maxRent = Math.max(maxRent,rent);
		minRent = Math.min(minRent,rent);
	});
	options = {
		max: maxBedrooms,
		min: minBedrooms,
		range: true,
	//	step: 1,
		values: [minBedrooms,maxBedrooms],
		slide: callback,
		change: callback
	};
	$bedroomsSlider = $('#bedroomsSlider').slider(options);
	options = {
		max: maxRent,
		min: minRent,
		range: true,
		step: 5,
		values: [minRent,maxRent],
		slide: callback
	};
	$rentSlider = $('#rentSlider').slider(options);
	
	$('#resetFilter').live('click', function(e) {
		e.preventDefault();
		resetFilter();
	});
});
