﻿var LocationFinder =
{
	initialised: false,
	maxSuggestions: 10,
	stateFilter: null,
	currentInput: null,
	resultsHolder: null,
	resultsList: null,
	enterSelectedSuggestion: false,

	initialise: function()
	{
		if (!window.jQuery || parseInt(jQuery.fn.jquery.replace(/\./g, "")) < 126)
		{
			alert("The LocationFinder control requires jQuery 1.2.6 or higher.");
			return;
		}

		jQuery(document).ready(function()
		{
			jQuery("body").append('<div id="LocationFinderResults" style="display:none;position:absolute;top:0px;left:0px;border:1px solid #000;"><ul></ul></div>');
			LocationFinder.resultsHolder = jQuery("#LocationFinderResults");
			LocationFinder.resultsList = jQuery("#LocationFinderResults ul");
			jQuery("body").click(LocationFinder.hideResults);
		});
		this.initialised = true;
	},

	register: function(inputID, maxSuggestions, stateFilter)
	{
		LocationFinder.maxSuggestions = maxSuggestions;
		LocationFinder.stateFilter = stateFilter;
		var input = jQuery("#" + inputID);
		input.attr("autocomplete", "off");
		input.keydown(this.keyDown);
		input.keyup(this.keyUp);
	},

	keyDown: function(event)
	{
		switch (event.keyCode)
		{
			case 38: // arrow up
				event.stopPropagation();
				LocationFinder.moveSelection(true);
				break;

			case 40: // arrow down
				event.stopPropagation();
				LocationFinder.moveSelection(false);
				break;

			case 10: // enter/return
			case 13:
				var returnVal = true;
				var selection = LocationFinder.resultsList.find("li.Selected");
				if (selection.length > 0)
				{
					LocationFinder.setSelection(selection, true);
					returnVal = false;
				}
				event.stopPropagation();
				return returnVal;
				break;
		}
	},

	keyUp: function(event)
	{
		if (!LocationFinder.enterSelectedSuggestion)
		{
			switch (event.keyCode)
			{
				case 37: // arrow keys
				case 38:
				case 39:
				case 40:
					event.stopPropagation();
					break;

				default:
					var urlAndQuery = "LocationFinderHandler.axd?Query=" + this.value + "&State=" + LocationFinder.stateFilter + "&MaximumResults=" + LocationFinder.maxSuggestions;
					var ajaxOptions =
					{
						url: urlAndQuery,
						dataType: "json",
						success: LocationFinder.locationsFound
					};
					jQuery.ajax(ajaxOptions);
					LocationFinder.currentInput = jQuery(event.target);
					break;
			}
		}
		else
		{
			LocationFinder.enterSelectedSuggestion = false;
		}
	},

	locationsFound: function(locations)
	{
		LocationFinder.hideResults();
		if (locations.length > 0)
		{
			LocationFinder.resultsList.empty();
			for (var i = 0; i < locations.length; i++)
			{
				var location = locations[i];
				LocationFinder.resultsList.append("<li>" + location.Name + ", " + location.StateTerritory.Acronym + ", " + location.Postcode + "</li>");
			}

			LocationFinder.resultsList.find("li").click(function() { LocationFinder.setSelection(jQuery(this), false); });

			// Position
			var offset = LocationFinder.currentInput.offset();
			var inputPaddingTopBottom = parseInt(LocationFinder.currentInput.css("padding-top")) + parseInt(LocationFinder.currentInput.css("padding-bottom"));
			var inputBordersTopBottom = parseInt(LocationFinder.currentInput.css("border-top-width")) + parseInt(LocationFinder.currentInput.css("border-bottom-width"));
			var inputPaddingLeftRight = parseInt(LocationFinder.currentInput.css("padding-left")) + parseInt(LocationFinder.currentInput.css("padding-right"));
			var inputBordersLeftRight = parseInt(LocationFinder.currentInput.css("border-left-width")) + parseInt(LocationFinder.currentInput.css("border-right-width"));
			LocationFinder.resultsHolder.css("width", (parseInt(LocationFinder.currentInput.css("width")) + inputPaddingLeftRight) + "px");
			LocationFinder.resultsHolder.css("left", offset.left + "px");
			LocationFinder.resultsHolder.css("top", (offset.top + LocationFinder.currentInput.height() + inputPaddingTopBottom + inputBordersTopBottom - 1) + "px");
			LocationFinder.resultsHolder.slideDown("fast");
		}
	},

	setSelection: function(selectedItem, fromEnter)
	{
		LocationFinder.currentInput.val(selectedItem.text());
		LocationFinder.enterSelectedSuggestion = fromEnter;
		LocationFinder.hideResults();
	},

	moveSelection: function(isUp)
	{
		var rows = this.resultsList.find("li");
		var currentIndex = -1;
		var selectedRow = rows.each(function(i)
		{
			var row = jQuery(this);
			if (row.hasClass("Selected"))
			{
				jQuery(this).removeClass("Selected");
				currentIndex = i;
			}
		});
		if (selectedRow.length == 0)
		{
			if (isUp) rows.find(":last").addClass("Selected");
			else rows.find(":first").addClass("Selected");
		}
		else
		{
			var index = currentIndex + (isUp ? -1 : 1);
			if (index >= rows.length) index = 0;
			else if (index < 0) index = rows.length - 1;
			jQuery(rows[index]).addClass("Selected");
		}
	},

	hideResults: function()
	{
		LocationFinder.resultsHolder.hide();
	}
};
LocationFinder.initialise();