// do not call this function 'autocomplete', because this is an IE attribute
function startAutocomplete(event, element, url)
{
	// if this function was called as a result of an attribute change,
	// it should be a value change
	if (event.propertyName && event.propertyName != 'value') {
		return;
	}

	var id = 'autocomplete_' + element.id;

	if (event && event.keyCode) {
		switch (event.keyCode) {
		case Event.KEY_DOWN:
			if ($(id)) {
				$(id).firstChild.className = 'active';
				$(id).firstChild.focus();
			}
			break;
		case Event.KEY_ESC:
			if ($(id)) {
				document.body.removeChild($(id));
			}
			break;
		}
	}

	if (!element.previousValue || (element.previousValue != element.value)) {

		element.previousValue = element.value;

		if (element.value.length < 2) {
			stopAutocomplete(element);
			return;
		}

		new Ajax.Request(
			url,
			{
				onSuccess: autocompleteSuccess,
				method: 'post',
				parameters: {search_string: element.value},
				element: element
			}
		);
	}
}

function stopAutocomplete(element)
{
	var id = 'autocomplete_' + element.id;
	if ($(id)) {
		document.body.removeChild($(id));
	}
}

function autocompleteSuccess(xml)
{
	var parameters = xml.request.parameters;
	var results = xml.responseXML.getElementsByTagName('result');
	var element = xml.request.options.element;

	var id = 'autocomplete_' + element.id;

	if ($(id)) {
		document.body.removeChild($(id));
	}
	if (results.length == 0) {
		return;
	} else if (results.length == 1) {
		// if the only result is the value already present, do not suggest it
		if (results[0].getElementsByTagName('value')[0].firstChild.nodeValue == element.value) {
			return;
		}
	}

	var dropdown = document.createElement('div');
	dropdown.setAttribute('id', id);
	dropdown.className = 'autocomplete_dropdown';
	dropdown.style.top = (element.cumulativeOffset().top + element.offsetHeight) + 'px';
	dropdown.style.left = element.cumulativeOffset().left + 'px';
	dropdown.style.minWidth = (element.offsetWidth) + 'px';

	for (var i = 0; i < results.length; i++) {
		var result = results[i];
		var valueNodes = result.getElementsByTagName('value');
		var titleNodes = result.getElementsByTagName('title');
		var value = (valueNodes.length > 0) ? valueNodes[0].firstChild.nodeValue : '';
		var title = (titleNodes.length > 0) ? titleNodes[0].firstChild.nodeValue : value;
		var link = new Element('a', {'href': '#'});
		link.appendChild(document.createTextNode(title));
		link.onclick = autocompletePick.curry(element.id, value, title);

		link.observe('keyup', function (event) {

			if (event.keyCode == Event.KEY_ESC) { // escape
				// remove the dropdown
				document.body.removeChild($(id));
				// focus the source element
				element.focus();

			} else if (event.keyCode == Event.KEY_UP || event.keyCode == Event.KEY_DOWN) {
				var currentLink = this;

				if (event.keyCode == Event.KEY_DOWN) {
					if (this.nextSibling) {
						var nextLink = this.nextSibling;
					} else {
						var nextLink = $(id).firstChild;
					}
				} else if (event.keyCode == Event.KEY_UP) {
					if (this.previousSibling) {
						var nextLink = this.previousSibling;
					} else {
						var nextLink = $(id).lastChild;
					}
				}

				currentLink.className = '';
				nextLink.focus();
				nextLink.className = 'active';

			} else if (event.keyCode == Event.KEY_RETURN) {
				this.onclick();
			}

			event.stop();
		});

		dropdown.appendChild(link);
	}

	document.body.appendChild(dropdown);
}

function autocompletePick(textElementId, value, text)
{
	var textElement = $(textElementId);
	textElement.value = text;
	textElement.pickedValue = value;
	var id = 'autocomplete_' + textElementId;
	document.body.removeChild($(id));

	if ($(textElementId).next('input')) {
		$(textElementId).next('input').focus();
	}

	textElement.fire('autocomplete:pick', {value: value, title: text});

	return false;
}

