	$(document).ready(function() {

	var curselected = null
	
	/**
	 * Construct the javascript for keywordmatching.
	 * @param String matchertag the id of the span-element in which the matches should be displayed.
	 */
	function keywordSuggestionFactory(matchertag) {
		return function(e) {
			var suggestionTextField = this;
			var currentText = suggestionTextField.value;
			
			function hasSpecialSearchCharacters(input) {
				// starts-with('-') would mean not in lucene query speak
				if (input.search(/^-.*/) == 0) {
					return true;
				}
				return false;
			}
			
			function selectItem(newitem) {
				$(matchertag + ' ul li').removeClass('searchSuggestionhover')
				$(newitem).addClass('searchSuggestionhover')
				var newSearchText = $(newitem).text();
				if (hasSpecialSearchCharacters(newSearchText)) {
					// Quote the special text so that searches work
					newSearchText = '"' + newSearchText + '"';
				}
				suggestionTextField.value = newSearchText;
			}
						
			var keyup = 38
			var keydown = 40
			// if arrow down or arrow up, select item from dropdown
			if (e.which == keyup || e.which == keydown) {
				if (curselected == null) {
					curselected = $(matchertag + ' ul li:first')
					selectItem(curselected)
				} else {
					var newSelected = null
					if (e.which == keyup) {
						newSelected = curselected.prev();
					} else {
						newSelected = curselected.next();
					}
					if (newSelected.text() != '') {
						selectItem(newSelected, curselected)
						curselected = newSelected
					}
				}
			} else {
			
				if (currentText.length < 2) {
					$(matchertag).empty();
					$(matchertag).css('display', 'none');
					return;
				}
				
				var segments = currentText.split(',');
				var lastSegment = segments.length > 0 ? segments[segments.length-1] : segments[0];
				lastSegment = jQuery.trim(lastSegment);
				if (lastSegment.length < 1) {
					$(matchertag).empty();
					$(matchertag).css('display', 'none');
					return;
				}
				
				
				keywordService.findUniqueKeywordTextsByCaseInsensitivePrefix(lastSegment, function(data) {
					if (data != null && typeof data == 'object') {
						curselected = null
						var searchfield = $("#" + suggestionTextField.id)
						$(matchertag).css('left', searchfield.position().left)
						$(matchertag).css('top', searchfield.position().top + searchfield.outerHeight())
						$(matchertag).css('width', searchfield.outerWidth() - 2)
						
						$(matchertag).empty();
						var content = '<ul>';
						for (var i = 0; i < data.length; i++) {
							content += '<li class="_search_suggestion">' + data[i] + '</li>'
						}
						content += '</ul>';
						if (data.length == 0) {
							$(matchertag).css('display', 'none');
						} else {
							$(matchertag).css('display', 'block');
						}
						$(matchertag).append(content);
							
						
						$(matchertag + " ._search_suggestion").click(function() {
							if (segments.length > 0) {
								segments.pop();
							}
		
							suggestionTextField.value = $(this).text()
							$(matchertag).empty();
							$(matchertag).css('display', 'none');
						});
						
						
						$(matchertag + " ._search_suggestion").mouseenter(function() {
							// 'in'
							$(this).addClass('searchSuggestionhover')
						});
	
						
						$(matchertag + " ._search_suggestion").mouseleave(function() {
							// out
							$(this).removeClass('searchSuggestionhover')
						});
					} else {
						$(matchertag).css('display', 'none');
					}
				});
			}
		}
	}
	
	
	var searchSuggestionFunc = keywordSuggestionFactory("#searchtagMatches");
	$("#searchquery").keyup(searchSuggestionFunc)
});