/*
	AJAX Suggestions is developed by Robert Nyman, http://www.robertnyman.com, and it is released according to the
	Creative Commons Deed license (http://creativecommons.org/licenses/GPL/2.0/)
	For more information, please see http://www.robertnyman.com/ajax-suggestions
*/
/* Have amended significantly, direct replacement with above code will not be advisable, fabulous code though */

/*  
 * make sure these are added to containing HTML whenever using suggestion.js 
 * 
 * window.addEvent('domready', function() {inputSuggest.init();});
 * window.addEvent('beforeunload', function(){inputSuggest.closeSession();});
 * 
* */

var inputSuggest = {
	xmlHttp : null,
	resultsElement : null,
	resultsContainer : null,
	resultsVisible : false,
	timer : null,
	suggestDelay : 200, 
	cInput : null,
	cKeyEvent : null,
	suggestInInput : false,
	urlExt : "search=",
	suggestions : [],
	selItem: -1,
	resultIndex: 0,
	offsetLeft: 0,
	offsetTop: 0,

		
	init : function () {
		this.xmlHttp = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP");
		this.elements = $$('input.suggesttext');
		var element;
		this.elements.each(function(element, index){
			element.setAttribute("autocomplete", "off");
			element.addEvent('keyup', function(e){
				if (inputSuggest) {
					clearTimeout(inputSuggest.timer);
					inputSuggest.cInput = (/input/i.test(this.nodeName)) ? this : e.target;
					inputSuggest.cKeyEvent = e.code;
					inputSuggest.timer = setTimeout("inputSuggest.getSuggestions()", inputSuggest.suggestDelay);
				}
			});
			element.addEvent('click', function (e){
				return false;
			});
		});
		this.resultsElement = $('suggestion-picker');
		this.resultsContainer = $('suggestion-container');
		// query why this isn't done at element level and the use of keydown:keys(up)'
		document.addEvent('keydown', this.overrideArrowKeys);
		document.addEvent('keypress', this.overrideArrowKeys);
		document.addEvent('keyup', this.navigateResults);
		document.addEvent('click', function (){
			inputSuggest.clearResults();
		});
	},
	
	getSuggestions : function (){
		if ($('search-long') && $('search-long').get('value')!='') {
			resetFindMe();
		}
		var value = this.cInput.value;
		if(!/13|27|37|39|38|40/.test(this.cKeyEvent)){
			var url = this.cInput.className.replace(/.*url-([\w\/\?\.-]+).*/, "$1");
			if(!this.suggestInInput){
				inputSuggest.clearResults(true);
			}
			if(value.length > 2 && url.length > 0){
				this.makeSuggestionCall(value, url);
			}
			else if(value.length == 0 || !this.SuggestInInput){
				inputSuggest.clearResults();
			}
		}
	},

	makeSuggestionCall : function (value, url){
		var regExpValue = new RegExp(("^" + value + "$"), "i");
		var exists = false;
		var suggestionItem;
		var url = url + ((/\?/.test(url))? "&" : "?") + "search=" + value;
		for (var i=0; i<this.suggestions.length; i++){
			suggestionItem = this.suggestions[i];
			if(regExpValue.test(suggestionItem[0]) && url == suggestionItem[2]){
				exists = true;
				this.resultIndex = i;
				this.presentResult(this.suggestions[i][1]);
				break;
			}
		};
		if(!exists){
			this.xmlHttp.onreadystatechange = function (){};
			this.xmlHttp.abort();
			this.currentValue = value;
			this.currentURL = url;
			this.xmlHttp.open("GET", url, true);
			this.xmlHttp.onreadystatechange = this.getResults;
			this.xmlHttp.send(null);
		}
	},

	getResults : function (){
		if(inputSuggest.xmlHttp.readyState == 4 && inputSuggest.xmlHttp.responseText.length > 0){
			inputSuggest.loadResults();
		}
	},

	loadResults : function (){
		this.resultIndex = this.suggestions.length;
		this.suggestions.push([this.currentValue, this.xmlHttp.responseText, this.currentURL]);
		this.presentResult();
	},

	presentResult : function (){
		this.resultsElement.innerHTML = this.suggestions[this.resultIndex][1];
		var narrowSearchOverride = 0;
		if ( ($('searcheatbtn').get('class')).indexOf('narrow') >= 0) {
			narrowSearchOverride =  -1; 
		}
		var coordinates = this.getCoordinates();
		var elm = this.resultsContainer.style;
		elm.left = coordinates[0] + this.offsetLeft + "px";
		elm.top = coordinates[1] + narrowSearchOverride + this.cInput.offsetHeight + this.offsetTop + "px";
		this.applyResultEvents();
		elm.display = "block";
		this.resultsVisible = true;
		// why is this key test here? 
		if(/38|40/.test(this.cKeyEvent)){
			if(!this.valueInInput){
				this.selectedItem = -1;
			}
			this.navigateResults(null, this.cKeyEvent);
		}
	},

	navigateResults : function (e, keyCode){
		if(inputSuggest && inputSuggest.cInput && inputSuggest.resultsElement){
			var event = (typeof e != "undefined")? e : event;
			var results = inputSuggest.resultsElement.getElements('*.item');
			var keyCode = keyCode || event.code;
			var selItem = (!e && keyCode == 38)? results.length : inputSuggest.selItem;
			var navigateUp = keyCode == 37 || keyCode == 38;
			var navigateDown = keyCode == 39 || keyCode == 40;
			if(results.length > 0 && (navigateUp || navigateDown)){
				if(navigateUp){
					if((selItem - 1) >= 0) {selItem--;}
					else{	selItem = -1;}
				}		
				else if(navigateDown){
					if((selItem + 1) < results.length){	selItem++;}
					else{	selItem = -1;}
				}
				var item;
				var classToRemove;
				for(var i=0; i<results.length; i++){
					item = results[i];
					classToRemove = new RegExp(('selected\s?'), 'i');
					item.className = item.className.replace(classToRemove, "").replace(/^\s?|\s?$/g, "");
				};
				inputSuggest.selItem = selItem;
				var elmToFocus = inputSuggest.cInput;
				if(selItem > -1){
					var currentItem = results[selItem];
					var currentClass = item.className;
					if(!new RegExp('selected', "i").test(currentClass)){
						currentItem.className = currentClass + ((currentClass.length > 0)? " " : "") + 'selected';
					}
					elmToFocus = results[selItem];
				}
				try{
					elmToFocus.focus();
				}
				catch(e){
					// Just in case... :-)
				}
				if(event){
					if(event.preventDefault){event.preventDefault();}
					else{	event.returnValue = false;					}
					if(event.stopPropagation){	event.stopPropagation();}
					else{	event.cancelBubble = true;}
				}
				return false;
			}
			else if(keyCode == 27){
				inputSuggest.clearResults();
				try{
					inputSuggest.cInput.focus();
				}
				catch(e){
					// Just in case... :-)
				}
			}
		}
	},

	applyResultEvents : function (){
		var insertValueItems = this.resultsElement.getElements('a.choose-value');
		var item;
		for(var i=0; i<insertValueItems.length; i++){
			item = insertValueItems[i];
			item.inputRef = this.cInput;
			item.addEvent('click', this.insertValueIntoField);
		};		
	},

	insertValueIntoField : function (e){
		var elm = (/a/i.test(this.nodeName))? this : e.srcElement;
		var input = elm.inputRef;
		var value = decodeURI(elm.getAttribute("href"));
		if (value.lastIndexOf('/') >= 0) {
			value = value.substring(value.lastIndexOf('/')+1);
		}
		if(!new RegExp(value).test(input.value)){
			input.value = value;
		}
		if(e.preventDefault){e.preventDefault();}
		else{	e.returnValue = false;}
		if(e.stopPropagation){ e.stopPropagation();	}
		else{	e.cancelBubble = true;}
		try{ input.focus(); }
		catch(e){
			// Just in case... :-)
		}
		inputSuggest.clearResults();
		inputSuggest.valueInInput = true;
	},
	
	clearResults : function (justClear){
		if(this.resultsContainer && this.resultsElement){
			if(!justClear){
				this.resultsContainer.style.display = "none";
				this.resultsVisible = false;
			}
			this.resultsElement.innerHTML = "";
			this.selItem = -1;
		}
	},
	
	overrideArrowKeys : function (e){
		if ( (!e.ctrlKey && !e.metaKey) && inputSuggest.resultsVisible && (e.key == 'up' || e.key == 'left' || e.key == 'down' || e.key == 'right') ) {
			if(e.preventDefault){ e.preventDefault();}
			else{	e.returnValue = false;}
			if(e.stopPropagation){ e.stopPropagation();}
			else{ e.cancelBubble = true;}
			return false;
		}	
	},

	getCoordinates : function (){
		var elm = this.cInput;
		var offsetLeft = 0;
		var offsetTop = 0;		
		if (elm.getOffsetParent()){
			offsetLeft += elm.offsetLeft;
			offsetTop += elm.offsetTop;
		}
		return [offsetLeft, offsetTop];
	},
	
	closeSession : function (){
		delete inputSuggest;
		inputSuggest = null;
	}
};

