// defaults
var speed = 'download_speed'
var type = 'home';
var url = false;
var limit = 1;
var lat_long = false;
var old_url = false;
var markers = [];
var exchange_markers = []
var u_marker = false;
var loaded = false;
var user_location = false;
var user_latlng = false;
var postcode_location = false;
var postcodeDetails;
var map = false;
var localSearch = false;
var icon = false;
var exchange_icon = false;
var marker_cluster = false;
var exchange_marker_cluster = false;
var user_plotted = false;
var existing_markers = {};
var existing_exchange_markers = {};
var z_index_count = 1;
var bubble_marker = false;
var old_time = false;
var zoomLevel = 16;
var filters_enabled = true;
var exchange_to_click = false;

// url params
var url_type = 'home';
var url_place = false;
var url_speed = 'download';
var initial_hash = window.location.hash;
var url_speed_value = '0';
var url_exchange = 'all';
var url_provider = 'all';
var url_time = '0';
var url_verified = '1';

var PC_icon = new GIcon();
PC_icon.image = $.image({src: '/_img/broadband/speedtest_new/maps_green_you_marker.png',width: 58,height: 81,depth: 32, notag: true});
PC_icon.iconSize = new GSize(58, 81);
PC_icon.shadowSize = new GSize(0, 0);
PC_icon.iconAnchor = new GPoint(29, 81); // needs to be half width of the image and full height
PC_icon.infoWindowAnchor = new GPoint(25, 7);

// see if user_data exists
try {
	user_data = user_data;
} catch(e) {
	user_data = false;
}


// map initiation
function initMaps() {
	// intialise
	map = new GMap2(document.getElementById("map_canvas"), {size: new GSize(857, 550)});

	$('#map_location input.hint').val('').attr('title','Street or Postcode').hint();

	// search
	localSearch = new GlocalSearch();
	
	// setup geocoder and set default country to the UK
	geocoder = new GClientGeocoder();
	geocoder.setBaseCountryCode('UK'); // default to UK address
	
	// customise map
	customise_map(map);
	
	// custom marker
	icon = new GIcon();
	if ($.browser.msie && $.browser.version < 7) {
		icon.image = $.image({src: '/_img/map_marker_static.png',width: 81,height: 88,depth: 32, notag: true});
	}
	else {
		icon.image = $.image({src: '/_img/map_marker.png',width: 81,height: 88,depth: 32, notag: true});
	}
	
	icon.iconSize = new GSize(81, 88);
	icon.shadowSize = new GSize(0, 0);
	icon.iconAnchor = new GPoint(45, 75); // needs to be half width of the image and full height
	icon.infoWindowAnchor = new GPoint(25, 7);
	//Hover effect
	$('#map_canvas .LabeledMarker_markerLabel').live('mouseover',function(){
		$(this).prev().addClass('hovered_marker');
	});

	$('#map_canvas .LabeledMarker_markerLabel').live('mouseout',function(){
		$(this).prev().removeClass('hovered_marker')
	});
	
	// custom marker
	exchange_icon = new GIcon();
	if ($.browser.msie && $.browser.version < 7) {
		exchange_icon.image = $.image({src: '/_img/map_marker_exchange_static.png',width: 58,height: 65,depth: 32, notag: true});
	}
	else {
		exchange_icon.image = $.image({src: '/_img/map_marker_exchange.png',width: 58,height: 65,depth: 32, notag: true});
	}
	exchange_icon.iconSize = new GSize(58, 65);
	exchange_icon.shadowSize = new GSize(0, 0);
	exchange_icon.iconAnchor = new GPoint(26, 75); // needs to be half width of the image and full height
	
	//Hover effect
	$('#map_canvas .exchange').live('mouseover',function(){
		$(this).prev().addClass('hovered_exchange_marker');
	});

	$('#map_canvas .exchange').live('mouseout',function(){
		$('.hovered_exchange_marker').removeClass('hovered_exchange_marker');
	});

	
	// custom images for clusters
	var styles = [[{
		url: $.image({src: '/_img/broadband/speedtest_new/map_cluster_small.png',width: 70,height: 22,depth: 32, notag: true}),
		height: 22,
		width: 70,
		opt_textColor: '#FFF'
	},
	{
		url: $.image({src: '/_img/broadband/speedtest_new/map_cluster_medium.png',width: 80,height: 22,depth: 32, notag: true}),
		height: 22,
		width: 80,
		opt_textColor: '#FFF'
	},
	{
		url: $.image({src: '/_img/broadband/speedtest_new/map_cluster_large.png',width: 92,height: 22,depth: 32, notag: true}),
		height: 22,
		width: 92,
		opt_textColor: '#FFF'
	}]];
	
	// initialise clusterer
	marker_cluster = new MarkerClusterer(map, markers, {gridSize: 100, maxZoom: 15, styles: styles[0]});
	
	
	if(user_data) {
		//DEV
		//user_data.postcode=$('li.connection li:not(.connection_mobile_broadband) input:text').val();

		// save users new location
		if(user_data.postcode.match(/[A-Za-z]{1,2}\d[A-Za-z\d]? ?\d[A-Za-z]{2}/)) {
			
			get_postcode_location(user_data.postcode, update_users_location);
			
		// search for location
		} else {
			
			update_users_location();
	
		}
	
	}
	else {
	
	}
	
	location_check = setInterval("update_map_location()", 500);

	// load map filters
	load_filters();
	
	// load provider list
	update_provider_filter();
	
	$('em.exchange').text( user_data.location_data );

}

// update map location
function update_map_location() {

	if(user_latlng) {
	
		// clear the location check
		clearInterval(location_check);
		
		// center on map if speedtest
		// if (postcodeDetails) {
	
		user_latlng = new GLatLng(user_data.location_data.lat, user_data.location_data.long);
		map.addOverlay(new GMarker(user_latlng,PC_icon));
		var centerLatMap = parseFloat(user_data.location_data.lat) + 0.001;
		user_latlng = new GLatLng(centerLatMap, user_data.location_data.long);
		map.setCenter(user_latlng, 20);
		// } else {
		// map.setCenter(user_latlng, 15);
		// }
		
	}
}

// put maps in a function so we can unload it later
function load_map(map,url){
	
	// if new data is coming in, reset map & load data
	if(old_url != url) {

		// remove any previous loaders
		$('#map_container #loading_data').remove();
	
		// add loader
		$('#map_container').append('<span id="loading_data">'+$.image({src: '/_img/broadband/speedtest_new/spinner.gif',width: 15,height: 15,alt: 'Loading',depth: 32})+' Loading data...</span>');
	
		// Get data
		$.getJSON(url + '&jsoncallback=?', function(data){
		
			// remove loading
			$('#map_container #loading_data').remove();
		
			// plot map
			plot_maps(map,data);

			// update filters
			update_filters(data);
		
		});

	}
	
	// set old url so we can see if we need to fetch data when user changes settings
	old_url = url;

}

// loap default map (only on standalone speedmaps page)
if(window.location.href.indexOf("streetstats") > 1) {
	
	// set retest to false as this is defined in another js file not included on standalone speedmaps
	var retest = false;

}

// called when google api's have been loaded
function load_standalone_maps() {
	// add welcome message
	$('#fancy_overlay').addOverlay();
	$('#welcome_box').fadeInSlide();

	// initialise maps
	initMaps();

	// say we've loaded it
	loaded = true;

	// load directly to location in url
	if(initial_hash) {
		// now place the markers
		load_map(map,false);
		// check url for params
		get_url();
	
	} else {
	
		// default to users location if we can
		if(google.loader.ClientLocation){
			url_place = google.loader.ClientLocation.address.city;
			lat_long = new GLatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude);
		} else {
			url_place = 'London';
			lat_long = new GLatLng('51.5002', '-0.1262');
		}

		// now place the markers
		load_map(map,url);
		
		// fade out map until user chooses a location
		map.setCenter(lat_long, 6);
		
		// update type
		$('#results_nav li.speedmaps_home a').click();
	} // No initial hash
	

	// click box magic
	if (!$.browser.msie || $.browser.msie && $.browser.version > 6) {
		//clickBox();
	}
	
	// listen for any new location requests
	$('#fastest_locations a').click(function(){
	
		// delay slightly to give browser chance to update URL, then update map
		setTimeout("get_url()", 100);
		$(window).scrollTo($('#map_container'), 250);
	
	});
	
	//Trigger geolocation
		$('.trigger_geolocation').click(function(){
			$('#welcome_box').hide();
			$('#map_overlay,#dialogue_icon').show();
			$('#geolocation_dialogue').show();
			navigator.geolocation.getCurrentPosition(
				function(position){//Position handler
					latlng = new GLatLng(position.coords.latitude, position.coords.longitude);
					map.addOverlay(new GMarker(latlng,PC_icon));
					var centerLatMap = parseFloat(position.coords.latitude) + 0.001;
					latlng = new GLatLng(centerLatMap, position.coords.longitude);
					map.setCenter(latlng, 20);
					$('#geolocation_dialogue').addClass('location_success').find('span').html('Location detected');
					$('#map_overlay').fadeOut(1900, function(){$('#geolocation_dialogue').fadeOut(function(){
						$('#geolocation_dialogue').removeClass('location_success').find('span').html('Detecting your location...');
					})});
				},
				function(error) {//Error handler
					if (error.code==1) { //Permission denied
						$('#map_overlay').hide();
						$('#geolocation_dialogue').hide();
						$('#welcome_box').fadeIn();
					}
					else {
						$('#geolocation_dialogue').addClass('location_error').find('span').html('Unable to detect your location');
						$('#cancel_geolocation').html('close');
					}
				}
			,{timeout: 10000});
			
			$('#map_overlay, #geolocation_dialogue').click(function(){
				$('#map_overlay').fadeOut();
				$('#welcome_box').fadeIn();
				$('#geolocation_dialogue').fadeOut();
				
			});
		});

}

// unload map on window close
$(window).unload(function() {
	GUnload();
});

// get url
function get_url() {

	var hash = window.location.hash.replace('#','');
	var updated_url = hash.split("_");
	
	// custom hash, update map accordingly
	if(hash) {

		// replace spaces
		updated_url[1] = updated_url[1].replace(/%20/g,' ');

		// create url params
		url_type = updated_url[0];
		url_place = updated_url[1];
		url_speed = updated_url[2];
		url_speed_value = updated_url[3];
		url_exchange = updated_url[4];
		url_provider = updated_url[5];
		url_time = updated_url[6];
		url_verified = updated_url[7]

		// default to london if "street or postcode"
		if(url_place == 'street or postcode') {
			url_place = 'London';
		}

		// update type
		$('#results_nav li.speedmaps_' + updated_url[0] + ' a').click();

		// update location
		$('#map_location input:text').val(url_place).addClass('blur').next().click();
	
		// update speed
		$('#map_speed input#' + updated_url[2] + '_speeds').click();
		
		// update min speed value
		$('#slider').slider('option', 'value', url_speed_value);
		update_slider();
		
		// delay updating the selext boxes
		setTimeout('update_filter_selects()', 500);
		
		// update verified
		if(url_verified == 1){
			$('#url_verified').attr('checked','checked');
		} else {
			$('#url_verified').removeAttr('checked');
		}
	
	}
	
	return false;

}

function update_filter_selects() {
		
	// update provider
	$('#url_provider option[value=' + url_provider + ']').attr('selected', 'selected');
		
	// update time period
	$('#url_time option[value=' + url_time + ']').attr('selected', 'selected');
	
	update_filter_text();

}

// update url
function update_url() {

	update_filter_text();

	// loap default map (only on standalone speedmaps page)
	if(window.location.href.indexOf("streetstats") > 1) {
	
		window.location.href = window.location.href.replace(/#.*$/, '') + '#' + url_type + '_' + url_place + '_'  + url_speed + '_'  + url_speed_value + '_'  + url_exchange + '_'  + url_provider + '_'  + url_time + '_' + url_verified;

		// track in analytics
//		pageTracker._trackPageview("/speedtest/streetstats/#" + url_type + '_' + url_place + '_'  + url_speed + '_'  + url_speed_value + '_'  + url_exchange + '_'  + url_provider + '_'  + url_time + '_' + url_verified);
	
	}

}

// allows for clicks on the markers
function createMarkerClickHandler(marker, speedtest) {
	return function() {
		
		// disable clicks if click is on the same bubble
		if( $(marker.div_.lastChild).is('.bubble_info') ) {
			return false;
		}
		
		// get pixel position of marker
		pixels = map.fromLatLngToContainerPixel(marker.getLatLng());

		// apply an offset so we can center on marker nicely
		pixels.y = pixels.y - 135;
		
		// convert to lat/long
		lat = map.fromContainerPixelToLatLng(pixels)
		
		// pan to marker
		map.panTo(lat);
		
		// show any hidden markers
		$('.temp_hidden').show();
		
		// remove any other bubbles
		$('.bubble_info').remove();
		
		// set z-index high so it overlaps other markers
		$(this.div_).css('z-index', z_index_count + 20);
		
		// hide the bubble image relating to the marker
		if( $(this.div_).prev().is('img') ){
			$(this.div_).prev().addClass('temp_hidden').hide();
		}
		
		
		// if price not 2 decimal places, add them
		if(speedtest.price) {
			if(speedtest.price.indexOf('.') == -1) {
				speedtest.price = speedtest.price + '.00';
			}
		}
		
		// add close button
		var html = '<a class="close_window" alt="Close" title="Close"></a>';

		// setup table content
		html += '<table cellpadding="0" cellspacing="0" width="281"><thead><tr><th colspan="2">' + STREETSTATS_BUBBLE_HEADER_TEXT + '</th></tr></thead><tbody><th width="40%">Speeds</th><td width="60%">Download: ' + Math.round(speedtest.download_speed*10)/10 + 'Mb <span>Upload: ' + Math.round(speedtest.upload_speed*10)/10 + 'Mb</span></td></tr>';
		
		// check if provider exists
		if(speedtest.provider) {
			html += '<tr><th>' + STREETSTATS_BUBBLE_PROVIDER_TEXT + '</th><td>' + speedtest.provider + '</td></tr>';		
		} else {
			html += '<tr><th>' + STREETSTATS_BUBBLE_PROVIDER_TEXT + '</th><td>Unknown</td></tr>';
		}
		
		// check which location type to show
		if(speedtest.type == 2) {
		
			var location = speedtest.pc;
		
			if(location.length > 23) {
				location = location.substring(0,20) + '...';
			}
		
			html += '<tr><th>' + STREETSTATS_BUBBLE_LOCATION_TEXT + '</th><td>' + location + '</td></tr>';
			
		} else {
		
			html += '<tr><th>' + STREETSTATS_BUBBLE_POSTCODE_TEXT + '</th><td>' + speedtest.pc + '</td></tr>';
			
		}
		
		exchange_to_click = false;
		
		// loop through all exchanges to figure out which one we can click on
		jQuery.each(exchange_markers, function() {

			// strip out the telephone exchange text so we can get the real name of the exchange
			var exchange_name = this.title_;
			exchange_name = exchange_name.substring(0, exchange_name.length-19);

			if( speedtest.exchange == exchange_name ) {
			
				exchange_to_click = this;
			
				$('#exchangeLink').live('click', function(){
				
					// need to zoom in so we can see the marker if zoomed out too far
					if(zoomLevel >= 15) { map.setZoom(16) }
				
					// close the speed test marker, we don't want that open as well as the exchange marker
					$('.bubble_info .close_window').click();

					// click on the exchange marker to open it
					GEvent.trigger(exchange_to_click, 'click');					
					
					return false;
				
				});
			
			}

		});
		
		// strip characters if too long
		if(speedtest.exchange.length > 18) {
			speedtest.exchange = speedtest.exchange.substring(0,15) + '...';
		}
		
		// add exchange
		html += '<tr><th>' + STREETSTATS_BUBBLE_EXCHANGE_TEXT + '</th><td><a href="#" id="exchangeLink">' + speedtest.exchange + '</a></td></tr><tr><th>' + STREETSTATS_BUBBLE_EXCHANGE_DISTANCE_TEXT + '</th><td>' + speedtest.exchange_distance + ' meters away</td></tr>';

		// add date & time
		html += '<tr><th>' + STREETSTATS_BUBBLE_DATE_TEXT + '</th><td>' + speedtest.date + '</td></tr></tbody></table>';
		
		// setup deal text
		if(speedtest.com == 1 && speedtest.provider_logo) {
			html += '<span class="price provider_logo">' + $.image({src: speedtest.provider_logo, width: 34, height: 21, alt: this.title_, mode: 'fill',depth:32}) + ' ' + STREETSTATS_BUBBLE_DEAL_TEXT + '' + speedtest.price + '</span>';
		} else if(speedtest.com == 1 && speedtest.provider) {
			html += '<span class="price">' + speedtest.provider + ' ' + STREETSTATS_BUBBLE_DEAL_TEXT + '' + speedtest.price + '</span>';
		}
		
		// setup button
		if(speedtest.com == 1) {
			html += '<a href="'+channel_url+'/_ajax/speedtest.php?action=products&provider=' + speedtest.provider_id + '&menu_id=' + menu_id + '" class="provider_table btn btn_red" alt="' + STREETSTATS_BUBBLE_DEAL_BUTTON_TEXT+ '" title="' + STREETSTATS_BUBBLE_DEAL_BUTTON_TEXT + '"><span>' + STREETSTATS_BUBBLE_DEAL_BUTTON_TEXT + '</span></a>';
		}
		
		// add bubble
		$('<div class="bubble_info">' + html + '</div>').appendTo(this.div_);
		
		// setup fancybox
		$('.provider_table').providerFancybox();
		
		// increment z-index count for next click
		++z_index_count;
		
		// redraw last marker to have a bubble so its z-index is set correctly
		if(bubble_marker.div_) { bubble_marker.redraw(true); }
		
		// set marker
		bubble_marker = marker;

	};
}

// allows for mouseover on the markers
function createMarkerMouseoverHandler(marker, speedtest) {
/*
	return function() {
	
		if( $(this.div_).prev().is('img') ){
			var src = $.asset({src:$(this.div_).prev().attr('data-src'),notag:1});
			$(this.div_).prev().attr('src', $.asset({src: src.replace('.png','_hover.png'),notag:true}));
		}
	
	}
*/
}

// allows for mouseout on the markers
function createMarkerMouseoutHandler(marker, speedtest) {
/*
	return function() {
	
		if( $(this.div_).prev().is('img') ){
			var src = $.asset({src:$(this.div_).prev().attr('data-src'),notag:true});
			$(this.div_).prev().attr('src', src.replace('_hover','') );
		}
	
	}
*/
}

// allows for clicks on the exchange markers
function createExchangeMarkerClickHandler(marker, exchange) {
	return function() {
		
		// disable clicks if click is on the same bubble
		if( $(marker.div_.lastChild).is('.bubble_info') ) {
			return false;
		}
		
		// get pixel position of marker
		pixels = map.fromLatLngToContainerPixel(marker.getLatLng());

		// apply an offset so we can center on marker nicely
		pixels.y = pixels.y - 135;
		
		// convert to lat/long
		lat = map.fromContainerPixelToLatLng(pixels)
		
		// pan to marker
		map.panTo(lat);
		
		// show any hidden markers
		$('.temp_hidden').show();
		
		// remove any other bubbles
		$('.bubble_info').remove();
		
		// set z-index high so it overlaps other markers
		$(this.div_).css('z-index', z_index_count + 20);
		
		// hide the bubble image relating to the marker
		if( $(this.div_).prev().is('img') ){
			$(this.div_).prev().addClass('temp_hidden').hide();
		}
		
		// add close button
		var html = '<a class="close_window" alt="Close" title="Close"></a>';

		// strip characters if too long
		if(exchange.name.length > 18) {
			exchange.name = exchange.name.substring(0,15) + '...';
		}

		// setup table content
		html += '<table cellpadding="0" cellspacing="0" width="281"><thead><tr><th colspan="2">Exchange Details</th></tr></thead><tbody>';
		html += '<tr><th width="55%">' + STREETSTATS_EXCHANGE_BUBBLE_NAME_TEXT + '</th><td width="45%">' + exchange.name + '</td></tr>';
		html += '<tr><th>' + STREETSTATS_EXCHANGE_BUBBLE_POSTCODE_TEXT + '</th><td>' + exchange.pc + '</td></tr>';
		html += '<tr><th>' + STREETSTATS_EXCHANGE_BUBBLE_TESTS_TEXT + '</th><td>' + exchange.tests + '</td></tr>';
		html += '<th>' + STREETSTATS_EXCHANGE_BUBBLE_DOWNLOAD_TEXT + '</th><td>' + Math.round(exchange.download*10)/10 + 'Mb</td></tr>';
		html += '<tr class="last"><th>' + STREETSTATS_EXCHANGE_BUBBLE_UPLOAD_TEXT + '</th><td>' + Math.round(exchange.upload*10)/10 + 'Mb</td></tr>';
		html += '</tbody></table>';
		
		// add bubble
		$('<div class="bubble_info exchange_bubble">' + html + '</div>').appendTo(this.div_);
		
		// setup fancybox
		$('.provider_table').providerFancybox();
		
		// increment z-index count for next click
		++z_index_count;
		
		// redraw last marker to have a bubble so its z-index is set correctly
		if(bubble_marker.div_) { bubble_marker.redraw(true); }
		
		// set marker
		bubble_marker = marker;

	};
}

// yay plot the map
function plot_maps(map,data) {

	var markers = []
	var label_text = '';
	
	// add exchanges
	jQuery.each(data.exchange, function() {
		
		// only add markers not already on the map
		if(!existing_exchange_markers[this.id]) {
		
			// add to existing markers
			existing_exchange_markers[this.id] = true;
		
			// get latlng
			var latlng = new GLatLng(this.latitude, this.longitude);
			
			// options
			opts = { 
				"icon": exchange_icon,
				"clickable": true, // set to true if we want to show product tables again
				"title": this.name + ' Telephone Exchange',
				"labelOffset": new GSize(0, -68),
				"labelClass": "exchange"
			};
			
			var exchange_marker = new LabeledMarker(latlng, opts);
			exchange_markers.push(exchange_marker);
			map.addOverlay( exchange_marker );
			
			// add click handler
			var exchange_handler = createExchangeMarkerClickHandler(exchange_marker, this);
			GEvent.addListener(exchange_marker, "click", exchange_handler);
			
/*
			// add mouseover handler
			var mouseover_handler = createMarkerMouseoverHandler(exchange_marker, this);
			GEvent.addListener(exchange_marker, "mouseover", mouseover_handler);
			
			// add mouseout handler
			var mouseout_handler = createMarkerMouseoutHandler(exchange_marker, this);
			GEvent.addListener(exchange_marker, "mouseout", mouseout_handler);
*/

		}
		
	});
	
	// add tests
	jQuery.each(data.tests, function() {
		
		// only add markers not already on the map
		if(!existing_markers[this.id]) {
		
			// add to existing markers
			existing_markers[this.id] = true;
			
			// get latlng
			var latlng = new GLatLng(this.latitude, this.longitude);
			
			// no provider, set to unknown
			if(!this.provider) {
				label_text = '<em class="unknown_provider">?</em>';
			// no logo, set text
			} else if(!this.provider_logo) {
				label_text = '<em class="provider_without_logo">' + this.provider + '</em>';
			// logo
			} else {
				label_text = $.image({src: this.provider_logo, width: 50, height: 31, alt: this.provider, mode: 'fill',depth:32})
			}
			
			// format download speed
			if(this.download_speed < 0.05) {
				var m_download_speed = '0.1';
			} else {
				var m_download_speed = Math.round(this.download_speed*10)/10;
			}
			
			// format upload speed
			if(this.upload_speed < 0.05) {
				var m_upload_speed = '0.1';
			} else {
				var m_upload_speed = Math.round(this.upload_speed*10)/10;
			}
			
			// options
			opts = { 
				"icon": icon,
				"clickable": true, // set to true if we want to show product tables again
				"title": this.provider,
				"labelText": label_text + '<p class="download_speed">' + m_download_speed + 'Mb</p><p class="upload_speed">' + m_upload_speed + 'Mb</p><span id="' + this.id + '"></span>',
				"labelOffset": new GSize(-35, -70)
			};
			
			// don't add markers that sit on top of users marker
			if(user_data && user_latlng) {
	
				// distance has to be more than 100 meters
				if (latlng.distanceFrom(user_latlng) > 100) {
		
					var marker = new LabeledMarker(latlng, opts);
					markers.push(marker);
			
					// click handlers must be added here, 
					// not outside the if statement, otherwise google throws an error
			
					// add click handler
					var handler = createMarkerClickHandler(marker, this);
					GEvent.addListener(marker, "click", handler);
							
/*
					// add mouseover handler
					var mouseover_handler = createMarkerMouseoverHandler(marker, this);
					GEvent.addListener(marker, "mouseover", mouseover_handler);
					
					// add mouseout handler
					var mouseout_handler = createMarkerMouseoutHandler(marker, this);
					GEvent.addListener(marker, "mouseout", mouseout_handler);
*/
		
				}
			
			} else {
			
				var marker = new LabeledMarker(latlng, opts);
				markers.push(marker);
				
				// click handlers must be added here, 
				// not outside the if statement, otherwise google throws an error
				
				// add click handler
				var handler = createMarkerClickHandler(marker, this);
				GEvent.addListener(marker, "click", handler);
						
/*
				// add mouseover handler
				var mouseover_handler = createMarkerMouseoverHandler(marker, this);
				GEvent.addListener(marker, "mouseover", mouseover_handler);
				
				// add mouseout handler
				var mouseout_handler = createMarkerMouseoutHandler(marker, this);
				GEvent.addListener(marker, "mouseout", mouseout_handler);
*/
			
			}
			
		}

	});
	
	// hide exchanges if zoomed too far out
	if(zoomLevel >= 15) {
		// don't show exchange marker if bubble already showing
		if( !$('div.exchange .bubble_info') ) {
			$('div.exchange').add( $('div.exchange').prev() ).show();
		}
	} else {
		$('div.exchange').add( $('div.exchange').prev() ).hide();
	}
	
	// place the markers on the map
	marker_cluster.addMarkers(markers);

	// only do this when filters enabled
	if(filters_enabled) {
	
		if(marker_cluster.getClustersInViewport_().length == 0) {
			
			// show tip
			$('.map_tip').fadeIn();
			
			// Offset google copyright & logo
			$('div#map_canvas').children('div:eq(2)').add('#logocontrol').addClass('offset_map');
			
		} else {
		
			// hide tip
			$('.map_tip').fadeOut();
			
			// remove offset on copyright & logo
			$('div#map_canvas').children('div:eq(2)').add('#logocontrol').removeClass('offset_map');
		}
	
	}

}

// update map filters
function update_filters(data) {

	$exchanges = $('#url_exchange');
	$selected = $('#url_exchange option:selected').val();

	// empty current selection apart from selected item
	$exchanges.find('option:not(:first,:selected)').remove();

	if(data.exchange) {

		// add new exchanges in
		jQuery.each(data.exchange, function() {
		
			if(this.id != $selected) {
		
				if(this.id == url_exchange) {
					selected = 'selected="selected"';
				} else {
					selected = false;
				}
				
				if(this.tests_on_map == 1) {
					result_msg = 'result'
				} else {
					result_msg = 'results'
				}
				
				var result_msg = 'results'
				if(this.tests_on_map == 1) {
					result_msg = 'result'
				}
				
				$exchanges.append($('<option value="' + this.id + '"' + selected + '>' + this.name +' ('+ this.tests_on_map+ ' '+ result_msg +')</option>'));
			
			}
		
		});
	
	}

}

// updates the provider filter select
function update_provider_filter() {

	select_box = $('select#url_provider');
	
	// empty previous providrs
	$(select_box).find('optgroup, option:not(:first)').remove();

	// load providers
	$.ajax({
		url: channel_url+'/_ajax/speedtest.php',
		data: 'action=providers_list&connection_type=1',
		dataType: "json",
		success: function(ajax_response) {
			$.each(ajax_response, function (k, v) {
				$(select_box).append('<optgroup label="'+k+'">');
				$.each(v,function(kk,vv){
					$(select_box).append('<option value=\"'+vv.id+'\" label=\"'+vv.name+'\">'+vv.name+'</option>');
				});
			$(select_box).append('</optgroup>');
			});
		}
	});
}

// add users tests onto the map
function addUserMarker(icon,marker_cluster,refresh) {
	
	// Custom Marker Icon
	var icon = new GIcon();
	icon.image = $.image({src: '/_img/broadband/speedtest_new/map_marker_user.png',width: 81,height: 88,depth: 32, notag: true});
	icon.iconSize = new GSize(81, 88);
	icon.shadowSize = new GSize(0, 0);
	icon.iconAnchor = new GPoint(45, 75); // needs to be half width of the image and full height
	icon.infoWindowAnchor = new GPoint(25, 7);
	
	// setup users marker
	u_opts = { 
	"icon": icon,
	"clickable": false,
	"labelText": '<div class="user_rating"><em class="rating_' + user_data.rating + '"></em><h4>You</h4><p class="download_speed">' + down_speed + 'Mb</p><p class="upload_speed">' + up_speed + 'Mb</p></div>',
	"labelOffset": new GSize(-35, -70)
	};
	
	// add users marker
	u_marker = new LabeledMarker(user_latlng, u_opts);
	
	// add it to map
	map.addOverlay(u_marker);

	return false;

}

// used for mobile broadband to get a random point within an area
// as we can't have them all on the same point
function getRandomPoint(location_latlng) {

	// setup area
	var bounds = map.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var lngSpan = northEast.lng() - southWest.lng();
	var latSpan = northEast.lat() - southWest.lat();

	// generate a lat/lng for user
	user_latlng = new GLatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random());
	
	// distance has to be more than 1500 meters
	if (user_latlng.distanceFrom(location_latlng) > 1500) {
	
		// try again
		getRandomPoint(location_latlng);
	
	}

}

// shows location on map
function showAddressOnMap(response) {

	if (!response || response.Status.code != 200) {
	
		// don't do this if first time loaded
		if(window.location.hash != initial_hash || window.location.href.indexOf("streetstats") == -1) {
		
			// update welcome box with error message
			$('#welcome_box')
			.addClass('error')
			.find('h2')
			.html('<em></em> Error')
			.end()
			.find('p:first')
			.text($('#map_location input:text').val() + " " + STREETSTATS_LOCATION_NOT_FOUND)
			.end()
			.find('p:last')
			.text(SPEEDTEST_MAPS_EXAMPLE)
			.end()
			.fadeInSlide();
			
			// track in analytics
//			pageTracker._trackPageview("/speedtest/streetstats/error/location_not_found/" + $('#map_location input:text').val());
		
		}
	
	} else {
	
		// don't do this if first time loaded
		if(window.location.hash != initial_hash || window.location.href.indexOf("streetstats") == -1) {
	
			// hide welcome box
			$('#welcome_box').fadeOutSlide();
		
		}
	
		place = response.Placemark[0];
		point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
		accuracy = place.AddressDetails.Accuracy;
		
		// Zoom levels for things like cities, countries, roads etc. as google doesn't provide this in their API
		if (accuracy==1) { // Country
			zoomLevel = 6;
			location_name = place.AddressDetails.Country.CountryName;
			$("div.zoomOut").fadeTo("normal", 0.4).css("cursor","default");
		} else if (accuracy==2) { // Country
			zoomLevel = 6;
			try {
				location_name = place.AddressDetails.Country.AddressLine[0];
			} catch(i) {
				location_name = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
			}
		} else if (accuracy==3) { // Area/Region
			zoomLevel = 10;
			location_name = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
		} else if (accuracy==4) { // City
			zoomLevel = 12;
			
			try {
				location_name = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
			} catch(i) {
				try {
					location_name = place.AddressDetails.Country.SubAdministrativeArea.Locality.LocalityName;
				} catch(i) {
					try {
						location_name = place.AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
					} catch(i) {
						try {
							location_name = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.AddressLine[0];
						} catch(i) {
							location_name = place.AddressDetails.Country.Locality.AddressLine[0];
						}
					}
				}
			}
			
		} else if (accuracy == 5) { // Postcode
			zoomLevel = 15;
			try {
				location_name = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName
			} catch(i) {
				location_name = place.AddressDetails.Country.Locality.LocalityName
			}
			$("div.zoomIn").fadeTo("normal", 0.4).css("cursor","default");
		}
		
		// exceptions for countries of large proportions
		if (place.address=='United States' || place.address=='Canada' || place.address=='China') {
			zoomLevel = 4;
		} else if (place.address=='Russian Federation') {
			zoomLevel = 3;
		} else if (place.address=='Brazil' || place.address=='Australia') {
			zoomLevel = 5;	
		}
	
		zoomLevel = 16;
	
		// only do this is the map not been loaded before
		if(!loaded) {

			// update broadband availability
			broadband_location = $("fieldset#map_location input[type='text']").val();
			
			// strip characters if too long
			if(broadband_location.length > 8) {
				broadband_location = broadband_location.substring(0,5) + '...';
			}
			
			$('div#broadband_availability h3').text("Broadband for " + broadband_location);
			
			// map loaded
			loaded = true;

			// center the map on users marker/location (might already be done by update_map_location)
			//map.checkResize();
			//map.setCenter(new GLatLng(user_latlng.x, user_latlng.long), zoomLevel);
		
		} else {
		
			// center the map on point & apply zoom level
			map.checkResize();
			map.setCenter(point, zoomLevel);
		
		}
	
	}

	return false;

}

// shows postcode on map
function showPostcodeOnMap(point) {

	// default zoom level
	var zoomLevel = 16;
			
	// center the map on point & apply zoom level
	map.checkResize();
	map.setCenter(point, zoomLevel);
	
	// only do this is the map not been loaded before
	if(!loaded) {
		
		// change location text (only on results page)
		if(user_data) {
		
			// update broadband availability
			broadband_location = $("fieldset#map_location input[type='text']").val().toUpperCase();
			$('div#broadband_availability h3').text("Broadband for " + broadband_location);

		}
		
		// map loaded
		loaded = true;
	
	}

}

// location switcher
$("fieldset#map_location input[type='submit']").click(function(){
	var address = $("fieldset#map_location input[type='text']").val();
	
	// standalone speedmaps page only
	if(window.location.href.indexOf("streetstats") > 1) {
	
		// update url
		url_place = address.toLowerCase();
		update_url();
		
	}
	
	// valid uk postcode
	if(address.match(/[A-Za-z]{1,2}\d[A-Za-z\d]? ?\d[A-Za-z]{2}/)) {
		// slightly delay updating map as webkit prefers this
		setTimeout(function(){ get_postcode_location(address, showPostcodeOnMap); }, 500);
	
	// search for location
	} else {
		// slightly delay updating map as webkit prefers this
		setTimeout(function(){ geocoder.getLocations(address, showAddressOnMap); }, 500);

	}
	
	return false;
	
});

// speed switcher
$("fieldset#map_speed input").click(function(){

	// update speed so that MarkerClusterer knows which speed to show when it redraws
	speed = $(this).val();
	
	// standalone speedmaps page only
	if(window.location.href.indexOf("streetstats") > 1) {
	
		// update url
		url_speed = speed.replace(/_.*$/, '').toLowerCase();
		update_url();

	}
	
	// toggle which speed to show
	$("div.LabeledMarker_markerLabel p").hide();
	$("div.LabeledMarker_markerLabel p." + speed).show();

});

// add/remove marker
$("p.user_marker a").live("click", function(){
	
	var rel = $(this).attr("rel");
	var visibility = false;
	
	if(rel == 'remove') {
		
		u_marker.hide();
		
		$(this).parent().html('You have been removed from the map. <a href="#" rel="add">Undo</a>');
		
		visibility = '0';
		
	} else {
		
		u_marker.show();
		
		$(this).parent().html('<a href="#" rel="remove">Remove yourself from the map</a>');
		
		visibility = '1';
		
	}
	
	$.ajax({
		type: "POST",
		url: channel_url+"/_ajax/speedtest.php",
		data: "action=visibility&id=" + user_data.test_id + "&value=" + visibility,
		success: function() {},
		error: function(){}
	});
	
	return false;

});

// Speedmap promo on comparison clicked
$(".speedmap_promo a").click(function(){

	$("ul#results_nav li.results_streetstats a").click();
	
	return false;

});

// Speedmap link clicked
$("ul#results_nav li.results_streetstats a").click(function(){

	// only do this is the map not been loaded before
	if(!loaded) {

		// update user speed
		$('.user_rating .download_speed').text(down_speed + 'Mb');
		$('.user_rating .upload_speed').text(up_speed + 'Mb');

		// add location onto map
		$('input[name=location]').val(user_data.postcode).addClass('blur');
		
		// center map on location
		$("fieldset#map_location input[type='submit']").click();
		
		// load map data
		load_map(map,url);
	
	}
	
	// redraw map otherwise it does a partial draw
	// running the resize straight away doesn't work, so we have to delay slightly
	setTimeout(function(){ map.checkResize(); }, 100);
	
	return false;

});

// custom controls etc
function customise_map(map) {

	// Set min/max zoom levels
	G_NORMAL_MAP.getMinimumResolution = function () { return 12 };
	G_NORMAL_MAP.getMaximumResolution = function () { return 16 };
	
	// Setup pan custom controls
	function PanControl() {}
	PanControl.prototype = new GControl();
	PanControl.prototype.initialize = function(map) {
		var panContainer = document.createElement("div");
		panContainer.className = "panControls";
	
		var panLeftDiv = document.createElement("div");
		panLeftDiv.className = "panLeft";
		panContainer.appendChild(panLeftDiv);
		GEvent.addDomListener(panLeftDiv, "click", function() {
			map.panDirection(1,0);
		});
		
		var panRightDiv = document.createElement("div");
		panRightDiv.className = "panRight";
		panContainer.appendChild(panRightDiv);
		GEvent.addDomListener(panRightDiv, "click", function() {
			map.panDirection(-1,0);
		});
		
		var panUpDiv = document.createElement("div");
		panUpDiv.className = "panUp";
		panContainer.appendChild(panUpDiv);
		GEvent.addDomListener(panUpDiv, "click", function() {
			map.panDirection(0,1);
		});
		
		var panDownDiv = document.createElement("div");
		panDownDiv.className = "panDown";
		panContainer.appendChild(panDownDiv);
		GEvent.addDomListener(panDownDiv, "click", function() {
			map.panDirection(0,-1);
		});
	
		map.getContainer().appendChild(panContainer);
		return panContainer;
	}
	PanControl.prototype.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 50));
	}
	
	// Setup zoom custom controls
	function ZoomControl() {}
	ZoomControl.prototype = new GControl();
	ZoomControl.prototype.initialize = function(map) {
		var zoomContainer = document.createElement("div");
	
		var zoomInDiv = document.createElement("div");
		zoomInDiv.className = "zoomIn";
		zoomContainer.appendChild(zoomInDiv);
		GEvent.addDomListener(zoomInDiv, "click", function() {
			map.zoomIn();
		});
		
		var zoomOutDiv = document.createElement("div");
		zoomOutDiv.className = "zoomOut";
		zoomContainer.appendChild(zoomOutDiv);
		GEvent.addDomListener(zoomOutDiv, "click", function() {
			map.zoomOut();
		});
	
		map.getContainer().appendChild(zoomContainer);
		return zoomContainer;
	}
	ZoomControl.prototype.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(17, 110));
	}
	
	// Enable zooming on map
	map.enableScrollWheelZoom();
	
	// Add custom controls
	map.addControl(new PanControl());
	map.addControl(new ZoomControl());
	
	// Remove map types
	map.removeMapType(G_HYBRID_MAP);
	map.removeMapType(G_PHYSICAL_MAP );
	map.removeMapType(G_SATELLITE_MAP);
	
	// Custom Marker Icon
	var icon = new GIcon(G_DEFAULT_ICON);
	icon.image = $.image({src: '/_img/broadband/speedtest_new/map_marker.png',width: 81,height: 88,depth: 32, notag: true});
	icon.iconSize = new GSize(81, 88);
	icon.shadowSize = new GSize(0, 0);
	icon.iconAnchor = new GPoint(45, 75); // needs to be half width of the image and full height

	// load data as map moves
	GEvent.addListener(map, "moveend", function(){
		
		// time
		new_time = new Date().getTime();
		time_difference = new_time - old_time;
	
		// update old time
		old_time = new_time;
	
		// only update map if there has been 350 hundreths of a second between moves
		if(time_difference > 350) {
	
			// get new point
			lat_long = map.getCenter();
			
			// get zoom
			zoomLevel = map.getZoom();
			
			// generate URL
			url = generate_url();
			
			// load map
			load_map(map,url);
		
			// reset viewport
			marker_cluster.resetViewport();
		
		}
	
	});

	// make sure any info bubbles stay above all other markers as Google redraws zIndex
	GEvent.addListener(map, "move", function(){
	
		$('.bubble_info').parent().css('z-index', z_index_count + 1);
	
	});

	// fade zoom buttons depending on level of zoom
	GEvent.addListener(map, "zoomend", function(oldLevel, newLevel) {
	
		// min & max zoom levels
		var minResolution = G_NORMAL_MAP.getMinimumResolution();
		var maxResolution = G_NORMAL_MAP.getMaximumResolution();
	
		// figure out range for speed test api
		if(newLevel == 16) {
			limit = 25;
		} else if(newLevel == 15) {
			limit = 50;
		} else if(newLevel == 14) {
			limit = 75;
		} else if(newLevel == 13) {
			limit = 100;
		} else if(newLevel == 12) {
			limit = 125;
		}
        

	
		zoomLevel = newLevel;
	
		// hide exchanges if zoomed too far out
		if(newLevel >= 15) {
			$('div.exchange').add( $('div.exchange').prev() ).show();
		} else {
			$('div.exchange').add( $('div.exchange').prev() ).hide();
		}
	
		// figure out which zoom controls to enable/disable
		if(newLevel==minResolution) {
			$("div.zoomOut").fadeTo("normal", 0.4).css("cursor","default");
		}
		if(newLevel>minResolution) {
			$("div.zoomOut").fadeTo("normal", 1).css("cursor","pointer");
		}
		if(newLevel==maxResolution) {
			$("div.zoomIn").fadeTo("normal", 0.4).css("cursor","default");
		}
		if(newLevel<maxResolution) {
			$("div.zoomIn").fadeTo("normal", 1).css("cursor","pointer");
		}
		
		// first load, get data for users location
		if(user_latlng) {
			lat_long = new GLatLng(user_latlng.y, user_latlng.x);
		}
		
		// generate URL
		url = generate_url();

		// load map
		load_map(map,url);
		
		// make sure any info bubbles on top still as Google redraws zIndex
		$('.bubble_info').remove();
		
		// reset viewport
		marker_cluster.resetViewport();
		
	});
	
	// exclude IE6 as it can't handle multiple classes
	if (!$.browser.msie || $.browser.msie && $.browser.version > 6) {
	
		// hover & active states
		$('.panControls, .zoomIn, .zoomOut').mouseover(function(){
		
			$(this).addClass('hover');
		
		}).mouseout(function(){
		
			$(this).removeClass('hover');
		
		});
		$('.panControls, .zoomIn, .zoomOut').mousedown(function(){
		
			$(this).addClass('focus');
		
		}).mouseup(function(){
		
			$(this).removeClass('focus');
		
		});
	
	};

}

function get_postcode_location(postcode, callbackFunction) {
	
	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);

			// update user location if speedtest completed
			if(user_data) {

				user_data.location_data.long = resultLng;
				user_data.location_data.lat = resultLat;
			
			}
			
			postcode_location = localSearch.results[0];
			
			callbackFunction(point);
			
			// don't do this if first time loaded
			if(window.location.hash != initial_hash || window.location.href.indexOf("streetstats") == -1) {
			
				// hide welcome box
				$('#welcome_box').fadeOutSlide();

			}
			
		} else {
			// don't do this if first time loaded
			if(window.location.hash != initial_hash || window.location.href.indexOf("streetstats") == -1) {
			
				// update welcome box with error message
				$('#welcome_box')
				.addClass('error')
				.find('h2')
				.html('<em></em> Error')
				.end()
				.find('p:first')
				.text($('#map_location input:text').val() + " " + STREETSTATS_LOCATION_NOT_FOUND)
				.end()
				.find('p:last')
				.text('Example: London, England')
				.end()
				.fadeInSlide();
				
				// track in analytics
//				pageTracker._trackPageview("/speedtest/streetstats/error/postcode_not_found/" + $('#map_location input:text').val());

			}
			
		}
		
		
	});
	
	localSearch.execute(postcode + ", UK");
}

// Used for showing text inside an input instead of label
$.fn.hint = function() {
	return this.each(function(){
	
		var t = $(this); // get jQuery version of 'this'
		
		if (t.attr('title')) { // only apply logic if the element has the attribute
			
			// on focus, set value to blank if current value matches title attr
			t.focus(function(){
				if (t.val() == t.attr('title')) {
					t.val('');
					t.addClass('blur');
				}
			})

			// on blur, set value to title attr if text is blank
			t.blur(function(){
				if (t.val() == '') {
					t.val(t.attr('title'));
					t.removeClass('blur');
				}
			})

			// now change all inputs to title
			t.blur();
		}
		
	})
}

// Apply hint function to inputs
$('input.hint').hint();

// Update lat/long of users marker
function update_users_location() {
		user_latlng = new GLatLng(postcode_location.lat, postcode_location.lng);
		
		// add user marker
		//if(!user_plotted) {
		//	addUserMarker(icon,marker_cluster,true);
		//	user_plotted = true;
		//}
		
		// save lat/long
		if (user_data.test_id) {
			$.ajax({
				type: "POST",
				url: channel_url+"/_ajax/speedtest.php",
				data: "action=update&id=" + user_data.test_id + "&lat=" + user_latlng.y + "&long=" + user_latlng.x,
				success: function() {},
				error: function(){}
			});
		}
}

$('#end_of_setup a.start_big_button').click(function(){

	// add user marker
	addUserMarker(icon,marker_cluster,true);
	user_plotted = true;

});

$.fn.addOverlay = function() {
$(this).append('<div class="loading_overlay"><span class="loading_large"><span class="sifr">'+$.image({src: '/_img/broadband/speedtest_new/spinner_big.gif',width: 32,height: 32,alt: 'Loading',depth: 32})+' Loading...</span></span></div>');
}

$.fn.providerFancybox = function () {
		$(this).fancybox({
			'width':870,
			'height':625,
			'onComplete': function(){

				// Call row_highlight1 hover function from fancyboxHack.js
				hoverPopUpTable()

			},
			'onCleanup': function(){$('#fancybox-inner').empty();$('#products table').stickyheader();}
		})/*fancybox*/
};

$.fn.fadeInSlide = function () {

	$(this).animate({
		opacity: "show",
		top: '-=40px'
	},'fast');

};

$.fn.fadeOutSlide = function () {

	$(this).animate({
		top: '+=40px',
		opacity: "hide"
	},'fast');

}

function load_filters(){

	var value = 0;
	$('#current_value').text('Any');

	// initiate slider
	$('#slider').slider({
		animate: false,
		step: 2,
		min: 0,
		orientation: 'horizontal',
		max: 20,
		value: value,
		range: 'min',
		start: function(event, ui){
			slide_int = setInterval(update_slider, 10);	
		},
		slide: function(event, ui){
			setTimeout(update_slider, 10);  
		},
		stop: function(event, ui){
		
			clearInterval(slide_int);

			update_url();
			
			// clear previous markers
			marker_cluster.clearMarkers();
			existing_markers = {}
			
			url_speed_value = $('#slider').slider('option', 'value');
			
			// generate URL
			url = generate_url();
			
			// load map
			load_map(map,url);
			
			// reset viewport
			marker_cluster.resetViewport();
			
		}
	});
	
	// hide filters
	$('.hide_filters').click(function(){
	
		$('.filters_on').slideUp('fast', function(){
			$('.filters_off').css('z-index','1').fadeTo('fast', 1);
		});
		
		return false;
	
	});
	
	// show filters
	$('.show_filters').click(function(){
	
		$('.filters_off').css('z-index','-1').fadeTo('fast', 0, function(){
			$('.filters_on').slideDown('fast');
		});
	
		return false;
	
	});
	
	// handle reset of filters
	$('.reset_filters').click(function(){
		return false;
	});
	
	// handle changes to select boxes
	$('.filters_on select').change(function(){
		
		// clear previous markers
		marker_cluster.clearMarkers();
		existing_markers = {}
		
		// get which select box has changed
		select_box = $(this).attr('id');
		
		// handle exchange switching
		if(select_box == 'url_exchange') {
		
			url_exchange = $(this).val();
		
		// handle provider switching
		} else if(select_box == 'url_provider') {
		
			url_provider = $(this).val();
		
		// handle time switching
		} else if(select_box == 'url_time') {
		
			url_time = $(this).val();
			
		}

		update_url();
		
		// generate URL
		url = generate_url();
			
		// load map
		load_map(map,url);
			
		// reset viewport
		marker_cluster.resetViewport();
		
		return false;
		
	});

	// handle change for provider detection
	$('#url_verified').click(function(){
		
		// clear previous markers
		marker_cluster.clearMarkers();
		existing_markers = {}
		
		// figure out whether or not to limit to verified providers only
		if( $(this).is(':checked') ) {
			url_verified = 1;
		} else {
			url_verified = 0;
		}

		update_url();
		
		// generate URL
		url = generate_url();
			
		// load map
		load_map(map,url);
			
		// reset viewport
		marker_cluster.resetViewport();
		
	});

}

function update_filter_text() {

	url_exchange_text = $('#url_exchange option[value=' + url_exchange + ']').text();
	
	if(url_exchange_text != 'All Exchanges') {
	
		$('.single_exchange').show();
	
		// strip characters if too long
		if(url_exchange_text.length > 12) {
			url_exchange_text = url_exchange_text.substring(0,9) + '...';
		}
	
	} else {
	
		$('.single_exchange').hide();
	
	}
	
	$('em.exchange').text( url_exchange_text );

	url_provider_text = $('#url_provider option[value=' + url_provider + ']').text();
	
	if(url_provider_text != 'All Providers') {
	
		// strip characters if too long
		if(url_provider_text.length > 12) {
			url_provider_text = url_provider_text.substring(0,9) + '...';
		}

	}
		
	$('em.provider').text( url_provider_text );
		
	$('em.date_range').text( $('#url_time option[value=' + url_time + ']').text() );

}

// update the slider value
function update_slider(){
    var value = $('#slider').slider('option', 'value');
	url_speed_value = value;
	
	if(value == 0) {
		$('#current_value, em.speed').text('Any');
	} else {
		$('#current_value, em.speed').text(value + 'Mb');
	}
}

// generate the ajax url
function generate_url() {
    var bounds = map.getBounds();
    var ne     = bounds.getNorthEast();
    var sw     = bounds.getSouthWest();
    
	generated_url = 'http://'+streetstats_host+'/_ajax/speedtest.php/?action=map&type=' + url_type + '&lat=' + lat_long.y + '&long=' + lat_long.x +  '&limit=' + limit
	
    generated_url+= '&bounds_ne_lat='+ne.lat()+'&bounds_ne_lng='+ne.lng();
    generated_url+= '&bounds_sw_lat='+sw.lat()+'&bounds_sw_lng='+sw.lng();
    
    
    
	if(url_speed_value) {
		generated_url += '&speed=' + url_speed_value
	}
	if(url_exchange != 'all') {
		generated_url += '&exchange=' + url_exchange
	}
	if(url_provider != 'all') {
		generated_url += '&provider=' + url_provider
	}

	generated_url += '&time=' + url_time + '&verified=' + url_verified
	return generated_url

}

$(document).ready(function() {
	
	// close welcome box
	$('.close_welcome_box').click(function(){
		$('#welcome_box').fadeOutSlide();
	});
	
	// close bubble info popup
	$('.bubble_info .close_window').live('click', function() {
	
		// redraw last marker to have a bubble so its z-index is set correctly
		if(bubble_marker.div_) { bubble_marker.redraw(true); }
	
		image = $.asset({src:$(bubble_marker.div_).prev().attr('src').replace('_hover',''),notag:true});
		
		$(bubble_marker.div_).prev().attr('src',image);
	
		// show any hidden markers
		$('.temp_hidden').show();
	
		// remove bubble
		$(this).parent().remove();
	
	});
	
	// click handlers for fancybox table
	$('a.provider_table').live('click', function() {
		return false;
	});
	
	// stops IE from submitting the form & refreshing page
	$("#map_location input:text").keypress(function (e) {
		if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
			$(this).parent().find('input:submit').click();
			return false;
		} else {  
			return true; 
		}
	});

});
