var markers_done = false;
var data_in_progress = false;
var loop_detection = 0;
var markers = [];
var popups = [];
var images = [];
var map = null;
var data = [];
var refresh_timer;
var mapStyle = [ 
	{ featureType: "road", elementType: "all", stylers: [ { visibility: "off" } ] },
	{ featureType: "all", elementType: "all", stylers: [ { lightness: 40 } ] },
	{ featureType: "administrative.locality", elementType: "all", stylers: [ { lightness: -20 } ] },
	{ featureType: "administrative.province", elementType: "labels", stylers: [ { visibility: "off" } ] },
	{ featureType: "administrative.country", elementType: "labels", stylers: [ { visibility: "off" } ] },
	{ featureType: "water", elementType: "labels", stylers: [ { visibility: "off" } ] }
];

var config_lat;
var config_long;
var config_zoom;
var config_marker_type;
var config_period;
var config_period_count;

function changeConfigLatLongZoom(lat, long, zoom) {
	config_lat = lat;
	config_long = long;
	config_zoom = zoom;
	reCenterMap();
}

function changeConfigMarkerType(marker_type) {
	config_marker_type = marker_type;
	displayMarkers();
}

function changeTimePeriod(period, period_count) {
	config_period = period;
	config_period_count = Math.abs(parseInt(period_count) || 0);
	getWeatherData();
}

function setupMap(lat, long, zoom, marker_type, period, period_count) {
	config_lat = lat;
	config_long = long;
	config_zoom = zoom;
	config_marker_type = marker_type;
	config_period = period;
	config_period_count = period_count;

	var center = new google.maps.LatLng(config_lat, config_long);
	var mapOptions = {
      		name: "WeatherStats",
		center: center,
		zoom: config_zoom,
		mapTypeControl: false,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		navigationControl: true,
		navigationControlOptions: {
			style: google.maps.NavigationControlStyle.SMALL
		},
		maxZoom: 8,
		minZoom: 3
	}
        map = new google.maps.Map(document.getElementById("map"), mapOptions);
	var dimmedMap = new google.maps.StyledMapType(mapStyle, mapOptions);
	map.mapTypes.set('weatherstats', dimmedMap);
	map.setMapTypeId('weatherstats');
	getWeatherData();
	fetchData ("/config.json", null, setupWeatherMarkers);

	google.maps.event.addListener(map, 'zoom_changed', function() {
    		displayMarkers();
	});
}

function getWeatherData() {
	// stop any refresh timers

	if (data_in_progress) {
		alert ("Still loading your last request; go away!");
		return;
	}

	data_in_progress = true;

	clearTimeout(refresh_timer);

	// ok, get the data now
	if (config_period_count != 0) {
		fetchData ("/data.json?period=" + config_period + ';count=' + config_period_count, null, setupWeatherData);
	} else {
		fetchData ("/data.json", null, setupWeatherData);
	}
}

function reCenterMap() {
	map.setCenter(new google.maps.LatLng(config_lat, config_long));
	map.setZoom(config_zoom);
}

function displayMarkers() {
	var cities = data["config"].city;

	var zoomLevel = map.getZoom();
	for (var i in markers) {
		var zoom = cities[i].zoom;
		if ((zoomLevel >= zoom) && (images[config_marker_type][i])) {
			markers[i].setIcon(images[config_marker_type][i]);
			markers[i].setVisible(true);
		} else {
			markers[i].setVisible(false);
		}
	}
}

function setupWeatherData() {
	if (loop_detection > 1000) {
		// taking too long, abort
		alert ('error loading data');
		return;
	}
	if (! markers_done) {
		// can't do this yet, wait a bit
		loop_detection++;
		setTimeout(setupWeatherData, 10);
		return;
	}

	// markers are done, let's proceed

	var cities = data["config"].city;
	var wcities = data["weather"].city;

	images.conditions = [];
	images.warning = [];
	images.temperature = [];
	images.windchill = [];
	images.humidex = [];
	images.health_index = [];
	images.sunrise = [];
	images.sunset = [];

	for (var i in cities) {
		var name = cities[i].name;
		var short_name = cities[i].short_name;
		var conditions = wcities[i].conditions;
		var warning = wcities[i].warning;
		var temperature = wcities[i].temperature;
		var windchill = wcities[i].windchill;
		var humidex = wcities[i].humidex;
		var health_index = wcities[i].health_index;
		var icon = wcities[i].icon;
		var sunrise_icon = wcities[i].sunrise_icon;
		var sunset_icon = wcities[i].sunset_icon;
		var sunrise = wcities[i].sunrise;
		var sunset = wcities[i].sunset;

		// ---------- conditions icon

		images.conditions[i] = new google.maps.MarkerImage("/images/" + icon + ".gif",
			new google.maps.Size(32, 32),
			null,
			null,
			new google.maps.Size(32, 32)
		);

		// ---------- warning icon

		var warning_icon = warning ? "warning-warning-100" : "warning-check-100";
		createStandardIcon(i, 'warning', "/images/" + warning_icon + ".png", 1);

		// ---------- temperature/humidex/windchill icon

		var prefix = 'n';
		if (warning) {
			prefix = 'w';
		}
		createStandardIcon(i, 'temperature', "/images/temperature/" + prefix + parseInt(temperature) + ".png", temperature);

		if (windchill) {
			createStandardIcon(i, 'windchill', "/images/temperature/" + prefix + parseInt(windchill) + ".png", windchill);
		} else {
			createStandardIcon(i, 'windchill', "/images/temperature/" + prefix + 'x' + parseInt(temperature) + ".png", temperature);
		}
		if (humidex) {
			createStandardIcon(i, 'humidex', "/images/temperature/" + prefix + parseInt(humidex) + ".png", humidex);
		} else {
			createStandardIcon(i, 'humidex', "/images/temperature/" + prefix + 'x' + parseInt(temperature) + ".png", temperature);
		}

		// ---------- health_index

		createStandardIcon(i, 'health_index', "/images/health_index/" + 'n' + parseInt(health_index) + ".png", health_index);

		// ---------- sunrise/sunset

		createStandardIcon(i, 'sunrise', "/images/clock/" + sunrise_icon + ".png", sunrise_icon);
		createStandardIcon(i, 'sunset',  "/images/clock/" + sunset_icon  + ".png", sunset_icon);

		// ---------- popup window

	        var popup = "<TABLE BORDER=0><TR VALIGN=TOP><TD><B>" + name + "</B>";
		//	+ "&nbsp; &nbsp; [<A TARGET=_top HREF=" + url + ">Go</A>]"
		if (null != conditions) {
			popup += "<BR>" + conditions;
		}
		if (null != warning) {
			popup += "<BR><B>" + warning + "</B>";
		}
		if (null != temperature) {
			popup += "<BR>Temperature: " + temperature + "&deg;C";
		}
		if (null != windchill) {
			popup += "<BR>Windchill: " + windchill;
		}
		if (null != humidex) {
			popup += "<BR>Humidex: " + humidex;
		}
		if (null != sunrise) {
			popup += "<BR>Sunrise: " + sunrise;
		}
		if (null != sunset) {
			popup += "<BR>Sunset: " + sunset;
		}
		popup += "</TD><TD>";
	        if ((null != icon) && ("unknown" != icon)) {
	          popup += "<IMG SRC=/images/" + icon + ".gif WIDTH=80 HEIGHT=75 ALT=''>";
	        }
		popup += "</TD></TR></TABLE>";

		popups[i].setContent(popup);
	}

	displayMarkers();

	// keep reloading the data in case it changes, every 2 min
	refresh_timer = setTimeout(getWeatherData, 2 * 60000);
	data_in_progress = false;
}

function createStandardIcon(i, marker_type, url, value) {
	if (value) {
		images[marker_type][i] = new google.maps.MarkerImage(url,
			new google.maps.Size(30, 30),
			null,
			null,
			new google.maps.Size(30, 30)
		);
	} else {
		images[marker_type][i] = null;
	}
}

function setupWeatherMarkers() {
	var cities = data["config"].city;

	for (var i in cities) {
		var name = cities[i].name;
		var short_name = cities[i].short_name;
		var url = "http://" + short_name + ".weatherstats.ca/";

		var point = new google.maps.LatLng(cities[i].latitude, cities[i].longitude);

		var marker = new google.maps.Marker({
			position: point,
			map: map,
			title: name,
			visible: false,
			clickable: true
			});
		markers[i] = marker;

		createMarkerEvents (i, marker, url);
	}

	// let the data thread run now
	markers_done = true;
}

function createMarkerEvents (i, marker, url) {
	var infowindow = new google.maps.InfoWindow({
	});
	google.maps.event.addListener(marker, 'mouseover', function() {
		infowindow.open(map, marker);
	});
	google.maps.event.addListener(marker, 'mouseout', function() {
		infowindow.close(map, marker);
	});
	google.maps.event.addListener(marker, 'click', function() {
		top.document.location = url;
	});
	popups[i] = infowindow;
}
