/* Class that performs predictive search functions */

function Predictor(config){
	this.minChars = config.minChars; /* The minimum number of characters that will trigger suggestions */
	this.suggestionDivId = config.suggestionDivId; /* The id to be used for the div that will contain the suggestions (if the element does not exist it will be created immediately after the text input in the DOM) */
	this.predictiveSearchUrl = config.predictiveSearchUrl; /* The URL of the article that uses the predictive search template */
	
	this.pid = 0;
	/* Does the search using the value of the given element */
	this.doSearch = function(el){
		clearTimeout(this.pid);
		var self = this;
		/* Wait for a break in the typing 500ms should be long enough */
		this.pid = setTimeout(function(){
			/* Check length of input - only start searching with {minChars} or more characters */
			if(el && el.value && el.value.length >= self.minChars){
				var xmlhttp;
				if(window.XMLHttpRequest){
					xmlhttp=new XMLHttpRequest();
				}else{
					xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
				}
				xmlhttp.onreadystatechange=function(){
					if (xmlhttp.readyState==4 && xmlhttp.status==200){
						self.renderSuggestions(el, xmlhttp.responseText);
				    }
				};
				xmlhttp.open('GET',self.predictiveSearchUrl+(self.predictiveSearchUrl.indexOf('?')==-1 ? '?' : '&')+'ajax=true&terms='+encodeURI(el.value),true);
				xmlhttp.send();
			}else{
				self.renderSuggestions(el, '');
			}
		}, 500);
	}
	
	/* Renders the given html in a div immediately following the given element */
	this.renderSuggestions = function(el, html){
		var sugDiv = this.getSuggestionDiv(el)
		sugDiv.style.display = html.length > 0 ? 'block' : 'none';
		sugDiv.innerHTML = html;
	}
	
	/* Calls the function that hides the suggestions div after a short delay */
	this.hideSuggestions = function(){
		/* We need a short delay in hiding the suggestions, otherwise when the user
		 * clicks a suggestion, they are hidden before the link is followed */
		var self = this; 
		setTimeout(function(){ 
			self.hide(); 
		}, 500);
	}
	
	/* Hides the suggestions div */
	this.hide = function(){
		var sugDiv = document.getElementById(this.suggestionDivId);
		if(sugDiv){
			sugDiv.style.display = 'none';
		}
	}
	
	/* Gets the suggestions div (creates it first if it doesn't exist yet) */
	this.getSuggestionDiv = function(el){
		var sugDiv = document.getElementById(this.suggestionDivId);
		if(sugDiv) return sugDiv;
		
		var sugEl = document.createElement('div');
		sugEl.id = this.suggestionDivId;
		sugEl.style.display = 'none';
		if(el.nextSibling){
			el.parentNode.insertBefore(sugEl, el.nextSibling);
		}else{
			el.parentNode.appendChild(sugEl);
		}
		return sugEl;
	}
}
