		var req;
		// This url will need to change in the final version to avoid XSS
		var url="boatsuggest.php?mm=";
		var selectedMake;
		var selectedRow;
		var lengthMList;
		var deletePressed;
		var ready = true;
		var timeoutDelay = 250;
		var times = 0;
		var timeoutHandler = null;
		function Initialize()
		{
			try
			{
				req=new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(e)
			{
				try
				{
					req=new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch(oc)
				{
					req=null;
				}
			}
		
			if(!req&&typeof XMLHttpRequest!="undefined")
			{
				req=new XMLHttpRequest();
			}
		
		}
		function doSearch(key,keyEvent,fromKeyboard)
		{

			Initialize();
			if (keyEvent.keyCode)
				{
				keyCode = keyEvent.keyCode;
				}
			else
				{
				keyCode = keyEvent;
				}
			key = document.getElementById('manufacturer').value;
			if(req != null && key != null && key != "")
			{
				if ((keyCode != 8 && keyCode < 32) || (keyCode >= 33 && keyCode <= 45) || (keyCode >= 112 && keyCode <= 123))
				{
				deletePressed = false;
				switch (keyCode)
					{
					case 40: //Down arrow
						if (selectedRow <= lengthMList - 2) //Don't arrow off the bottom of the list
							{
							llAllRows(selectedRow);
							selectedRow++;
							hl(selectedRow);
							arrowOver(selectedRow);
							//alert(selectedRow);
							}
						break;
					case 38: // Up arrow
						if (selectedRow >= 1) //Don't arrow off the top of the list
							{
							llAllRows(selectedRow);
							selectedRow--;
							hl(selectedRow);
							arrowOver(selectedRow);
							}
						break;
					case 13: // Enter
						HideDiv("autocomplete");
						break;
					case 27: //Esc
						HideDiv("autocomplete");
						break;
				    // Field only receives the tab key onfocus not onblur so tabbing away isn't detected
				    // To get round this there's an onblur in the boatsuggest input field (manufacturer)
				    // which hides the dropdown div
					case 9: //Tab
						HideDiv("autocomplete");
						return false;
						break;
					}
				}
				else
				{
					if (keyCode == 8)//Backspace
						{
						key = key.substring(0,key.length);
						deletePressed = true;
						}
					else
						{
						if (keyCode == 46)//Delete
							{
							deletePressed = true;
							}
						else
							{
							deletePressed = false;
							}
						}
					if (keyCode == 32)
						{
						//key = key.substring(0,key.length-1);
						//key = key + ' ';
						}
					if (ready)	
						{
						ready = false;
						strKey = new String(key);
						key = strKey.replace("&","%26");
						var fullUrl = url+key+'&'; //The & at the end of the URL allows a space to be entered as the last character of the search string
						req.onreadystatechange = Process;
						//alert(fullUrl);
						req.open("GET", fullUrl, true); 
						req.send(null);
						selectedRow = -1; //No row is selected at this stage
						}
					else
						{
						if (fromKeyboard)
							{
							clearTimeout(timeoutHandler);
							timeoutHandler = setTimeout("allowSend('"+ key + "'," + keyCode + ");",timeoutDelay);
							//window.status = 'timing'
							}
						}
				}
			}
			else
			{
				HideDiv("autocomplete");
			}
		
		}
		
		function allowSend(key,keyEvent)
			{
			ready = true;
			doSearch(key,keyEvent,false);
			//window.status = 'not timing';
			}
		
		function Process()
		{
			if (req.readyState == 4)
				{
					if (req.status == 200)
					{
						if(req.responseText=="")
							document.getElementById("autocomplete").innerHTML ="No matching results";
						else
							eval(req.responseText);
							//alert(req.responseText);
					}
					/*
					if we can't get the data from the server, then do nothing
					*/
					else
					{
						document.getElementById("autocomplete").innerHTML="There was a problem retrieving data: " + req.status + " - " + req.statusText;
					}
				}
		}
		
		function ShowDiv(divid)
		{
			if (document.layers) document.layers[divid].visibility="show";
			else document.getElementById(divid).style.visibility="visible";
		}
		
		function HideDiv(divid)
		{
			if (document.layers) document.layers[divid].visibility="hide";
			else document.getElementById(divid).style.visibility="hidden";
			document.getElementById("autocomplete").innerHTML = "";
			showSelectControls();
		}
		

		function BodyLoad()
		{
			//document.form1.keyword.focus();
		}
		
		function MM(blank,typed,MList,AList)
		/*
		The response from the Ajax call to the server will look like this:
			MM(frameElement, "fairl", new Array("FAIRLINE"), new Array("434 available");
		This function is called by the eval(req.responseText); line in the Process() function.
		*/
		{
			currentTyped = document.getElementById('manufacturer').value;
			if (currentTyped != typed)
				{
				setTimeout("allowSend('"+ currentTyped + "',32);",timeoutDelay);
				//window.status = 'timing';
				return false;
				}
				
			var dropDown;
			dropDown = '';
			lengthMList = MList.length;
			for (i = 0; i < lengthMList; i++)
				{
				dropDown = dropDown + '<ul id="ul' + i + '" onmouseover="mo(\'' + i + '\',\'' + MList[i] + '\')" onmouseout="llAllRows(\'' + i + '\')" onclick="itemClick(\'' + MList[i] + '\')" class="suggest"><li id="liA' + i + '" class="name">' + MList[i] + ' </li><li id="liB' + i + '" class="num">' + AList[i] + '</li></ul>';
				}
			if (MList[0] && !deletePressed) //Check that we have some results and then prefill the text input box with the first result
				{
				strFirstOption = new String(MList[0]);
				document.qSearch.manufacturer.value = strFirstOption;
				//alert(dropDown);
				//Prepare the parameters for selectUntypeChars
				noCharsFirstOption = strFirstOption.length;
				strTyped = new String(typed);
				noCharsTyped = strTyped.length;
				if (!deletePressed)
					{
					selectUntypedChars(document.qSearch.manufacturer,noCharsTyped,noCharsFirstOption);
					}
				ShowDiv("autocomplete");	
				document.getElementById("autocomplete").innerHTML = dropDown;
				//"Select" inputs will display on top of our dropdown Div, so we need to hide them.
				hideSelectControls(16,250,100,400,document.getElementById("autocomplete"));
				}
		}
		
		function arrowOver(row)
			//Called when the user uses the arrow up and arrow down keys to navigate the dropdown Div.
		{
			itemId = 'liA' + row;
			make = document.getElementById(itemId).innerHTML;
			make = trim(make);
			document.qSearch.manufacturer.value = make;
		}
		
		function itemClick(make)
			//If the user clicks on an item in the dropdown Div, select that one and hide the dropdown Div
		{
			document.qSearch.manufacturer.value = make;
			HideDiv("autocomplete");	
		}
				
		function selectUntypedChars(input,selectionStart,selectionEnd) 
			//As the user types, they need to be able to overtype the suggested make. This function
			//will select the suggested part of the make, so when the user types, it will overwrite it
		{ 
			 if (input.setSelectionRange) 
			 { 
				 // Firefox, etc. 
				 input.selectionStart = selectionStart; 
			 } 
			 else
			 { 
				 // IE Only
				var range = input.createTextRange();
				range.moveStart("character", selectionStart);
				range.moveEnd("character", input.length - selectionEnd);
				range.select();
				//input.focus();	
			 } 
		} 
		
		function mo(row, make)
		{
			//alert('Row to blank: ' + selectedRow + '\nRow to hilite: ' + row);
			llAllRows(selectedRow);
			hl(row, make);
		}

		function hl(row, make) //highlight a row and change the typed value in the make field.
		{
			rowname = 'ul' + row;
			//document.getElementById(rowname).style.backgroundColor='#018bb9';
			document.getElementById(rowname).className='suggesthighlight';
			document.getElementById('manufacturer').value = make;
			selectedRow = row;
		}
		function ll(row) //lowlight a row - ie.unselect it
		{
			rowname = 'ul' + row;
			//document.getElementById(rowname).style.backgroundColor='#ffffff';
			document.getElementById(rowname).className='suggest';
			selectedRow = row;
		}
		
		function llAllRows() //lowlight all rows in the dropdown Div (useful if your code isn't very good at knowing which row it needs to lowlight)
		{
			var rows = document.getElementById("autocomplete").getElementsByTagName("ul");
			for (var i=0; i<rows.length; i++)
			{
				var rowname='ul' + i;
				//document.getElementById(rowname).style.backgroundColor='#ffffff';
    			document.getElementById(rowname).className='suggest';
			}
		}
		
		/*
		function showSelectControls()
			//This is the counterpoint to hideSelectControls. This makes visible all the Select controls on the page.
		{
			var selectControls=document.getElementsByTagName("select"); 
			selectControls[i].style.visibility='visible';
		}
		*/
		function hideSelectControls(x,y,width,height,div) 
			//pass this function the details of the dropdown Div and it will hide any Select input controls
			//underneath it.
		{ 
			divWidth = div.clientWidth;
			divHeight = div.clientHeight;
			var divRight=x+divWidth-1; 
			var divBottom=y+divHeight-1; 
			
			
			var selectControls=document.getElementsByTagName("select"); 
			for (var i=0; i<selectControls.length; i++) 
			{ 
				var sx=selectControls[i].offsetLeft; 
				var sy=selectControls[i].offsetTop; 
				var parent=selectControls[i].offsetParent; 
				
				do 
				{ 
					sx += parent.offsetLeft; 
					sy += parent.offsetTop; 
				} while ( parent = parent.offsetParent ); 
		
		
				var sRight=sx+selectControls[i].offsetWidth-1; 
				var sBottom=sy+selectControls[i].offsetHeight-1; 
				//alert("sx: " + sx + "\nsy: " + sy + "\nparent: " + parent + "\nx: " + x + "\ny: " + y + "\nsRight: " + sRight + "\nsBottom: " + sBottom + "\nRight: " + divRight + "\nBottom: " + divBottom);
		
		
				if (sy >= y && sy <= divBottom) 
					selectControls[i].style.visibility='hidden'; 
				else
					selectControls[i].style.visibility='visible'; 
			} 
		}
		
		function showSelectControls()
			//This is the counterpoint to hideSelectControls. This makes visible all the Select controls on the page.
		{
			var selectControls=document.getElementsByTagName("select"); 
			for (var i=0; i<selectControls.length; i++) 
			{
				selectControls[i].style.visibility='visible'; 
			}
			
		}
		
		function trim(stringToTrim) 
			{ 
			stringToTrim=stringToTrim.replace(/^\s*(.*)/, "$1"); 
			stringToTrim=stringToTrim.replace(/(.*?)\s*$/, "$1"); 
			return stringToTrim;
			}

		

