var quakes = [];
var quakeIds = {};
var quakesToShow = 20;
var quakeCallbackURL = 'quakes.php';
var Earthquake = {
	map: null,
	markers: [],
	infoWindow: null
}

function timeDelta(datetime)
{
	var delta = (new Date).getTime();
	
	if (delta < datetime.getTime()) {
		return "zero seconds";
	}
	var ms = delta - datetime.getTime();
	
	var weeks = Math.floor(ms / (1000 * 60 * 60 * 24 * 7));
	ms -= weeks * (1000 * 60 * 60 * 24 * 7);
	
	var days = Math.floor(ms / (1000 * 60 * 60 * 24)); 
	ms -= days * (1000 * 60 * 60 * 24);

	var hours = Math.floor(ms / (1000 * 60 * 60)); 
	ms -= hours * (1000 * 60 * 60);

	var mins = Math.floor(ms / (1000 * 60)); 
	ms -= mins * (1000 * 60);

	secs = Math.floor(ms / 1000); 
	ms -= secs * 1000;
	
	var toRet = "";
	
	if (weeks > 0) {
		toRet += (toRet.length > 0 ? ", " : "") + weeks
					+ " week" + (weeks > 1 ? "s" : "");
	}
	if (days > 0) {
		toRet += (toRet.length > 0 ? ", " : "") + days
					+ " day" + (days > 1 ? "s" : "");
	}
	if (hours > 0) {
		toRet += (toRet.length > 0 ? ", " : "") + hours
					+ " hour" + (hours > 1 ? "s" : "");
	}
	if (mins > 0) {
		toRet += (toRet.length > 0 ? ", " : "") + mins
					+ " minute" + (mins > 1 ? "s" : "");
	}
	
	return toRet;
}


/*****************************************************************************
 * Callbacks
 */

Earthquake.closeInfoWindow = function() {
	Earthquake.infoWindow.close();
};

Earthquake.openInfoWindow = function(marker, quake) {
	var date = new Date(quake.time_occurrence);
	Earthquake.infoWindow.setContent('<div class="info-header">Near '+quake.region+'</div>'+
			'<table class="info-desc">'+
				'<tr><td class="info-desc-key">Occurred at:</td><td class="info-desc-val">'+date.toString()+'</td></tr>'+
				'<tr><td class="info-desc-key">Occured:</td><td class="info-desc-val">'+timeDelta(date)+' ago</td></tr>'+
				'<tr><td class="info-desc-key">Magnitude:</td><td class="info-desc-val">'+quake.mag+'</td></tr>'+
				'<tr><td class="info-desc-key">Depth:</td><td class="info-desc-val">'+quake.depth+'</td></tr>'+
			'</table>'
	);
	Earthquake.infoWindow.open(Earthquake.map, marker);
};

function handleError(errorMsg)
{
	// TODO
	console.error(errorMsg);
}

function handleAjaxError(request, textStatus, errorThrown)
{
	handleError(textStatus);
}

function drawQuake(quake, class)
{
	var date = new Date(quake.time_occurrence);
	
	//// Create the marker stuff
	// Create the marker
	var marker = new google.maps.Marker({
		position: new google.maps.LatLng(quake.lat, quake.lon),
		title: ''+quake.mag+' magnitude earthquake near '+quake.region
	});
	
	// Create the callbacks
	google.maps.event.addListener(marker, 'click', function() {
		Earthquake.openInfoWindow(marker, quake);
	});
	// Add to map
	marker.setMap(Earthquake.map);
	Earthquake.markers.push(marker);
	
	//// Create the row
	var header = $('<div>').addClass('row-header')
				.html('Magnitude '+quake.mag+' - near '+quake.region);
	var desc = $('<div>').addClass('row-desc')
				.html('Earthquake occured '+timeDelta(date)+' ago');
	// Create the dom object
	$('<div>').addClass('sidebar-row')
		.addClass(class)
		// Create the content in the div
		.append(header)
		.append(desc)
		// Create the callback
		.click(function() {
			var q = quake;
			
			// Show the marker on the map
			Earthquake.map.panTo(marker.getPosition());
			Earthquake.openInfoWindow(marker, q);
		})
		// Add to the table
		.appendTo('#sidebar');
}

function redrawQuakesList()
{
	console.log('Redraw quakes, choosing from '+quakes.length+' earthquakes.');
	
	//// Reset the display
	
	// Reset the sidebar
	$('#sidebar').empty();
	
	// Reset the map
	for (i in Earthquake.markers) {
		Earthquake.markers[i].setMap(null);
	}
	Earthquake.markers.length = 0;
	Earthquake.closeInfoWindow();
	
	//// Gather the filters
	// Magnitude low
	var mag_low = $("#magnitude-slider").slider("value");
	// Magnitude high
	// Since some time
	// Lat / Lng bounding box
	
	// Display the first quakesToShow earthquakes
	var i = 0, count = 0;
	while (count < quakesToShow && i < quakes.length) {
		var quake = quakes[i];
		
		if (quake.mag < mag_low) {
			i++;
			continue;
		}
		
		drawQuake(quake, (count % 2) == 0 ? 'even' : 'odd');
		
		count++;
		i++;
	}
}

function handleQuakesResponse(json)
{
	// Verify argument
	if (json.error) {
		// There was an error, so don't go on
		handleError(json.errorText);
		return false;
	}
	
	// Foreach new quake, parse it and put it into the quakes list
	for (var i in json.quakes) {
		var quake = json.quakes[i];
		
		if (quake.qid in quakeIds) {
			continue;
		} else {
			quakeIds[quake.qid] = quake.qid;
			quake.time_occurrence = parseInt(quake.time_occurrence) * 1000;
			quakes.push(quake);
		}
	}
	
	// Resort the quakes array
	quakes.sort(function(a, b) {
		if (a.time_occurrence > b.time_occurrence) {
			return -1;
		} else if (a.time_occurrence == b.time_occurrence) {
			return 0;
		} else {
			return 1;
		}
	});
	
	// Refresh the quakes list
	redrawQuakesList();
}

function requestQuakesByMagnitudeRange(mag_low, mag_high)
{
	$.ajax({url: quakeCallbackURL,
		dataType: 'json',
		data: { type: 'json', mag_low: mag_low, mag_high: mag_high },
		success: handleQuakesResponse,
		error: handleAjaxError
		}
	);
}

/*****************************************************************************
 * Initialization
 */
$(document).ready(function() {
	
	//// Initialize the UI Widgets
	// Init the magnitude slider
	$("#magnitude-slider").slider({
		range: "max",
		min: 0,
		max: 10,
		value: 1,
		step: .25,
		slide: function(event, ui) {
			// Update the magnitude display
			$("#magnitude-input").val(ui.value);
		},
		stop: function(event, ui) {
			console.log('slider.stop: ', ui.value)
			
			// Filter the list of quakes to display
			//redrawQuakesList();
			
			// Fire off a query for more quakes
			requestQuakesByMagnitudeRange(ui.value);
		}
	});
	$("#magnitude-input").val($("#magnitude-slider").slider("value"));
	
	//// Initialize the Map
	// Main map init
	var startCenter = new google.maps.LatLng(39.90973, -96.15234);
	var startOptions = {
		zoom: 3,
		center: startCenter,
		mapTypeId: google.maps.MapTypeId.SATELLITE
	};
	Earthquake.map = new google.maps.Map(document.getElementById("map-canvas"), startOptions);
	// Create the infowindow
	Earthquake.infoWindow = new google.maps.InfoWindow({
		disableAutoPan: true
	});
	google.maps.event.addListener(Earthquake.map, 'click', Earthquake.closeInfoWindow)
	
	//// Start the query for the earthquakes
	requestQuakesByMagnitudeRange($("#magnitude-slider").slider("value"));
});
