

var sidebar_collapse_time = 1000;
var collapse_sidebar_offset = -25;
var infolist_animation_duration = 1000;
var interactive_animation_duration = 400;
var infoelement_width = 200;
var infoelement_outerwidth = infoelement_width + 12;
var infobox_id = 'infobox-cebbf26ec16a845666bc1982e34bfc3df2f4f2dd';
var infotabs_id = 'infotabs-cebbf26ec16a845666bc1982e34bfc3df2f4f2dd';
var infoelement_class = 'infoelement-cebbf26ec16a845666bc1982e34bfc3df2f4f2dd';

function debug_log(text) {
	$('#debug').append($('<p></p>').text(text));
}

function handleResize() {
	if (map == null) return;
	var centre = map.getCenter();
	var zoom = map.getZoom();

	map.setCenter(centre, zoom);
}

function collapse_sidebar() {
	$('#sidebar').fadeOut(sidebar_collapse_time);
	$('#expand-sidebar-button').fadeIn(sidebar_collapse_time);
	$('#collapse-sidebar-button').fadeOut(sidebar_collapse_time);
	$('#right-pane').animate({left:0}, sidebar_collapse_time, function() {handleResize(); render_infolists();});
	$('#collapse-sidebar').animate({left:collapse_sidebar_offset+"px"}, sidebar_collapse_time);
	$('#expand-sidebar').animate({left:0}, sidebar_collapse_time);
}

function expand_sidebar() {
	sidebar = $('#sidebar');
	sidebar.fadeIn(sidebar_collapse_time);
	$('#expand-sidebar-button').fadeOut(sidebar_collapse_time);
	$('#collapse-sidebar-button').fadeIn(sidebar_collapse_time);
	$('#right-pane').animate({left: (sidebar.width()+sidebar.offset().left)+"px"}, sidebar_collapse_time, function() {handleResize(); render_infolists();});
	$('#collapse-sidebar').animate({left: (sidebar.width()+sidebar.offset().left+collapse_sidebar_offset)+"px"}, sidebar_collapse_time);
	$('#expand-sidebar').animate({left: (sidebar.width()+sidebar.offset().left)+"px"}, sidebar_collapse_time);
}

var infolist_none = { "category":"None", "infolist":new Array(), "infobox":false, "infotab":false };
var infolist_all = { "category":"All", "infolist":new Array(), "infobox":false, "infotab":false };
var infolists = new Array();
var info_marker = false;
var info_popup = false;
var info_popup_delay = false;

function show_info_pin(id) {
	var found = false;
	var icon;
	var popup_html;

	if (info_marker) {
		info_marker.destroy();
		info_marker = false;
	}
	if (info_popup) {
		info_popup.destroy();
		info_popup = false;
	}
	for (i in infolist_all.infolist) {
		if (infolist_all.infolist[i].id == id) {
			found = infolist_all.infolist[i];
			break;
		}
	}
	if (found == false) return;
	merc_coords = lonLatToMercator(new OpenLayers.LonLat(found.lon, found.lat));
	icon = new OpenLayers.Icon('OpenLayers/img/marker.png', new OpenLayers.Size(21,25), new OpenLayers.Pixel(-11, -25));
	info_marker = new OpenLayers.Marker(merc_coords, icon)
	markers_layer.addMarker(info_marker);
	
	var link_element = $('<a href="info_redirect?id='+escape(found.impression_id)+'" target="_blank"></a>').text(found.title);
	popup_html = $('<div></div>').append(link_element).html();
	if (found.html_description == "") {
		var description_element = $('<p></p>').text(found.description);
		popup_html += $('<div></div>').append(description_element).html();
	} else popup_html += "<p>"+found.html_description+"</p>";
	if (found.category != '') {
		var category_element = $('<p class="info_bubble_category"></p>').text("Category: "+found.category);
		popup_html += $('<div></div>').append(category_element).html();
	}

	info_popup = new OpenLayers.Popup.AnchoredBubble("info_bubble", merc_coords, new OpenLayers.Size(200, 200), popup_html, icon, true, function() {
		info_marker.destroy();
		info_marker = false;
		info_popup.destroy();
		info_popup = false;
	});
	info_popup.autoSize = true;
	info_popup.panMapIfOutOfView = true;
	var map_size = map.getSize();
	info_popup.maxSize = new OpenLayers.Size(map_size.w - 200, map_size.h - 100);

//	var centre = map.getCenter();
//	if ((centre.lon == merc_coords.lon) && (centre.lat == merc_coords.lat)) {
		map.addPopup(info_popup);
//	} else {
//		map.panTo(merc_coords);
//		info_popup_delay = true;
//	}
}

/*
 * Updates an infolist and returns an array of infolist elements to be deleted and the updated infolist.
 */
function update_info_list(new_infolist_data, infolist) {
	var deletionlist = new Array();
	var new_infolist = new Array();
	var new_infolist_element;
	var i;
	var j;
	var link_element;
	var title_element;
	var description_element;

	for (i in new_infolist_data) {
		// Transfer existing elements from infolist to new_infolist_data and create new ones
		new_infolist_element = {
			"id": new_infolist_data[i].id,
			"impression_id": new_infolist_data[i].impression_id,
			"title": new_infolist_data[i].title,
			"description": new_infolist_data[i].description,
			"html_description": new_infolist_data[i].html_description,
			"lon": new_infolist_data[i].lon,
			"lat": new_infolist_data[i].lat,
			"category": new_infolist_data[i].category,
			"element": false,
			"displayed": false
		}
		for (j in infolist.infolist) {
			if (new_infolist_element.id == infolist.infolist[j].id) {
				new_infolist_element.element = infolist.infolist[j].element;
				new_infolist_element.displayed = infolist.infolist[j].displayed;
				if (new_infolist_element.title != infolist.infolist[j].title) {
					new_infolist_element.element.children('.infotitle_link').text(new_infolist_element.title);
				}
				if (new_infolist_element.description != infolist.infolist[j].description) {
					new_infolist_element.element.children('.infodescription').text(new_infolist_element.description);
				}
				infolist.infolist[j] = false;
				break;
			}
		}
		if (! new_infolist_element.element) {
			// No existing element found - create a new one
			// link_element = $('<a class="infotitle_link" href="info_redirect?id='+escape(new_infolist_element.id)+'"</a>').text(new_infolist_element.title);
			link_element = $('<a class="infotitle_link" href="javascript:show_info_pin('+escape(new_infolist_element.id)+')"></a>').text(new_infolist_element.title);
			title_element = $('<p class="infotitle"></p>').append(link_element);
			description_element = $('<p class="infodescription"></p>').text(new_infolist_element.description);
			new_infolist_element.element = $('<div class="'+infoelement_class+'"></div>');
			new_infolist_element.element.append(title_element);
			new_infolist_element.element.append(description_element);
			// Add it to the DOM tree (hidden for now because display:none is set in the CSS)
			infolist.infobox.append(new_infolist_element.element);
		}
		new_infolist.push(new_infolist_element);
	}
	
	for (j in infolist.infolist) {
		// Add unused elements to the deletion list.  Any that are not
		// currently being displayed are simply removed from the DOM instead
		if (infolist.infolist[j]) {
			if (infolist.infolist[j].displayed) deletionlist.push(infolist.infolist[j]);
			else infolist.infolist[j].element.remove();
		}
	}
	return {
		"deletionlist":	deletionlist,
		"infolist":	new_infolist
	};
}

function remove_infolist_element(element) {
	element.element.fadeOut(infolist_animation_duration);
	element.displayed = false;
}

function render_infolist(infolist, force_display) {
	var total_width;
	var remaining_width;
	var i;
	var new_remaining_width;
	var left_offset;
	var i;
	var displayed_elements = 0;

	total_width = $('#'+infobox_id).innerWidth();
	remaining_width = total_width;
	for (i in infolist.infolist) {
		new_remaining_width = remaining_width - infoelement_outerwidth;
		if (new_remaining_width < 0) break;
		remaining_width = new_remaining_width;
	}
	left_offset = remaining_width / 2;
	for (i in infolist.infolist) {
		total_width -= infoelement_outerwidth;
		if (total_width >= 0) {
			if (infolist.infolist[i].displayed) {
				infolist.infolist[i].element.css('display', 'inline-block');
				infolist.infolist[i].element.animate({'left':left_offset+'px', 'opacity':1}, infolist_animation_duration)
			} else {
				infolist.infolist[i].displayed = true;
				infolist.infolist[i].element.css('left', left_offset+'px');
				infolist.infolist[i].element.css('display', 'inline-block');
				infolist.infolist[i].element.animate({'opacity':1}, infolist_animation_duration)
			}
			displayed_elements ++;
		} else if (infolist.infolist[i].displayed) remove_infolist_element(infolist.infolist[i]);
		left_offset += infoelement_outerwidth;
	}
	if ((displayed_elements > 0) || (force_display)) {
		infolist.infotab.css('display', 'inline-block');
		infolist.infotab.animate({'opacity':1}, infolist_animation_duration)
	} else infolist.infotab.fadeOut(infolist_animation_duration);
	return displayed_elements;
}

function render_deletion_list(deletion_list) {
	var i;

	for (i in deletion_list) {
		remove_infolist_element(deletion_list[i]);
	}
}

function select_info(infolist) {
	infolist.infobox.fadeIn_visibility(interactive_animation_duration);
	infolist.infotab.addClass('selected');
	if (infolist != infolist_none) {
		infolist_none.infobox.fadeOut_visibility(interactive_animation_duration);
		infolist_none.infotab.removeClass('selected');
	}
	if (infolist != infolist_all) {
		infolist_all.infobox.fadeOut_visibility(interactive_animation_duration);
		infolist_all.infotab.removeClass('selected');
	}
	for (i in infolists) {
		if (infolists[i] != infolist) {
			infolists[i].infobox.fadeOut_visibility(interactive_animation_duration);
			infolists[i].infotab.removeClass('selected');
		}
	}
}

function update_info_lists(new_infolist) {
	var i;
	var cat;
	var found_cat;
	var j;
	var subinfobox;
	var infotab;
	var results;
	var deletionlist;
	var cat_infolist;

	if (! infolist_none.infobox) {
		subinfobox = $('<div></div>');
		$('#'+infobox_id).append(subinfobox);
		infolist_none.infobox = subinfobox;
		infotab = $('<div onClick="select_info(infolist_none)"></div>').text(infolist_none.category);
		$('#'+infotabs_id).append(infotab);
		infolist_none.infotab = infotab;
	}
	if (! infolist_all.infobox) {
		subinfobox = $('<div></div>');
		$('#'+infobox_id).append(subinfobox);
		infolist_all.infobox = subinfobox;
		infotab = $('<div onClick="select_info(infolist_all)"></div>').text(infolist_all.category);
		$('#'+infotabs_id).append(infotab);
		infolist_all.infotab = infotab;
		select_info(infolist_all);
	}
	for (i in new_infolist) {
		cat = new_infolist[i].category;
		if (cat != '') {
			found_cat = false;
			for (j in infolists) {
				if ((infolists[j].category != '') && (infolists[j].category == cat)) {
					found_cat = true;
					break;
				}
			}
			if (! found_cat) {
				subinfobox = $('<div></div>');
				$('#'+infobox_id).append(subinfobox);
				infotab = $('<div onClick="select_info(infolists['+infolists.length+'])"></div>').text(cat);
				$('#'+infotabs_id).append(infotab);
				infolists.push({ "category":cat, "infolist":new Array(), "infobox":subinfobox, "infotab":infotab}) - 1;
			}
		}
	}
	results = update_info_list(new_infolist, infolist_all);
	infolist_all.infolist = results.infolist;
	deletionlist = results.deletionlist;
	
	for (i in infolists) {
		cat_infolist = new Array();

		for (j in new_infolist) {
			if (new_infolist[j].category == infolists[i].category) {
				cat_infolist.push(new_infolist[j]);
			}
		}
		results = update_info_list(cat_infolist, infolists[i]);
		infolists[i].infolist = results.infolist;
		deletionlist = deletionlist.concat(results.deletionlist);
	}
	
	return deletionlist;
}

function render_infolists() {
	var i;
	var displayed_elements;

	if (infolist_all.infobox) {
		displayed_elements = render_infolist(infolist_all, 0);
		render_infolist(infolist_none, displayed_elements > 0);
	}
	for (i in infolists) {
		render_infolist(infolists[i], 0);
	}
}

function info_update_callback(data, textstatus, xmlhttprequest) {
	var new_infolist = new Array();
	var i;
	var d;
	var infolist_element;
	var deletion_list;

	for (i in data.infoarray) {
		d = data.infoarray[i];
		infolist_element = {
			"id":			d.id,
			"impression_id":	d.impression_id,
			"title":		d.title,
			"description":		d.description,
			"html_description":	d.html_description,
			"category":		d.category,
			"lon":			d.lon,
			"lat":			d.lat
		};
		new_infolist.push(infolist_element);
	}
	deletion_list = update_info_lists(new_infolist);
	render_infolists();
	render_deletion_list(deletion_list);
	$('#locationtext').text(data.geolocation.display_name);
	$('#locationtext').fadeIn(interactive_animation_duration);
}

function ui_moveend_timeout() {
	var lonlat = mercatorToLonLat(map.getCenter());
	var zoom = map.getZoom();
	var extents = map.getExtent();
	var bounds_topleft = mercatorToLonLat({lon:extents.left, lat:extents.top});
	var bounds_bottomright = mercatorToLonLat({lon:extents.right, lat:extents.bottom});
	
	var data = {
		"lat":		lonlat.lat,
		"lon":		lonlat.lon,
		"left":		bounds_topleft.lon,
		"right":	bounds_bottomright.lon,
		"top": 		bounds_topleft.lat,
		"bottom":	bounds_bottomright.lat,
		"zoom":		zoom
	};
	$.get('info_update', data, info_update_callback, 'json');
}

var ui_moveend_timeout_handle = false;

function ui_moveend_event() {
	if ((info_popup_delay) && (info_popup != false)) map.addPopup(info_popup);
	if (ui_moveend_timeout_handle) clearTimeout(ui_moveend_timeout_handle);
	ui_moveend_timeout_handle = setTimeout(ui_moveend_timeout, 5000);
}

function ui_movestart_event() {
	$('#locationtext').fadeOut(interactive_animation_duration);
	if (ui_moveend_timeout_handle) clearTimeout(ui_moveend_timeout_handle);
	ui_moveend_timeout_handle = false;
}

function zoom_map_to_extents(minlat, maxlat, minlon, maxlon) {
	var topleft = lonLatToMercator(new OpenLayers.LonLat(minlon, maxlat));
	var bottomright = lonLatToMercator(new OpenLayers.LonLat(maxlon, minlat));
	var bounds = new OpenLayers.Bounds();
	bounds.extend(topleft);
	bounds.extend(bottomright);
	map.zoomToExtent(bounds);
	ui_moveend_timeout();
}

function search_callback(data, textstatus, xmlhttprequest) {
	var contentbox = $('#search-box-content');
	var result;
	var link;
	var list;
	var d;
	var cat;
	var decimals;
	var minlat;
	var minlon;
	var maxlat;
	var maxlon;
	
	contentbox.empty();
	if (data.length <= 0) {
		contentbox.append($("<p></p>").text("No results found."));
	} else {
		decimals = Math.pow(10, Math.floor(map.getZoom()/3));
		list = $("<ul></ul>");
		for (i in data) {
			d = data[i];
			cat = d.type.replace("_", " ");
			if (cat != "") cat = cat[0].toUpperCase() + cat.substr(1);
			result = $("<li></li>");
			result.text(cat+": ");
			link = $("<a></a>").text(d.display_name);
			minlat = Math.round(d.boundingbox[0] * decimals) / decimals;
			maxlat = Math.round(d.boundingbox[1] * decimals) / decimals;
			minlon = Math.round(d.boundingbox[2] * decimals) / decimals;
			maxlon = Math.round(d.boundingbox[3] * decimals) / decimals;
			link.attr("href", "?minlat="+escape(minlat)+"&maxlat="+escape(maxlat)+"&minlon="+escape(minlon)+"&maxlon="+escape(maxlon));
			link.attr("onclick", "close_search(); zoom_map_to_extents("+d.boundingbox[0]+","+d.boundingbox[1]+","+d.boundingbox[2]+","+d.boundingbox[3]+"); return false;");
			result.append(link);
			list.append(result);
		}
		contentbox.append(list);
	}
}

function search_submit() {
	var search_data;
	var searchbox;
	var contentbox;
	var fadecontent;
	var extents = map.getExtent();
	var bounds_topleft = mercatorToLonLat({lon:extents.left, lat:extents.top});
	var bounds_bottomright = mercatorToLonLat({lon:extents.right, lat:extents.bottom});

	search_data = $('#search').attr('value');
	http_patt = /^http(s?):\/\//i
	if (http_patt.test(search_data)) {
		param_patt = /[?]/
		if (param_patt.test(document.location)) delim = "&";
		else delim = "?";
		document.location += delim+"track="+search_data;
	} else if (search_data != "") {
		searchbox = $('#search-box');
		contentbox = $('#search-box-content');
		contentbox.empty();
		contentbox.append($("<p></p>").text("Searching for '"+search_data+"'..."));
		searchbox.fadeIn(interactive_animation_duration);
		var left = bounds_topleft.lon;
		var right = bounds_bottomright.lon;
		var top = bounds_topleft.lat;
		var bottom = bounds_bottomright.lat;
		var data = {
			"viewbox":	left+","+top+","+right+","+bottom,
			"q":		search_data
		};
		$.get('proxy_nominatim_search', data, search_callback, 'json');
	}
}

function close_search() {
	$('#search-box').fadeOut(interactive_animation_duration);
}

/*
 * jQuery extensions
 */
jQuery.fn.fadeIn_visibility = function(duration, callback) {
	this.css({"visibility":"visible"})
	this.animate({ "opacity":1 }, duration, callback);
}

jQuery.fn.fadeOut_visibility = function(duration, callback) {
	this.animate({ "opacity":0 }, duration, function() {
		$(this).css({"visibility":"hidden"});
		if (callback) callback();
	});
}


$(window).resize(function() {handleResize(); render_infolists();});



