﻿function NewAutoComplete(txtSearchTerm, objSource)
{
	var THIS = this;
	var divAutoCompleteList = null;
	var strLastText = "";
	
	this.Input = txtSearchTerm;
	this.Handle = NewAutoComplete.NextHandle;
	NewAutoComplete.NextHandle++;
	this.ItemSelected = null;
	this.SelectedOption = null;
	this.UpperCaseOptions = true;
	this.Source = objSource;
	this.TextChanged = null;
	this.ModifyEntry = null;
	this.MaxHeight = 300;
	this.VisibleChanged = null;
	this.Blur = null;
	this.Active = false;
	this.DataFiltered = null;
	this.Data = null;
	this.Focus = null;
	var intHideHandle = 0;
	this.CaseSensitive = false;
	this.Count = 0;
	var aExactMatch = null;
	
	if (arguments.length == 2 || !strStorageKey)
		strStorageKey = null;

	NewAutoComplete.Instances[this.Handle] = this;

	if (txtSearchTerm != null)
	{
		txtSearchTerm.onfocus = txtSearchTerm_Focus;
		txtSearchTerm.onkeyup = txtSearchTerm_KeyUp;
		txtSearchTerm.onblur = txtSearchTerm_Blur;
	}

	//==========================================
	// Clear the currently selected option
	//==========================================
	this.RemoveSelectedOption = function RemoveSelectedOption(aOption)
	{
		try
		{
			if (arguments.length == 0)
			{
				aOption = this.SelectedOption;
				this.SelectedOption = null;
			}

			if (aOption != null)
			{
				aOption.innerHTML = aOption.getAttribute("data");
				aOption.className = "";
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Clear the input, and the currently selected auto complete entry
	//==========================================
	this.Clear = function Clear()
	{
		try
		{
			this.Input.value = "";
			this.RemoveSelectedOption();
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Set the selected option
	//==========================================
	this.SetSelected = function SetSelected(strOption)
	{
		try
		{
			this.Clear();

			if (strOption == null || this.Input == null || this.Data == null)
				return;

			if (this.UpperCaseOptions)
				strOption = strOption.toUpperCase();

			this.Input.value = strOption;

			for (strData in this.Data)
			{
				var strCheck = strData;
				if (this.UpperCaseOptions)
					strCheck = strData.toUpperCase();

				if (strCheck == strOption)
				{
					this.SelectedOption = this.Data[strData];
					this.SelectedOption.className = "selected";
					break;
				}
			}

			if (this.SelectedOption == null)
			{
				//no option set...
				//create a new option and add it to the list
				var aData = CreateOption(strOption);

				if (aData != null)
				{
					aData.className = "selected";
					this.SelectedOption = aData;

					divAutoCompleteList.style.display = "none";
				}
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}
	
	//==========================================
	// Get the list container
	//==========================================
	this.GetListContainer = function GetListContainer()
	{
		if (divAutoCompleteList == null)
		{
			divAutoCompleteList = document.createElement("DIV");
			divAutoCompleteList.className = "quickSearchAutoComplete";

			if (BrowserDetect.browser == "Explorer" && BrowserDetect.version != 8)
				divAutoCompleteList.className += " ie7";

			this.Input.parentNode.insertBefore(divAutoCompleteList, this.Input);
		}

		return divAutoCompleteList;
	}

	//==========================================
	// Reload the auto complete data
	//==========================================
	this.ReloadData = function ReloadData()
	{
		try
		{
			LoadQuickSearch(false);
			txtSearchTerm_Focus(null);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// A key has been pressed in the search term field
	//==========================================
	function txtSearchTerm_Focus(evt)
	{
		try
		{
			if (intHideHandle != 0)
				window.clearTimeout(intHideHandle);
			intHideHandle = 0;
		
			var evt = window.event ? window.event : evt;
			THIS.Active = true;

			if (THIS.Data != null)
			{
				FilterAutoComplete(false);
				return;
			}

			LoadQuickSearch(false);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
		finally
		{
			if (THIS.Focus != null)
				THIS.Focus(evt, THIS, THIS.Input);
		}
	}

	//==========================================
	// The focus has left this control, if the auto complete is visible set it to hide in a few moments
	//==========================================
	function txtSearchTerm_Blur(evt)
	{
		try
		{
			THIS.Active = false;

			//does the text match an item in the list?
			if (divAutoCompleteList != null)
				intHideHandle = window.setTimeout(fncHideAutoComplete, 400);

			if (THIS.Blur != null)
				THIS.Blur(THIS, evt);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Hide the auto complete drop down now.
	//==========================================
	function fncHideAutoComplete()
	{
		try
		{
			intHideHandle = 0;
			THIS.HideAutoComplete();

			var aPreviousSelection = THIS.SelectedOption;
			FilterAutoComplete(false);

			if (aExactMatch != null)
			{
				if (aPreviousSelection != aExactMatch)
				{
					THIS.RemoveSelectedOption(aPreviousSelection);

					THIS.SelectedOption = aExactMatch;
					THIS.SelectedOption.className = "selected";
					var strData = THIS.SelectedOption.getAttribute("data");

					if (THIS.ItemSelected != null)
						THIS.ItemSelected(THIS, strData, true);
				}
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Hide the auto complete drop down now.
	//==========================================
	this.HideAutoComplete = function HideAutoComplete()
	{
		try
		{
			if (divAutoCompleteList != null)
			{
				divAutoCompleteList.style.display = "none";

				if (this.VisibleChanged != null)
					this.VisibleChanged(this, false);
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// A key has been pressed in the search term field
	//==========================================
	function txtSearchTerm_KeyUp(evt)
	{
		try
		{
			var evt = window.event ? window.event : evt;
			var intKeyCode = evt.keyCode ? evt.keyCode : evt.which;

			if (intKeyCode == KEYCODE_DOWN)
				SelectNext();
			else if (intKeyCode == KEYCODE_UP)
				SelectPrevious();
			else if (intKeyCode != KEYCODE_TAB)
			{
				if (THIS.TextChanged != null && THIS.Input.value != strLastText)
					THIS.TextChanged(THIS, THIS.Input.value);

				LoadQuickSearch(true);
//				if (THIS.Data == null)
//				{
//					fncHideAutoComplete();
//					LoadQuickSearch(true);
//				}
//				else
//					FilterAutoComplete(true);
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
		finally
		{
			strLastText = THIS.Input.value;
		}
	}

	//==========================================
	// Save the quick search into memory, then update local storage
	//==========================================
	this.SaveQuickSearch = function SaveQuickSearch(strSearchTerm)
	{
		try
		{
			if (this.Data == null)
				this.Data = new Object();

			this.Data[strSearchTerm] = "true";

			StoreQuickSearch();
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Load the quick search options from local storage
	//==========================================
	function LoadQuickSearch(blnFireItemSelected)
	{
		try
		{
			if (THIS.Source != null)
				THIS.Source.GetData(THIS, DisplayQuickSearch, blnFireItemSelected);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Load the quick search options from local storage
	//==========================================
	function DisplayQuickSearch(arrData, blnFireItemSelected)
	{
		try
		{
			var objData = new Object();

			if (arrData != null)
			{
				for (var intIndex = 0; intIndex < arrData.length; intIndex++)
				{
					var strData = arrData[intIndex];

					if (strData == "")
						continue;

					if (THIS.UpperCaseOptions == true)
						strData = strData.toUpperCase();

					objData[strData] = "true";
				}
			}

			THIS.GetListContainer();

			divAutoCompleteList.innerHTML = "";
			if (THIS.Active)
			{
				divAutoCompleteList.style.display = "";

				if (THIS.VisibleChanged != null)
					THIS.VisibleChanged(THIS, true);
			}

			THIS.SelectedOption = null;
			THIS.Count = 0;

			for (var strData in objData)
			{
				var aData = CreateOption(strData);

				if (aData == null)
					continue;
			}

			FilterAutoComplete(blnFireItemSelected);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Create an option for the auto complete list
	//==========================================
	function CreateOption(strData)
	{
		var aData = document.createElement("A");
		if (THIS.UpperCaseOptions == true)
			strData = strData.toUpperCase();

		aData.innerHTML = strData;

		if (THIS.ModifyEntry != null)
		{
			var strOriginalData = strData;
			strData = THIS.ModifyEntry(aData, strData);

			if (strData == null || strData == "")
				return null;
		}

		aData.setAttribute("data", strData);

		aData.onclick = AutoCompleteEntry_Selected;

		if (THIS.Data == null)
			THIS.Data = new Object();

		THIS.Data[strData] = aData;
		THIS.GetListContainer().appendChild(aData);

		THIS.Count++;

		return aData;
	}

	//==========================================
	// Store the quick search options into local storage
	//==========================================
	function StoreQuickSearch()
	{
		try
		{
			if (THIS.Source == null)
				return;

			if (THIS.Data != null && THIS.Source.SetData)
				THIS.Source.SetData(THIS.Data);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Open the list
	//==========================================
	this.OpenList = function OpenList(blnFilter)
	{
		try
		{
			if (blnFilter)
				FilterAutoComplete(false);
			else
			{
				var intCount = FilterAutoComplete(false);

				if (divAutoCompleteList == null)
					return;

				var aFirst = divAutoCompleteList.firstChild;
				var strSearch = txtSearchTerm.value;

				if (THIS.UpperCaseOptions)
					strSearch = strSearch.toUpperCase();

				while (aFirst != null)
				{
					aFirst.style.display = "";

					if (this.SelectedOption == null)
					{
						var strData = aFirst.getAttribute("data");

						if (THIS.UpperCaseOptions)
							strData = strData.toUpperCase();

						if (strData == strSearch)
						{
							this.SelectedOption = aFirst;
							this.SelectedOption.className = "selected";
						}
					}

					aFirst = aFirst.nextSibling;
				}

				UpdateHeight();

				divAutoCompleteList.style.display = intCount > 0 ? "" : "none";

				if (THIS.VisibleChanged != null)
					THIS.VisibleChanged(THIS, true);
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Filter the auto complete options
	//==========================================
	function FilterAutoComplete(blnFireItemSelected)
	{
		try
		{
			if (divAutoCompleteList != null)
			{
				var aData = divAutoCompleteList.firstChild;
				var intCount = 0;
				var intExactCount = 0;
				var strSearchTerm = THIS.UpperCaseOptions == true ? THIS.Input.value.toUpperCase() : THIS.Input.value;
				var aPreviousSelection = THIS.SelectedOption;
				var strSearchCheck = strSearchTerm;

				aExactMatch = null;

				if (THIS.CaseSensitive == false)
					strSearchCheck = strSearchCheck.toUpperCase();

				while (aData != null)
				{
					var strData = aData.getAttribute("data");
					
					var strDataCheck = strData;

					if (THIS.CaseSensitive == false)
						strDataCheck = strDataCheck.toUpperCase();

					if (strDataCheck.indexOf(strSearchCheck) == -1)
					{
						aData.style.display = "none";
						aData.className = "";

						if (aData == THIS.SelectedOption)
							THIS.SelectedOption = null;
					}
					else
					{
						var intStart = strData.toLowerCase().indexOf(strSearchTerm.toLowerCase());
						var strLeft = strData.substring(0, intStart);
						var strRight = strData.substring(intStart + strSearchTerm.length);
						var strMiddle = strData.substring(intStart, strSearchTerm.length + intStart);

						var strNew = strData;

						if (strSearchTerm.length >= 2)
							strNew = strLeft + "<u>" + strMiddle + "</u>" + strRight;

						aData.innerHTML = strNew;

						aData.style.display = "";

						if (strData.toUpperCase() == strSearchTerm.toUpperCase())
						{
							intExactCount++;
							aExactMatch = aData;
						}

						intCount++;
					}

					aData = aData.nextSibling;
				}

				if (intCount <= 1)
				{
					if (intCount == 1 && intExactCount == 0)
					{
						if (THIS.Active)
						{
							divAutoCompleteList.style.display = "";

							if (THIS.VisibleChanged != null)
								THIS.VisibleChanged(THIS, true);
						}
					}
					else
					{
						divAutoCompleteList.style.display = "none";

						if (intCount == 1 && intExactCount == 1 && aExactMatch != null)
						{
							if (aPreviousSelection != aExactMatch)
							{
								THIS.SelectedOption = aExactMatch;
								THIS.SelectedOption.className = "selected";
								var strData = THIS.SelectedOption.getAttribute("data");

								if (THIS.ItemSelected != null && blnFireItemSelected)
									THIS.ItemSelected(THIS, strData, false);
							}
						}

						if (THIS.VisibleChanged != null)
							THIS.VisibleChanged(THIS, false);
					}
				}
				else
				{
					if (THIS.Active)
					{
						divAutoCompleteList.style.display = "";

						if (THIS.VisibleChanged != null)
							THIS.VisibleChanged(THIS, true);
					}
				}

				UpdateHeight();

				if (THIS.DataFiltered != null)
					THIS.DataFiltered(THIS, strSearchTerm, intCount, intExactCount);

				return intCount;
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
			return 0;
		}
	}

	//==========================================
	// Update the height of the auto complete drop down
	//==========================================
	function UpdateHeight()
	{
		try
		{
			if (divAutoCompleteList == null)
				return;
				
			if (divAutoCompleteList.style.display == "none")
				return;

			var intHeight = 0;
			var aFirst = divAutoCompleteList.firstChild;

			while (aFirst != null)
			{
				if (aFirst.style.display != "none")
					intHeight += aFirst.offsetHeight;
				aFirst = aFirst.nextSibling;
			}

			if (intHeight > THIS.MaxHeight)
				divAutoCompleteList.style.height = THIS.MaxHeight + "px";
			else
				divAutoCompleteList.style.height = "";
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Select the next auto complete entry (or the first one if none selected)
	//==========================================
	function SelectNext()
	{
		try
		{
			var spnLast = THIS.SelectedOption;
			var spnCurrent = THIS.SelectedOption;

			if (spnCurrent != null)
			{
				while (spnCurrent != null)
				{
					spnCurrent = spnCurrent.nextSibling;

					if (spnCurrent == null)
						break;

					if (spnCurrent.tagName == "A")
					{
						if (spnCurrent.style.display == "none")
							continue;

						//use this span
						break;
					}
				}
			}

			if (spnCurrent == null && divAutoCompleteList.children.length > 0)
			{
				spnCurrent = divAutoCompleteList.firstChild;

				while (spnCurrent != null && spnCurrent.style.display == "none")
					spnCurrent = spnCurrent.nextSibling;
			}

			if (spnCurrent != null && spnCurrent.tagName == "A")
			{
				if (spnLast != null)
					spnLast.className = "";

				var strData = spnCurrent.getAttribute("data");
				THIS.SelectedOption = spnCurrent;
				THIS.SelectedOption.className = "selected";
				THIS.Input.value = strData;
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// Select the previous auto complete entry (or the last one if none selected)
	//==========================================
	function SelectPrevious()
	{
		try
		{
			var spnCurrent = THIS.SelectedOption;
			var spnLast = THIS.SelectedOption

			if (spnCurrent != null)
			{
				while (spnCurrent != null)
				{
					spnCurrent = spnCurrent.previousSibling;

					if (spnCurrent == null)
						break;

					if (spnCurrent.tagName == "A")
					{
						if (spnCurrent.style.display == "none")
							continue;

						//use this span
						break;
					}
				}
			}

			if (spnCurrent == null && divAutoCompleteList.children.length > 0)
			{
				spnCurrent = divAutoCompleteList.lastChild;

				while (spnCurrent != null && spnCurrent.style.display == "none")
					spnCurrent = spnCurrent.previousSibling;
			}

			if (spnCurrent != null && spnCurrent.tagName == "A")
			{
				if (spnLast != null)
					spnLast.className = "";

				var strData = spnCurrent.getAttribute("data");
				spnCurrent.className = "selected";
				THIS.Input.value = strData;
				THIS.SelectedOption = spnCurrent;
			}
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// An auto complete entry has been selected, set the text
	//==========================================
	function AutoCompleteEntry_Selected(evt)
	{
		try
		{
			evt = window.event ? window.event : evt;
			var aData = evt.srcElement ? evt.srcElement : evt.target;

			if (aData.tagName == "U")
				aData = aData.parentElement ? aData.parentElement : aData.parentNode;

			var strData = aData.getAttribute("data");
			THIS.Input.value = strData;

			THIS.RemoveSelectedOption();

			THIS.SelectedOption = aData;

			THIS.SelectedOption.className = "selected";

			if (THIS.ItemSelected != null)
				THIS.ItemSelected(THIS, strData, true);

			divAutoCompleteList.style.display = "none";
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}
}

NewAutoComplete.NextHandle = 1;
NewAutoComplete.Instances = new Object();

NewAutoComplete.HideAutoComplete = function HideAutoComplete(intHandle)
{
	var objInstance = NewAutoComplete.Instances[intHandle];
	objInstance.HideAutoComplete();
}

//==========================================
// DOM Storage auto complete source
//==========================================
function DOMStorage_AutoCompleteSource(strKey)
{
	this.Key = strKey;
	this.ModifyKey = null;

	//==========================================
	// Get the data from the DOM storage
	//==========================================
	this.GetData = function GetData(objAutoComplete, fncCallback, blnFireItemSelected)
	{
		var strKey = this.Key;

		if (this.ModifyKey != null)
			strKey = this.ModifyKey(this, objAutoComplete);

		var strList = DOMStorage.Get(strKey);
		if (strList == null)
		{
			fncCallback(new Array(), blnFireItemSelected);
			return;
		}
		var arrList = strList.split('|');

		arrList.sort();

		fncCallback(arrList, blnFireItemSelected);
	}

	//==========================================
	// Set the data in the DOM Storage
	//==========================================
	this.SetData = function SetData(objAutoComplete, objData)
	{
		var strKey = this.Key;

		if (this.ModifyKey != null)
			strKey = this.ModifyKey(this, objAutoComplete);

		if (objData != null)
		{
			var strList = "";

			for (var strData in objData)
			{
				if (strData == "" || strData == null)
					continue;

				if (strList != "")
					strList += "|";

				strList += strData;
			}

			DOMStorage.Set(strKey, strList);
		}
		else
			DOMStorage.Set(strKey, "");
	}
}

//==========================================
// Webservice auto complete source
//==========================================
function Webservice_AutoCompleteSource(strURL, strMethod, strColumnName, fncPrepareRequest)
{
	var THIS = this;
	this.PrepareRequest = fncPrepareRequest;
	this.ColumnName = strColumnName;
	this.URL = strURL;
	this.Method = strMethod;
	var intDelayedRefreshHandle = 0;
	var fncLastCallback = null;
	var objLastAutoComplete = null;
	var arrLastList = null;
	this.LastSearch = null;
	var strLastRequest = null;
	this.TextChanged = null;
	this.Loading = null;
	var blnIsLoading = false;
	this.FireItemSelected = false;
	this.ModifyData = null;
	this.ModifyList = null;

	//==========================================
	// Get the data from the webservice
	//==========================================
	this.GetData = function GetData(objAutoComplete, fncCallback, blnFireItemSelected)
	{
		if (intDelayedRefreshHandle != 0)
			window.clearTimeout(intDelayedRefreshHandle);
		intDelayedRefreshHandle = 0;

		objAutoComplete.TextChanged = objAutoComplete_TextChanged;
		objAutoComplete.Blur = objAutoComplete_Blur;

		var strSearch = objAutoComplete.Input.value;

//		if (this.LastSearch != null && strSearch.length >= this.LastSearch.length && strSearch.indexOf(this.LastSearch) == 0)
//		{
//			fncCallback(arrLastList, blnFireItemSelected);
//			return;
//		}

		this.FireItemSelected = blnFireItemSelected;
		fncLastCallback = fncCallback;
		objLastAutoComplete = objAutoComplete;
		intDelayedRefreshHandle = window.setTimeout(fncDelayedRefresh, 300);
	}

	//==========================================
	// User has left the auto complete entry field, fire the request NOW
	//==========================================
	function objAutoComplete_Blur(objAutoComplete, evt)
	{
		try
		{
			evt = window.event ? window.event : evt;
			var target = evt.srcElement ? evt.srcElement : evt.target;
			var strSearch = target.value;

			if (strSearch == THIS.LastSearch)
				return;

			objLastAutoComplete = objAutoComplete;

			if (intDelayedRefreshHandle != 0)
				window.clearTimeout(intDelayedRefreshHandle);

			intDelayedRefreshHandle = 0;

			if (THIS.LastSearch != null && strSearch.length >= THIS.LastSearch.length && strSearch.indexOf(THIS.LastSearch) == 0)
				return;
			else
				fncDelayedRefresh();
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}

	//==========================================
	// The text has changed
	//==========================================
	function objAutoComplete_TextChanged(objAutoComplete, strSearch)
	{
		try
		{
			if (THIS.LastSearch != null && strSearch.length >= THIS.LastSearch.length && strSearch.indexOf(THIS.LastSearch) == 0)
				return;

			THIS.LastSearch = null;
			arrLastList = null;
			objAutoComplete.Data = null;
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
		finally
		{
			if (THIS.TextChanged != null)
				THIS.TextChanged(objAutoComplete, strSearch);
		}
	}

	//==========================================
	// Perform a delayed refresh
	//==========================================
	function fncDelayedRefresh()
	{
		try
		{
			if (intDelayedRefreshHandle != 0)
				window.clearTimeout(intDelayedRefreshHandle);

			intDelayedRefreshHandle = 0;

			if (objLastAutoComplete == null || objLastAutoComplete.Input == null)
				return;

			var strSearch = objLastAutoComplete.Input.value;

//			if (strLastRequest != null && strSearch.length >= strLastRequest.length && strSearch.indexOf(strLastRequest) == 0)
//				return;

//			if (THIS.PrepareRequest == null)
//				return;

			var params = new SOAPClientParameters();

			if (!THIS.PrepareRequest(THIS, objLastAutoComplete, params))
				return;

			strLastRequest = strSearch;
			SetInputLoading(objLastAutoComplete.Input, true);
			SOAPClient.invoke(THIS.URL, THIS.Method, params, true, UpdateAutoComplete, [fncLastCallback, strSearch]);
		}
		catch (exc)
		{
			SetInputLoading(objLastAutoComplete.Input, false);
			HtmlPopup.Error(exc);
		}
		finally
		{
			fncLastCallback = null;
		}
	}

	//==========================================
	// Some data has been received, update the auto complete list
	//==========================================
	function UpdateAutoComplete(strXML, docXML, arrCommands)
	{
		strLastRequest = null;
		try
		{
			var fncCallback = arrCommands[0];
			var strSearch = arrCommands[1];

			if (typeof (strXML) == "object" && strXML != null)
				throw new Error(docXML + "\nSearch = '" + strSearch + "'\nCallback = " + fncCallback);

			if (strXML == null)
				return;

			if (strXML.indexOf("<") != 0)
				throw new Error(strXML);

			var recordset = new Recordset();
			recordset.LoadXML(strXML);

			THIS.LastSearch = strSearch;

			var arrList = new Array();
			var intCount = 0;

			while (!recordset.EOF())
			{
				var strData = recordset[THIS.ColumnName];

				if (THIS.ModifyData != null)
					strData = THIS.ModifyData(THIS, recordset, strData);
				
				if (strData != "")
					arrList.push(strData);

				recordset.MoveNext();
				intCount++;
			}

			if (THIS.ModifyList != null)
				THIS.ModifyList(THIS, arrList);

			arrLastList = arrList;

			if (fncCallback != null)
				fncCallback(arrList, THIS.FireItemSelected);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
			arrLastList = null;
			THIS.LastSearch = null;
			strLastRequest = null;
		}
		finally
		{
			SetInputLoading(objLastAutoComplete.Input, false);
		}
	}

	function SetInputLoading(txtInput, blnLoading)
	{
		try
		{
			if (txtInput == null)
				return;

			if (blnLoading == blnIsLoading)
				return;

			blnIsLoading = blnLoading;
			txtInput.className = txtInput.className.replace(/autoCompleteLoading/g, "");

			if (blnLoading)
				txtInput.className += " autoCompleteLoading";

			if (THIS.Loading != null)
				THIS.Loading(THIS, txtInput.value, blnLoading);
		}
		catch (exc)
		{
			HtmlPopup.Error(exc);
		}
	}
}
