// this can be done from anywhere once the dom is loaded
document.observe(
	"dom:loaded",
	function() {
		setupAutocomplete('zip', 'index.php?eID=tx_psoffers_pi1');
	}
);

/**
 * Setup the autocomplete feature for an input field.
 *
 * @var mixed input The ID of the input field or the dom element.
 * @return void
 */
function setupAutocomplete(input, url) {
	input = $(input);
	input.autocompleteUrl = url;
	input.insert({after: '<div class="autocompleteContainer"><div style="z-index: 999;" class="autocomplete hide"></div></div>'});
	input.observe('keyup', findAutocomplete);
	input.observe('keydown', navigateAutocomplete);
	input.observe('blur', blurAutocomplete);
	input.observe('focus', focusAutocomplete);
	input.setAttribute('autocomplete', 'off');
}

/**
 * Handle the blur event on the input field.
 *
 * @return void
 */
function blurAutocomplete() {
	var input = $(this);
	if (input.doNotBlur) {
		input.doNotBlur = false;
		return;
	}
	setTimeout('hideAutocomplete(\'' + input.id + '\');', 200);
}

/**
 * Handle the focus event on the input field.
 *
 * @return void
 */
function focusAutocomplete() {
	var input = $(this);
	var autocomplete = input.next('.autocompleteContainer').firstDescendant();
	var firstLi = autocomplete.down('li');
	if (firstLi && autocomplete.hasClassName('hide')) {
		showAutocomplete(input);
	}
}

/**
 * Handle the keydown event on the input field -> navigation keystrokes.
 *
 * @var mixed event The event.
 * @return void
 */
function navigateAutocomplete(event) {
	var input = $(this);
	
	var autocomplete = input.next('.autocompleteContainer').firstDescendant();
	var activeLinks = autocomplete.select('li.active');
	var firstLi = autocomplete.down('li');
	
	if (firstLi) {
		if (event.keyCode == Event.KEY_DOWN) {
			nextAutocompleteLink(input);
			input.stopped = true;
			return;
		} else if (event.keyCode == Event.KEY_UP) {
			previousAutocompleteLink(input);
			input.stopped = true;
			return;
		} else if (event.keyCode == Event.KEY_RETURN || event.keyCode == Event.BACKSPACE) {
			if (activeLinks && activeLinks[0]) {
				var link = activeLinks[0].down('a');
				link.onclick();
				activeLinks.each(function(n) { n.className = ''; });
				
				hideAutocomplete(input);
				input.stopped = true;
				event.stop();
				return;
			}
		}
	}
}

/**
 * Handle the keyup event on the input field and gets the data via ajax -> writing keystrokes.
 *
 * @return void
 */
function findAutocomplete() {
	var input = $(this);
	
	if (input.stopped) {
		input.stopped = false;
		return;
	}
	
	if (input.value.length < 3) {
		hideAutocomplete(input);
		return;
	}
	
	if (input.oldText) {
		if (input.oldText == input.value) {
			return;
		}
		input.oldText = input.value;
	}
	
	var psOffersAjax = new Ajax.Request(
		input.autocompleteUrl,
		{
			parameters: {
				'toComplete': input.value
			},
			method: 'post',
			onSuccess: function(response) {
				// evaluate the json into returnArray
				eval('var returnArray = ' + response.responseText + ';');
				if (returnArray == '') {
					return;
				}
				
				var length = 0;
				for (var key in returnArray) {
					length++;
				}
				
				if (length > 0) {
					if (length == 1) {
						for (var key in returnArray) {
							// only run once
							input.value = key;
							/* var autocomplete = input.next('.autocomplete');
							autocomplete.innerHTML = ''; */
							hideAutocomplete(input);
						}
					} else {
						var autocomplete = input.next('.autocompleteContainer').firstDescendant();
						html = '<ul class="autocompleteLinks">';
						
						for (var key in returnArray) {
							html += '<li>' + createAutocompleteLink(input, autocomplete, returnArray[key]['city'], key) + '</li>';
						}
						
						html += '</ul>';
						autocomplete.innerHTML = html;
						autocomplete.select('a').each(
							function (n) {
								n.observe('mouseover', hoverAutocompleteLink);
							}
						);
						showAutocomplete(input);
					}
				} else {
					hideAutocomplete(input);
				}
			},
			onFailure: function(response) {
				alert(response.responseText);
			}
		}
	);
}

/**
 * Hides the autocomplete dropdown menu.
 *
 * @var mixed input The ID of the input field or the dom element.
 * @return void
 */
function hideAutocomplete(input) {
	input = $(input);
	
	var autocomplete = input.next('.autocompleteContainer').firstDescendant();
	autocomplete.className = autocomplete.className.replace(new RegExp("\\bshow\\b"), "hide");
}

/**
 * Shows the autocomplete dropdown menu.
 *
 * @var mixed input The ID of the input field or the dom element.
 * @return void
 */
function showAutocomplete(input) {
	input = $(input);
	
	var autocomplete = input.next('.autocompleteContainer').firstDescendant();
	autocomplete.className = autocomplete.className.replace(new RegExp("\\bhide\\b"), "show");
	
	var firstLink = autocomplete.select('a');
	if (firstLink && firstLink[0]) {
		input.doNotBlur = true;
		firstLink[0].focus();
		input.focus();
	}
}

/**
 * Activates the next link (when pressing down button).
 *
 * @var mixed input The ID of the input field or the dom element.
 * @return Dom The link.
 */
function nextAutocompleteLink(input) {
	input = $(input);
	
	var autocomplete = input.next('.autocompleteContainer').firstDescendant();
	
	var activeLinks = autocomplete.select('li.active');
	if (!activeLinks || !activeLinks[0] || !activeLinks[0].next('li')) {
		nextLink = autocomplete.select('li')[0];
	} else {
		nextLink = activeLinks[0].next('li');
	}
	activeLinks.each(function(n) { n.className = ''; });
	input.doNotBlur = true;
	nextLink.className = 'active';
	nextLink.firstDescendant().focus();
	input.focus();
}

/**
 * Activates the previous link (when pressing up button).
 *
 * @var mixed input The ID of the input field or the dom element.
 * @return Dom The link.
 */
function previousAutocompleteLink(input) {
	input = $(input);
	
	var autocomplete = input.next('.autocompleteContainer').firstDescendant();
	
	var activeLinks = autocomplete.select('li.active');
	if (!activeLinks || !activeLinks[0] || !activeLinks[0].previous('li')) {
		previousLink = autocomplete.select('li');
		previousLink = previousLink[previousLink.length - 1];
	} else {
		previousLink = activeLinks[0].previous('li');
	}
	activeLinks.each(function(n) { n.className = ''; });
	input.doNotBlur = true;
	previousLink.className = 'active';
	previousLink.firstDescendant().focus();
	input.focus();
}

/**
 * Handles hovering over a link.
 *
 * @return void
 */
function hoverAutocompleteLink() {
	var ul = $(this).up(1);
	var active = ul.select('li.active');
	active.each(function(n) { n.className = ''; });
	
	$(this).up().className = 'active';
}

/**
 * Creates an autocomplete link.
 *
 * @var mixed input The ID/Dom-Element of the input field.
 * @var mixed autocomplete The ID/Dom-Element of the autocomplete container.
 * @var string title The link title.
 * @var string value The link value.
 * @return string The rendered link.
 */
function createAutocompleteLink(input, autocomplete, title, value) {
	input = $(input);
	return '<a title="' + value + ' ' + title + '" href="javascript:void(0);" onclick="updateAutocomplete(\'' + input.id + '\', \'' + value + '\');">' + value + ' ' + title + '</a>';
}

/**
 * Updates the input with the link value.
 *
 * @var mixed input The ID/Dom-Element of the input field.
 * @var string value The link value.
 * @return boolean false.
 */
function updateAutocomplete(input, value) {
	input = $(input);
	input.value = value;
	hideAutocomplete(input);
	return false;
}

