﻿var Functions = new FunctionsClass();

//======================================================
// Functions class
//======================================================
function FunctionsClass()
{
	var THIS = this;
	var winLockLayer = null;
	var winMessage = null;
	var winMessageText = null;
	var zIndex = 2000;
	
	this.Name = 'FunctionsClass';
	
	//==========================================
	// Set a cookie value.
	//==========================================
	this.SetCookie = function SetCookie(Name, Value, ExpireDays)
	{
		try
		{
			var dtDate = new Date();

			dtDate.setDate(dtDate.getDate() + ExpireDays);
			document.cookie = Name + "=" + escape(Value) + ((ExpireDays==null) ? "" : ";expires=" + dtDate.toGMTString()) + ";path=/";
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.SetCookie()\n\n' + exc);
		}
		return;
	}

	//==========================================
	// Get a cookie value.
	//==========================================
	this.GetCookie = function GetCookie(Name)
	{
		try
		{
			// Check if there are any cookies.
			if (document.cookie.length > 0)
			{
				var aCookies = unescape(document.cookie).split('; ');
				
				// Loop through the cookies and try and match the passed name.
				Name = '|' + Name;
				for (var Cookie in aCookies)
				{
					aCookies[Cookie] = '|' + aCookies[Cookie];
					if (aCookies[Cookie].indexOf(Name) == 0)
					{
						return aCookies[Cookie].substring((aCookies[Cookie].indexOf('=') + 1));
					}
				}
			}
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.GetCookie()\n\n' + exc);
		}
		return "";
	}
	
	//==================================================
	// Cancel bubble.
	//==================================================
	this.CancelBubble = function CancelBubble(evt)
	{
		try
		{
			if (document.body.addEventListener)
			{
				evt.stopPropagation();
			}
			else
			{
				if (window.event)
				{
					window.event.cancelBubble = true;
				}
				else
				{
					evt.cancelBubble = true;
				}
			}
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.CancelBubble()\n\n' + exc);
		}
		return false;
	}
	
	//==================================================
	// Key press event handler.
	//==================================================
	this.KeyPress = function KeyPress(evt, CallBack)
	{
		try
		{
			var objSourceElement = evt.srcElement ? evt.srcElement : evt.target;
			var intKeyCode = evt.keyCode ? evt.keyCode : evt.which;

			// Check the keycode.
			if (intKeyCode == 13)
			{
				if (CallBack != undefined)
					CallBack(evt);
				
				if (evt.preventDefault)
					evt.returnValue = false;

				return false;
			}
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.KeyPress()\n\n' + exc);
		}
		return;
	}
	
	//==================================================
	// GUID.
	//==================================================
	this.GUID = function GUID()
	{
		try
		{
			var chars = '0123456789abcdef'.split('');

			var uuid = [], rnd = Math.random, r;
			uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
			uuid[14] = '4'; // version 4

			for (var i = 0; i < 36; i++)
			{
				if (!uuid[i])
				{
				r = 0 | rnd()*16;

				uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r & 0xf];
				}
			}
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.GUID()\n\n' + exc);
		}
		return uuid.join('');
	}
	
	//==================================================
	// Display an error to the user.
	//==================================================
	this.WaitWindow = function WaitWindow(Message)
	{
		try
		{
			var WaitWindow = new WaitWindowClass();
			WaitWindow.Name = this.GUID();
			WaitWindow.XML = '<Data><ActionText>' + Message + '</ActionText></Data>';
			WaitWindow.Open();
			return WaitWindow;
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.WaitWindow()\n\n' + exc);
		}
		return null;
	}

	//==================================================
	// Generic onerror handler.
	//==================================================
	this.OnError = function OnError(Message, URL, LineNumber)
	{
		this.DisplayError('Message: ' + Message + '\nURL: ' + URL + '\nLine Number: ' + LineNumber);
		return;
	}
	
	//==================================================
	// Display an error to the user.
	//==================================================
	this.DisplayError = function DisplayError(Error, CallBack)
	{
		try
		{
			// Check if the callback handler has been defined.
			if ((CallBack == undefined) || (CallBack == null))
				CallBack = THIS.btnDisplayMessagePromptOK_Click
			
			Error = Error.replace(/\n/gi, '<br/>');

			var PopupWindow = new PopupWindowClass();
			PopupWindow.Name = this.GUID();
			PopupWindow.Title = 'Truckfile Application Error';
			PopupWindow.XML = '<Data><Icon>Error</Icon><ActionText>' + Error + '</ActionText></Data>';
			PopupWindow.XSLT = '/Xslt/Prompt.xslt';
			PopupWindow.CallBack = CallBack;
			PopupWindow.Message = true;
			PopupWindow.Open();
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.DisplayError()\n\n' + exc);
		}
		return;
	}
	
	//==================================================
	// Display a message to the user.
	//==================================================
	this.DisplayMessage = function DisplayMessage(Message, Title, Icon, CallBack)
	{
		try
		{
			// Check the title.
			Title = (Title == undefined) ? 'Truckfile' : Title;
			Message = Message.replace(/\n/gi, '<br/>');

			var PopupWindow = new PopupWindowClass();
			PopupWindow.Name = this.GUID();
			PopupWindow.Title = Title;
			PopupWindow.XML = '<Data><Icon>' + Icon + '</Icon><ActionText>' + Message + '</ActionText></Data>';
			PopupWindow.XSLT = '/Xslt/Prompt.xslt';
			PopupWindow.CallBack = CallBack;
			PopupWindow.Message = true;
			PopupWindow.Open();
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.DisplayMessage()\n\n' + exc);
		}
		return;
	}
	
	//==================================================
	// Display a message to the user.
	//==================================================
	this.DisplayWindow = function DisplayWindow(Title, XML, XSLT, Buttons, CallBack)
	{
		try
		{
			// Check the title.
			Title = (Title == undefined) ? 'Truckfile' : Title;

			var PopupWindow = new PopupWindowClass();
			PopupWindow.Name = this.GUID();
			PopupWindow.Title = Title;
			PopupWindow.XML = XML;
			PopupWindow.XSLT = XSLT;
			PopupWindow.Buttons = Buttons;
			PopupWindow.CallBack = CallBack;
			PopupWindow.Open();
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.DisplayWindow()\n\n' + exc);
		}
		return;
	}
	
	//=====================================================================
	// Left pad a value.
	//=====================================================================
	this.PadLeft = function PadLeft(Value, Length, Character)
	{
		try
		{
			var objRegExp = new RegExp(".{" + Length + "}$");
			var pad = "";
			
			if (!Character) Character = " ";
			do  {
				pad += Character;
			}while(pad.length < Length);
			
			return objRegExp.exec(pad + Value)[0];
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.PadLeft()\n\n' + exc);
		}
		return null;
	}
	
	//=====================================================================
	// Right pad a value.
	//=====================================================================
	this.PadRight = function PadRight(Value, Length, Character)
	{
		try
		{
			var objRegExp = new RegExp("^.{" + Length + "}");
			var pad = "";

			if (!Character) Character = " ";
			do {
				pad += Character;
			} while (pad.length < Length);

			return objRegExp.exec(Value + pad)[0];
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.PadRight()\n\n' + exc);
		}
		return null;
	}
	
	//=====================================================================
	// Replace ampersand.
	//=====================================================================
	this.Ampersand = function Ampersand(Text)
	{
		try
		{
			// Check if the browser is Internet Explorer.
			if (BrowserDetect.browser == 'Explorer')
				Text = Text.replace(/&#38;/gi, '&');
			
			return Text;
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.Ampersand()\n\n' + exc);
		}
		return null;
	}

	//=====================================================================
	// Format the XML for ampersand.
	//=====================================================================
	this.FormatXMLAmpersand = function FormatXMLAmpersand(XML)
	{
		try
		{
			XML = XML.replace(/&amp;/gi, '&#38;');
			XML = XML.replace(/  /gi, '');
			XML = XML.replace(/amp;/gi, '');
			return XML;
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.FormatXMLAmpersand()\n\n' + exc);
		}
		return null;
	}
	
	//===================================================================
	// Clean the HTML Content to remove 
	//===================================================================
	this.CleanHTMLContent = function CleanHTMLContent(strHTMLContent)
	{
		strHTMLContent = Functions.FormatXMLAmpersand(strHTMLContent);
		strHTMLContent = strHTMLContent.replace(/#38;/gi,'');
		strHTMLContent = strHTMLContent.replace(/&lt;/gi, '<');
		strHTMLContent = strHTMLContent.replace(/&gt;/gi, '>');
		return strHTMLContent;
	}
	
	//=====================================================================
	// Check if an email address is valid.
	//=====================================================================
	this.ValidateEmailAddress = function ValidateEmailAddress(EmailAddress)
	{
		try
		{
			//rules:
			//1. Must contain an @ character
			//2. Must contain a . character
			//3. The @ character must not be the first or last character in the string
			//4. The . character must not be the first or last character in the string
			//5. only 1 @ character can exist
			//6. Only uses letters, numbers, . and @ (spaces not allowed)
			//7. . cannot be immediately before or after the @
			//8. Must not be blank
			//9. Must be at least 2 letters after the last .
			//10. character '.' cannot appear 2 or more times consecutively
			//11. Must contain at least 1 . after the @

			//rule 8;
			if (EmailAddress == "")
				return false;

			var arrAllowedChars = new Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", "@", "-", "_");

			//rule 1;
			if (EmailAddress.indexOf("@") == -1)
				return false;

			//rule 2;
			if (EmailAddress.indexOf(".") == -1)
				return false;

			//rule 3;
			if (EmailAddress.indexOf("@") == 0 || EmailAddress.charAt(EmailAddress.length - 1) == "@")
				return false;

			//rule 4;
			if (EmailAddress.indexOf(".") == 0 || EmailAddress.charAt(EmailAddress.length - 1) == ".")
				return false;

			//rule 9;
			if (EmailAddress[EmailAddress.length - 1] == "." || EmailAddress.charAt(EmailAddress.length - 2) == ".")
				return false;

			//rule 7;
			if (EmailAddress.indexOf("@.") != -1 || EmailAddress.indexOf(".@") != -1)
				return false;

			//rule 10;
			if (EmailAddress.indexOf("..") != -1)
				return false;

			var blnIllegalChars = false;
			var intAtCount = 0; //number of @ characters
			EmailAddress = EmailAddress.toLowerCase();
			
			//rule 6 and 5
			for (var intIndex = 0; intIndex < EmailAddress.length; intIndex++)
			{
				var chrLetter = EmailAddress.substring(intIndex, intIndex + 1);
				var blnFound = false;
				
				for (var intLetter = 0; intLetter < arrAllowedChars.length; intLetter++)
				{
					var chrValid = arrAllowedChars[intLetter];

					if (chrValid == chrLetter)
					{
						blnFound = true;
						break;
					}
				}

				if (blnFound == false)
				{
					//chrLetter is not a valid letter
					return false; //rule 6
				}

				if (chrLetter == "@")
					intAtCount++;

				if (intAtCount > 1)
					return false; //rule 5
			}

			var strDomain = EmailAddress.substring(EmailAddress.indexOf("@") + 1);

			if (strDomain.indexOf(".") == -1)
				return false; //rule 11
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.ValidateTelephoneNumber()\n\n' + exc);
		}
		return true;
	}

	//=====================================================================
	// Check if a telephone number is valid
	//=====================================================================
	this.ValidateTelephoneNumber = function ValidateTelephoneNumber(TelephoneNumber)
	{
		try
		{
			//rules:
			//1: must only contain valid characters
			//2: must be at least 10 letters
			//3: cannot contain + more than once
			//4: must start with 0 or +

			if (TelephoneNumber == "")
				return true;

			var arrAllowedChars = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", " ");

			var blnIllegalChars = false;
			var intPlusCount = 0;
			TelephoneNumber = TelephoneNumber.toLowerCase();

			//rule 1
			for (var intIndex = 0; intIndex < TelephoneNumber.length; intIndex++)
			{
				var chrLetter = TelephoneNumber.substring(intIndex, intIndex + 1);

				if (intIndex == 0)
				{
					if (chrLetter != '0' && chrLetter != '+')
						return false; //rule 4
				}

				var blnFound = false;

				for (var intLetter = 0; intLetter < arrAllowedChars.length; intLetter++)
				{
					var chrValid = arrAllowedChars[intLetter];

					if (chrValid == chrLetter)
					{
						blnFound = true;
						break;
					}
				}

				if (blnFound == false)
				{
					//chrLetter is not a valid letter
					return false; //rule 1
				}

				if (chrLetter == '+')
					intPlusCount++;

				if (intPlusCount > 1)
					return false; // rule 3
			}

			if (TelephoneNumber.length < 11)
				return false; //rule 2
		}
		catch(exc)
		{
			Functions.DisplayError(this.Name + '.ValidateTelephoneNumber()\n\n' + exc);
		}
		return true;
	}

	//=====================================================================
	// Lookup search initialisation.
	//=====================================================================
	this.LookupSearchInitialise = function LookupSearchInitialise(SearchTimeout, DisplayCount, Container)
	{
		try
		{
			// Quick search variables.
			THIS.SearchTimeout = (SearchTimeout == 0) ? 700 : SearchTimeout;
			THIS.DisplayCount = (DisplayCount == 0) ? 20 : DisplayCount;
			THIS.intHideQuickSearchTimer = 0;
			THIS.QuickSearchHide = 2000;
			THIS.DataNotFoundMessage = false;
			THIS.QuickSearchResultsRS = null;
			THIS.Container = Container;
			
			// Check if the quick search layer has already been added.
			if ((document.getElementById('QuickSearchLayer') == undefined) || (document.getElementById('QuickSearchLayer') == null))
			{
				THIS.QuickSearchLayer = document.createElement('DIV');
				THIS.QuickSearchLayer.id = 'QuickSearchLayer';
				THIS.QuickSearchLayerShadow = document.createElement('DIV');
				THIS.QuickSearchLayerShadow.id = 'QuickSearchLayerShadow';
				THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
				THIS.QuickSearchLayerShadow.innerHTML = '&nbsp;';
				THIS.QuickSearchLayerShadow.className = 'QuickSearchShadow';
				THIS.QuickSearchLayerShadow.style.display = 'none';
				THIS.Container.appendChild(THIS.QuickSearchLayer);
				THIS.Container.appendChild(THIS.QuickSearchLayerShadow);
			}
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.LookupSearchInitialise():\n\n' + exc);
		}
		return;
	}

	//==================================================
	// Lookup search textbox (e.g make etc...) key up event handler.
	//==================================================
	this.LookupSearch = function LookupSearch(evt, Recordset, OnChange, Callback, StringLength)
	{
		try
		{
			// Check the browser.	
			if ((BrowserDetect.browser == 'Explorer') && ((BrowserDetect.version == 6) || (BrowserDetect.version == 7)))
			{
				THIS.ElementTop = (evt.clientY - evt.offsetY);
				THIS.ElementLeft = (evt.clientX - evt.offsetX);
			}
			
			window.clearTimeout(THIS.intSearchTimeOut);
			THIS.DisplaySearchResults = false;

			var objSourceElement = evt.srcElement ? evt.srcElement : evt.target;
			var intKeyCode = evt.keyCode ? evt.keyCode : evt.which;
			
			if ((intKeyCode == 16) || (intKeyCode == 35) || (intKeyCode == 36) || (intKeyCode == 37) || (intKeyCode == 39))
				return;

			var blnValid = ((intKeyCode > 47 && intKeyCode < 58) || (intKeyCode > 64 && intKeyCode < 91) || (intKeyCode > 95 && intKeyCode < 123) || (intKeyCode == 8) || (intKeyCode == 8) || (intKeyCode == 13));

			THIS.Data = new Object();
			THIS.Data['SourceElement'] = objSourceElement;
			THIS.Data['StringLength'] = StringLength;
			THIS.Data['Callback'] = Callback;
			THIS.Data['Recordset'] = Recordset;

			// Check the keycode.
			if (!blnValid)
			{
				if (Callback)
					Callback(undefined, THIS.Data);

				if (evt.preventDefault)
					evt.returnValue = false;

				return false;
			}
			
			// Raise the onchange event handler.
			if (OnChange)
				OnChange();

			// Check the length of the textbox.
			if (objSourceElement.value.length >= StringLength)
			{
				THIS.SourceElement = objSourceElement;
				THIS.DisplaySearchResults = true;
				THIS.intSearchTimeOut = window.setTimeout(THIS.InvokeLookupSearch, THIS.SearchTimeout);
			}
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.LookupSearch():\n\n' + exc);
		}
		return;
	}
	
	//==================================================
	// Invoke the lookup search.
	//==================================================
	this.InvokeLookupSearch = function InvokeLookupSearch()
	{
		try
		{
			window.clearTimeout(THIS.intSearchTimeOut);
			
			if (!THIS.DisplaySearchResults)
				return;

			THIS.SourceElement.className += ' Search';
				
			var soapClient = new SoapClient();
			
			// Check which item is being searched for.
			switch (THIS.SourceElement.id)
			{
				case 'txtMake':
					THIS.SearchType = 'Make';
					THIS.Data['Recordset'].Rows[THIS.Data['Recordset'].RecordPointer]['MakeId'] = 0;
					
					THIS.Data['ValueMember'] = 'MakeID';
					THIS.Data['DisplayMember'] = 'Make';
					soapClient.AddParameter('Name', escape(THIS.SourceElement.value));
					soapClient.SendRequest('/WebServices/Part.asmx', 'http://www.truckfile.co.uk/', 'Make_Select', THIS.LookupSearchCallback, THIS.Data);
					break;
					
				case 'txtSupplier':
					THIS.SearchType = 'Supplier';
					THIS.Data['Recordset'].Rows[THIS.Data['Recordset'].RecordPointer]['SupplierId'] = 0;
					
					THIS.Data['ValueMember'] = 'SupplierId';
					THIS.Data['DisplayMember'] = 'Supplier';
					soapClient.AddParameter('Name', escape(THIS.SourceElement.value));
					soapClient.SendRequest('/WebServices/Part.asmx', 'http://www.truckfile.co.uk/', 'Supplier_Select', THIS.LookupSearchCallback, THIS.Data);
					break;
					
				case 'txtPartType':
					THIS.SearchType = 'Part Type';
					THIS.Data['Recordset'].Rows[THIS.Data['Recordset'].RecordPointer]['PartTypeId'] = 0;
					
					THIS.Data['ValueMember'] = 'PartTypeId';
					THIS.Data['DisplayMember'] = 'PartType';
					soapClient.AddParameter('Name', escape(THIS.SourceElement.value));
					soapClient.SendRequest('/WebServices/Part.asmx', 'http://www.truckfile.co.uk/', 'PartType_Select2', THIS.LookupSearchCallback, THIS.Data);
					break;

				case 'txtOperator':
				case 'txtVehicle_Operator':
					THIS.SearchType = 'Operator';
					THIS.Data['ValueMember'] = 'Company_ID';
					THIS.Data['DisplayMember'] = 'Company_Name';
					soapClient.AddParameter('Search', escape(THIS.SourceElement.value));
					soapClient.AddParameter('CompanyType', 'OPT');
					soapClient.SendRequest('/WebServices/Common.asmx', 'http://www.truckfile.co.uk/', 'CompanySearch', THIS.LookupSearchCallback, THIS.Data);
					break;
			}
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.InvokeLookupSearch():\n\n' + exc);
		}
		return;
	}
	
	//==================================================
	// Lookup search callback event handler.
	//==================================================
	this.LookupSearchCallback = function LookupSearchCallback(Response, Data)
	{
		try
		{
			if (!THIS.DisplaySearchResults)
				return;

			// Cancel the quick search timer.
			THIS.CancelHideQuickSearchTimer();
			
			var SourceElement = Data['SourceElement'];
			var Callback = Data['Callback'];
			var strValueMember = Data['ValueMember'];
			THIS.StringLength = Data['StringLength'];
			
			// Check the response.
			if (Response == undefined)
			{
				THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
				THIS.QuickSearchLayerShadow.style.display = 'none';
				SourceElement.className = SourceElement.className.replace(' Search', '');
				return;
			}
			
			var aResponse = Response.split('|');
			
			// Check if an error occured.
			if (aResponse[0] == 'ERROR')
			{
				Functions.DisplayError(aResponse[1]);
				return;
			}
			
			// Check if the result set already exist.
			if (THIS.QuickSearchResultsRS != null)
				delete THIS.QuickSearchResultsRS;
			
			THIS.QuickSearchSourceElement = SourceElement;
			THIS.QuickSearchResultsRS = new RecordSet();
			THIS.QuickSearchResultsRS.LoadXML(aResponse[1], 'Data');
			
			// View the data.
			if (window.location.hostname == 'local.www.truckfile.co.uk')
			{
				var soapClient = new SoapClient();
				soapClient.AddParameter('Name', 'QuickSearchData.xml');
				soapClient.AddParameter('Data', escape(aResponse[1]));
				soapClient.SendRequest('/WebServices/Common.asmx', 'http://www.truckfile.co.uk/', 'ViewXMLData');
			}
			
			// Check if there are any results.
			if (THIS.QuickSearchResultsRS.RecordCount > 0)
			{
				if (THIS.QuickSearchSourceElement.value.length < THIS.StringLength)
				{
					THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
					THIS.QuickSearchLayerShadow.style.display = 'none';
					THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
					return;
				}
				
				// Check if only one result was found.
				if (THIS.QuickSearchResultsRS.RecordCount == 1)
				{
					THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
					THIS.QuickSearchLayerShadow.style.display = 'none';
					THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
					Callback(THIS.QuickSearchSourceElement, THIS.QuickSearchResultsRS, THIS.QuickSearchResultsRS[strValueMember]);
				}
				else
				{
					// Check the browser.	
					if ((BrowserDetect.browser == 'Explorer') && ((BrowserDetect.version == 6) || (BrowserDetect.version == 7)) && ((THIS.QuickSearchResultsRS.RecordCount > THIS.DisplayCount)))
					{
						THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
						Functions.DisplayMessage('Your browser is not capable of displaying all the results, please consider using Internet Explorer 8, Firefox of Safari. Please contact your system adinmistrator for more information.', 'Quick Search Results', 'Information');
						return;
					}

					// Load the content.
					var objXSLTransform = new XSLTransform();
					objXSLTransform.Transform(THIS.QuickSearchLayer, '/Xslt/LookupSearchResults.xslt?DisplayMember=' + Data['DisplayMember'] + '&DisplayCount=' + THIS.DisplayCount, aResponse[1], THIS.QuickSearchLayerLoaded);
					delete objXSLTransform;
				}
			}
			else
			{
				THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
				THIS.QuickSearchLayerShadow.style.display = 'none';
				THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
				
				Functions.DisplayMessage('Unfortunately \'' + THIS.QuickSearchSourceElement.value + '\' was not found.', THIS.SearchType +  ' Not Found', 'Information', THIS.CloseDataNotFoundMessage);
			}
		}
		catch (exc)
		{
			THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
			Functions.DisplayError(this.Name + '.LookupSearchCallback():\n\n' + exc);
		}
		return;
	}
	
	//====================================================
	// Quick search layer content loaded handler.
	//====================================================
	this.QuickSearchLayerLoaded = function QuickSearchLayerLoaded()
	{
		try
		{
			if (THIS.QuickSearchSourceElement.value.length < THIS.QuickSearchLength)
			{
				THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
				THIS.QuickSearchLayerShadow.style.display = 'none';
				THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
				return;
			}

			var intOffset = (BrowserDetect.browser == 'Explorer') ? 1 : 0;
			
			// Set the width and height of the quick search layer.
			THIS.QuickSearchLayer.style.width = (THIS.QuickSearchSourceElement.offsetWidth - 2) + 'px';
			THIS.QuickSearchLayer.scrollTop = 0;
			
			// Check if the element top and left variables exist.
			if (THIS.ElementTop)
			{
				THIS.QuickSearchLayer.style.top = ((THIS.ElementTop + THIS.QuickSearchSourceElement.offsetHeight) - 4) + 'px';
				THIS.QuickSearchLayer.style.left = (THIS.ElementLeft - 3) + 'px';
			}
			else
			{
				if (THIS.QuickSearchSourceElement.offsetParent.offsetParent == 'DIV')
				{
					THIS.QuickSearchLayer.style.top = (THIS.QuickSearchSourceElement.offsetParent.offsetParent.offsetTop + THIS.QuickSearchSourceElement.offsetParent.offsetTop + THIS.QuickSearchSourceElement.offsetTop) + (THIS.QuickSearchSourceElement.offsetHeight - 27) + 'px';
					THIS.QuickSearchLayer.style.left = ((THIS.QuickSearchSourceElement.offsetParent.offsetParent.offsetLeft + THIS.QuickSearchSourceElement.offsetParent.offsetLeft + THIS.QuickSearchSourceElement.offsetLeft) - intOffset)+ 'px';
				}
				else
				{
					THIS.QuickSearchLayer.style.top = ((THIS.QuickSearchSourceElement.offsetTop + THIS.QuickSearchSourceElement.offsetHeight) - 1)+ 'px';
					THIS.QuickSearchLayer.style.left = (THIS.QuickSearchSourceElement.offsetLeft) + 'px';
				}
			}
			
			THIS.QuickSearchLayer.className = 'QuickSearchLayerShow';
			THIS.QuickSearchLayer.onmouseout = THIS.StartHideQuickSearchTimer;
			THIS.QuickSearchLayer.onmouseover = THIS.CancelHideQuickSearchTimer;
			
			if (THIS.QuickSearchResultsRS.RecordCount > THIS.DisplayCount)
			{
				var QuickSearchContainer = document.getElementById('QuickSearchContainer');
				
				if (THIS.QuickSearchSourceElement.offsetParent.offsetParent == 'DIV')
				{
					QuickSearchContainer.style.height = (THIS.Container.offsetHeight - 50) + 'px';
				}
				else
				{
					QuickSearchContainer.style.height = ((THIS.QuickSearchSourceElement.offsetParent.offsetHeight - THIS.QuickSearchSourceElement.offsetTop) - 50) + 'px';
				}

				QuickSearchContainer.style.overflowY = 'scroll';
				QuickSearchContainer.style.borderTop = 'solid 1px #000';
				QuickSearchContainer.style.borderBottom = 'solid 1px #000';
			}
			
			THIS.QuickSearchLayerShadow.style.top = THIS.QuickSearchLayer.offsetTop + 5 + 'px';
			THIS.QuickSearchLayerShadow.style.left = THIS.QuickSearchLayer.offsetLeft + 5 + 'px';
			THIS.QuickSearchLayerShadow.style.width = THIS.QuickSearchLayer.offsetWidth + 'px';
			THIS.QuickSearchLayerShadow.style.height = THIS.QuickSearchLayer.offsetHeight + 'px';
			THIS.QuickSearchLayerShadow.style.display = 'block';

			THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
			THIS.StartHideQuickSearchTimer();
		}
		catch(exc)
		{
			THIS.QuickSearchSourceElement.className = THIS.QuickSearchSourceElement.className.replace(' Search', '');
			Functions.DisplayError(this.Name + '.QuickSearchLayerLoaded():\n\n' + exc);
		}
		return;
	}

	//====================================================
	// Lookup search item click event handler.
	//====================================================
	this.LookupSearchItem_Click = function LookupSearchItem_Click(ValueMember)
	{
		try
		{
			// Invoke the call back handler.
			THIS.Data['Callback'](THIS.QuickSearchSourceElement, THIS.QuickSearchResultsRS, ValueMember);
			THIS.HideQuickSearch();
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.LookupSearchItem_Click():\n\n' + exc);
		}
		return;
	}

	//====================================================
	// Start the timer to hide quick search layer.
	//====================================================
	this.StartHideQuickSearchTimer = function StartHideQuickSearchTimer()
	{
		try
		{
			THIS.intHideQuickSearchTimer = window.setTimeout(THIS.HideQuickSearch, THIS.QuickSearchHide);
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.StartHideQuickSearchTimer():\n\n' + exc);
		}
		return;
	}
	
	//====================================================
	// Cancel the hide quick search layer timer.
	//====================================================
	this.CancelHideQuickSearchTimer = function CancelHideQuickSearchTimer()
	{
		try
		{
			window.clearTimeout(THIS.intHideQuickSearchTimer);
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.CancelHideQuickSearchTimer():\n\n' + exc);
		}
		return;
	}

	//====================================================
	// Hide quick search layer.
	//====================================================
	this.HideQuickSearch = function HideQuickSearch()
	{
		try
		{
			window.clearTimeout(THIS.intHideQuickSearchTimer);
			
			if (THIS.QuickSearchLayer)
			{
				THIS.QuickSearchLayer.className = 'QuickSearchLayerHide';
				THIS.QuickSearchLayerShadow.style.display = 'none';
			}
		}
		catch (exc)
		{
			Functions.DisplayError(this.Name + '.HideQuickSearch():\n\n' + exc);
		}
		return;
	}

	return;
}
