$(document).ready(function() {
	
	$('.smartsearch').each(function() {	
		/* 	
			set everything up when the document loads.
			each input in the page (if there's more than 1!) will have its own object
		*/
		
		var oInputObj=this;	// useful to disambiguate what 'this' refers to.  At the moment it's the input DOM object
		
		// prevent the entry and exit to and from the input box interfering with the results list
		var bPreventBlur=false;
		var bResultsVisible=false;
		
		// wrap a div around the input
		$(oInputObj).removeClass('smartseearch');		
		var oWrapper=document.createElement('div');
		$(oInputObj.parentNode).append(oWrapper);
		$(oWrapper).append(oInputObj); 
		$(oWrapper).addClass('smartsearch');
		
		// create a div to hold the results
		var oResults=document.createElement('div');
		$(oResults).attr('id','results');  					
		$(oResults).css('height','50px');
		oResults.clear=function() {$(oResults).children('a').remove()}; // this function hasn't been used yet!
		$(oResults).hover(function() {
			bPreventBlur=true;
		},function() {
			bPreventBlur=false;
		});
		
		// create a div inside results to fade them out and show a waiting icon
		var oWaiting=document.createElement('div');
		$(oWaiting).attr('id','waiting');
		$(oWaiting).css('opacity',0.8);	// setting opacity here will work in IE too thanks to jQuery
		
		/* 
			an object to hold the timeout which is in scope of sub functions below
			the timeouts used to detect when the user stops typing and to send the request
			after they've stopped.  Don't want to send every keystoke because it generates a lot
			of traffic and database load as well as being a nightmare to track asychronous data sent back
		*/
		var oDelay;
		
		// set the string to show in the search box when no searching is going on.
		oInputObj.value='search';
		
		// things to do as the user begins to type
		$(this).keyup(function(){
			clearTimeout(oDelay);				// destroy the current queue
			var sSearchString=oInputObj.value;	// cache the current value
			
			// show the results in waiting state
			$(oWrapper).append(oResults); 
			bResultsVisible=true;
			$(oResults).append(oWaiting);
			
			// delay sending the request until the user's stopped for half a second
			oDelay=setTimeout(function() {
				// post up the search term and get a json array of results
				$.post('smartsearch.php','term='+sSearchString,function(oData){	
					/*
						this is what runs when the query's returned
						check that the search value cached is the same as
						the current value to stop asychonous request crossing over
					*/
					if(oInputObj.value!=sSearchString) return; // check that the current value matches the cached value
					$(oResults).empty();				// clear everything from the results - note this includes the wait div too although the object still exists
					$(oResults).css('height','auto');	// auto-size to content
					
					if(oData!=null && $(oData).length>0) {
						// check that there are results and show them
						var iCount=0;
						$.each(oData, function(i, jResult) {
							// parse the json array returned and count the results
							iCount++;
							if(iCount>10) {
								// only show first 10 results.  query is limited to 11 results for efficiency
								var oTopTen=document.createElement('div');
								$(oTopTen).addClass('topTen');
								$(oTopTen).append('showing first 10 results');
								/* 
									because we're over the results div, the results are forced to
									stay open even although the input's lost focus.  this means that clicking
									elsewhere on the page doesn't close the results so if the message is clicked on, 
									return focus to the input box
								*/
								$(oTopTen).click(function() {
									oInputObj.focus();
								});
								$(oResults).append(oTopTen);
							} else {
								/*
									show links to all the results
									I decided that it would be easiest to append these as block a tags
									rather than as an UL.  It used fewer elements so is quicker and uses
									less memory.  Block is set in the stylesheet of course.
								*/
								var oResult=document.createElement('a');
								// show the title and snippet from the description
								$(oResult).append('<strong>'+jResult.title+'</strong>'+'<br />'+jResult.dscr.substring(0,50)+'...');
								
								// work out which section the page is stored in and set the anchor to scroll to on that page
								// might need option to alter the path if this is in another folder.  Could be expando on the input.
								var sHref='#';
								if(jResult.in707==1) sHref='cs.php';
								if(jResult.in606==1) sHref='resources.php';
								//if(jResult.in505==1) sHref='projects/pa.php';
								if(jResult.in404==1) sHref='projects/ed.php';
								if(jResult.in303==1) sHref='projects/be.php';
								if(jResult.in202==1) sHref='projects/cph.php';
								if(jResult.in101==1) sHref='projects/hc.php';							
								
								if(sHref!='#') {
									if(jResult.in505==1) sHref=sHref+'?archive=true';
									sHref=sHref+'#'+jResult.id;
								}
								
								$(oResult).attr('href',sHref);
								$(oResults).append(oResult);
							}
						});
						// add a class to the last a tag so that the bottom border can be switched off
						$(oResults).children('a').last().addClass('last');
					} else {
						// if there's no data, tell the user
						var oNoResults=document.createElement('div');
						$(oNoResults).addClass('noResults');
						$(oNoResults).append('no results matched your search');
						// see topten comment around line 95
						$(oNoResults).click(function() {
							oInputObj.focus();
						});
						$(oResults).append(oNoResults);
					}
					 
				},'json');
			},500);
		});
		
		$(oInputObj).blur(function(){
			/*
				Destroy the results if we exit the input box e.g. by clicking elsewhere on the page.
				if we click on a link in the results, we need to run that link run that link though, and
				blur triggers before it's done.  
				bPreventBlur is set true when the cursor's over the results div so we can detect if
				the user wants to destroy the search or click through to a result.
				An alternative would be to interrogate the event target (the element which triggered
				the event - but this method works well
			*/
			if(bPreventBlur==true) return;
			$(oResults).detach();	// remove the results from the DOM
			bResultsVisible=false;
			$(oResults).empty();  	// empty the list
			$(oResults).css('height','50px');
			oInputObj.value='search';
		});
		
		$(oInputObj).focus(function(){
			/*
				if the results are visible then this is probably triggered by clicking the topten div
				or noresults div in which case we don't want to reset the search
			*/
			if(bResultsVisible==true) return;
			oInputObj.value='';
		});
		
	});
	
});
