function autocomplete(inp, obj, act) {
	/*the autocomplete function takes two arguments,
	the text field element and an objay of possible autocompleted values:*/
	var currentFocus;
	/*execute a function when someone writes in the text field:*/
	inp.addEventListener("input", function(e) {
		var a, b, i, val = this.value;
		/*close any already open lists of autocompleted values*/
		clearLists();
		document.querySelector(".md-google-search__empty-btn").style.display = (val ? "block" : "none");
		if (!val || val.length < 3) return false;
		currentFocus = -1;
		var is_empty = true;

		/*for each item in the object...*/
		for (node in obj) {
			var nomNode = obj[node].name;

			if (nomNode.toUpperCase().includes(val.toUpperCase())) {
				is_empty = false;
				var parts = nomNode.toUpperCase().split(val.toUpperCase());
				
				/*create a DIV element for each matching element:*/
				b = document.createElement("div");
				b.setAttribute("class", "autocomplete-item");

				/*make the matching letters bold:*/
				if (parts[0].length == 0) b.innerHTML = "";
				else b.innerHTML = "<span style='font-weight: bold; position:relative; z-index:120;'>" + nomNode.substr(0, parts[0].length) + "</span>";
				
				b.innerHTML += nomNode.substr(parts[0].length, val.length);
				b.innerHTML += "<span style='font-weight: bold; position:relative; z-index:120;'>" + nomNode.substr(parts[0].length + val.length) + "</span>";
				b.innerHTML += " <span class='autocomplete-year'>(" + obj[node].year + ")</span>";

				/*include node id to keep track of which is it*/
				b.dataset.id = node;

				/*execute a function when someone clicks on the item value (DIV element):*/
				b.addEventListener("click", function(e) {
					/*insert the value for the autocomplete text field:*/
					var n = this.dataset.id;
					inp.value = obj[n].name;

					switch (act) {
						case "search":
							// Move camera to desired node
							cameraGoto(obj[n].x, obj[n].y);
							break;
						case "addEdge":
							// @TODO: Add an edge between A and B
							alert(obj[n].name);
							break;
					}

					/*close the list of autocompleted values,
					(or any other open lists of autocompleted values:*/
					clearLists();
				});

				// Set "data-edges" attribute and compare with others
				var nEdges = Object.keys(s.graph.neighbors(node)).length;
				b.dataset.edges = nEdges;
				var inserted = false;

				// Sort nodes by degree
				for (i in document.querySelector("#autocomplete-list").childNodes) {
					var child = document.querySelector("#autocomplete-list").childNodes[i];
					if (!child.dataset) break;
					if (nEdges > child.dataset.edges) {
						document.querySelector("#autocomplete-list").insertBefore(b, child);
						inserted = true;
						break;
					}
				}

				if (!inserted) {
					document.querySelector("#autocomplete-list").appendChild(b);
				}
			}
		}

		document.querySelector(".autocomplete-container").style.display = (is_empty ? "none" : "block");
	});

	document.querySelector(".md-google-search__empty-btn").addEventListener("click", function() {
		document.querySelector("#search-input").value = "";
		this.style.display = "none";
	});

	/*execute a function presses a key on the keyboard:*/
	inp.addEventListener("keydown", function(e) {
		var x = document.getElementById("autocomplete-list");
		if (x) x = x.getElementsByTagName("div");
		if (x.length == 0) return;
		if (e.keyCode == 40) {
			/*If the objow DOWN key is pressed,
			increase the currentFocus variable:*/
			currentFocus++;
			/*and and make the current item more visible:*/
			addActive(x);
		} else if (e.keyCode == 38) { //up
			/*If the objow UP key is pressed,
			decrease the currentFocus variable:*/
			currentFocus--;
			/*and and make the current item more visible:*/
			addActive(x);
		} else if (e.keyCode == 13) {
			/*If the ENTER key is pressed, prevent the form from being submitted,*/
			e.preventDefault();
			if (currentFocus > -1) {
				/*and simulate a click on the "active" item:*/
				if (x) x[currentFocus].click();
			}
		}
	});
	function addActive(x) {
		/*a function to classify an item as "active":*/
		if (!x) return false;
		/*start by removing the "active" class on all items:*/
		removeActive(x);
		if (currentFocus >= x.length) currentFocus = 0;
		if (currentFocus < 0) currentFocus = (x.length - 1);
		/*add class "autocomplete-active":*/
		x[currentFocus].classList.add("autocomplete-active");
	}
	function removeActive(x) {
		/*a function to remove the "active" class from all autocomplete items:*/
		for (var i = 0; i < x.length; i++) {
			x[i].classList.remove("autocomplete-active");
		}
	}
	function clearLists() {
		/*close all autocomplete lists in the document,
		except the one passed as an argument:*/
		var x = document.querySelector("#autocomplete-list");
		x.innerHTML = "";
		document.querySelector(".autocomplete-container").style.display = "none";
	}
	/*execute a function when someone clicks in the document:*/
	document.addEventListener("click", function (e) {
		clearLists();
	});
}
