﻿
window.AutoComplete = function(input, url, options, data)
{
	$(function()
	{
		options.Events.OnItemChosen = options.Events.OnItemChosen && window[options.Events.OnItemChosen];
		options.Events.OnGetListClient = options.Events.OnGetListClient && window[options.Events.OnGetListClient];
		options.Events.OnBlur = options.Events.OnBlur && window[options.Events.OnBlur];
	});

	options = $.extend(
	{
		Css:
		{
			Panel: "",
			Textbox: "",
			Item: "",
			SelectedItem: ""
		},
		Events:
		{
			OnItemChosen: null,
			OnGetListClient: null,
			OnBlur: null,
			someEvent: 0
		},
		DataTextField: "text",
		DataValueField: "id",
		url: typeof url == "string" ? url : null,
		data: (data instanceof Array) ? data : null,
		minChars: 1,
		delay: 100
	}, options || {});

	var frame = null;
	var panel = $("<ul/>").insertAfter(input).hide()
		.addClass(options.Css.Panel)
		.css({ "position": "absolute", "zIndex": "2" });

	// fix for IE6 bug, to cover select elements
	if ($.browser.msie && $.browser.version == "6.0" && !window.XMLHttpRequest)
		frame = $("<iframe>").appendTo(panel.parent()).hide().addClass(options.Css.Panel).css({ "position": "absolute", "zIndex": "1" });

	var selectedItem = null;
	var lastKeyCode = null;
	var mouseMoved = false;
	var timeout = null;
	
	var that = this;

	$("form").each(function(index, form) { form.autocomplete = "off"; });

	input.addClass(options.Css.Textbox)
	.attr("autocomplete", "off")
	.css("display", "block")
	.blur(function(e)
	{
		function Close()
		{
			ChooseItem(selectedItem = null);
			HidePanel();

			options.Events.OnBlur && options.Events.OnBlur();
		}

		if ($.browser.msie)
		{
			with (panel[0].getBoundingClientRect())
			{
				// for IE: when the scroll is clicked, IE fires this event, so test by mouse coords and
				// panel box if the was outside the dropped down panel
				if (e.clientX >= left && e.clientX <= right && e.clientY >= top && e.clientY <= bottom)
				{
					input[0].focus();
					return;
				}
			}
		}

		Close();
	})
	.keydown(function(e)
	{
		// track last key pressed
		lastKeyCode = e.keyCode;
		mouseMoved = false;

		switch (e.keyCode)
		{
			case 37:
			case 39:
				break;
			case 38: // up
				e.preventDefault();
				e.stopPropagation();
				SelectItem(selectedItem && selectedItem.prev().length && selectedItem.prev() || panel.children(":last"), true);
				break;
			case 40: // down
				e.preventDefault();
				e.stopPropagation();
				SelectItem(selectedItem && selectedItem.next().length && selectedItem.next() || panel.children(":first"), true);
				break;
			case 9:  // tab
				e.preventDefault();
				e.stopPropagation();
				ChooseItem(selectedItem);
				HidePanel();
				NextFieldOnTab();
				break;
			case 13: // return
				ChooseItem(selectedItem);
				HidePanel();
				e.preventDefault();
				e.stopPropagation();
				return false;
			case 27:
				HidePanel();
				return false;
			default:
				SelectItem(null);
				timeout && clearTimeout(timeout);
				timeout = setTimeout(function()
				{
					timeout = null;

					if (input[0].value.length > options.minChars)
					{
						if (!options.Events.OnGetListClient || options.Events.OnGetListClient(input) != false)
						{
							var cnid = "";
							if(window.CountryId !=null)
							    cnid = "&cnid=" + CountryId;

							options.url ? $.getJSON(options.url + "&q=" + input[0].value + cnid, DataToDom) : DataToDom(options.data);
						}
					}
					else
						HidePanel();
				}, options.delay);
		}
	})
	.dblclick(function(e)
	{
		if (input[0].value.length > options.minChars)
			ShowPanel();
	});

	// Private methods

	function FindItem(text)
	{
		var foundItem = null;
		var textField = options.DataTextField;

		text = text.toLowerCase();

		panel.children().each(function(index, item)
		{
			var data = item.data;

			if (text == (textField ? data[textField] : data).toLowerCase())
			{
				foundItem = $(item); return false;
			}
		});

		return foundItem;
	}

	function DataToDom(data)
	{
		options.data = data;
		panel.empty(); // remove existing child nodes, if any

		if (data.length == 0)
			return;

		for (var n = 0, length = data.length; n < length; n++)
		{
			var item = data[n];
			var text = options.DataTextField ? item[options.DataTextField] : item;

			var li = $("<li>" + text + "</li>")
			.addClass(options.Css.Item)
			.hover(function() { mouseMoved && SelectItem($(this)); }, function() { })
			.mousedown(function(e)
			{
				selectedItem = $(this);
				ChooseItem(selectedItem);
				HidePanel();
				input.focus();
			})
			.mousemove(function(e)
			{
				mouseMoved = true;
			})
			.appendTo(panel);

			li[0].data = item;
		}

		ShowPanel();
	}

	function SelectItem(item, ignoreMouse)
	{
		ignoreMouse = ignoreMouse || false;

		if (selectedItem)
			selectedItem.removeClass(options.Css.SelectedItem);

		if (item)
		{
			if (item.length == 0) return;

			item.addClass(options.Css.SelectedItem);

			if (ignoreMouse == true)
				scroll(item, panel);
		}

		return selectedItem = item;
	}

	function scroll(item, scroller)
	{
		var ir = { top: item[0].offsetTop, bottom: item[0].offsetTop + item[0].offsetHeight, height: item[0].offsetHeight };
		var sr = { top: scroller[0].scrollTop, bottom: scroller[0].scrollTop + scroller[0].clientHeight, height: scroller[0].clientHeight };

		// the item's top is obove the scroller's one
		if (ir.top <= sr.top)
			scroller.scrollTop(ir.top);

		if (ir.bottom >= sr.bottom)
			scroller.scrollTop(ir.bottom - sr.bottom + sr.top);
	}

	function ChooseItem(item)
	{
		var text = null;
		var callback = options.Events.OnItemChosen;

		if (item)
			text = item.text();
		else
			item = FindItem(text = input.val());

		var oldItem = input[0].previousAC_TextChangedEvent || { input: input, text: "", data: null };
		var newItem = { input: input, text: text, data: item && item[0].data };

		if (oldItem.text == newItem.text)
			return;

		input[0].previousAC_TextChangedEvent = newItem;
		input[0].value = GetTextFieldValue(item, text);

		callback && callback.call(null, oldItem, newItem);
	}

	function ShowPanel()
	{
		panel.show();
		frame && frame.show();
	}

	function HidePanel()
	{
		panel.hide();
		frame && frame.hide();
	}

	function GetTextFieldValue(item, defaultValue)
	{
		return item ? (options.DataTextField ? item[0].data[options.DataTextField] : item[0].data) : (defaultValue || "");
	}


	function NextFieldOnTab()
	{
		var field = input[0];
		for (i = 0; i < field.form.elements.length; i++)
		{
			if (field.form.elements[i].tabIndex == field.tabIndex + 1)
			{
				field.form.elements[i].focus();
				field.form.elements[i].select();
				break;
			}
		}
	}
}

   

   

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();