﻿var fontFamily = "Arial";
var fontSize = "12px";
var tableColor = "#000000";
var tableBackgroundColor = "#ffffff";
var tableHighlightColor = "#ffffff";
var tableHighlightBackgroundColor = "#0066CC";
var tableBorder = "solid 1px #ccc";
var submitOnEnter = 1;
var countThreshold = -1;
var activeAutocompleteInput;

 

// ---------------------------- BEGIN CODE -------------------------------------
// -----------------------------------------------------------------------------
 
 var log = new Logger("autocompleteLogger"); 
 log.off(); 
 
 /**
  * AutoCompleteInput full Constructor
  * 
  * @param inputElement - the text input element
  * @param completionArray - an array of strings with which to populate the 
  *
  **/

 function AutocompleteInput(inputId, downButtonId, completionArray){
	 this.inputId = inputId;
	 this.downButtonId = downButtonId;
	 this.completionArray = completionArray;
 }
 
 
 AutocompleteInput.prototype.init = function() {
  
	
	var inputElement = document.getElementById(this.inputId); 
	var downButton = document.getElementById(this.downButtonId);
	
 	inputElement.completionArray = this.completionArray; 
 	inputElement.isSafari = (navigator.userAgent.indexOf("Safari") != -1);
	inputElement.caretStartPosition = 0; 
 	inputElement.caretHasMoved = 0; 
 	inputElement.tipTableIsOn = false; 
	inputElement.tipTableArray = new Array(); 	
 	inputElement.selectedIndex = -1;
	inputElement.preventRemove = false;

	downButton.inputElement = inputElement;
	inputElement.onfocus = AutocompleteInput.prototype.addDocumentListeners;
	inputElement.onblur = AutocompleteInput.prototype.removeDocumentListeners;
	downButton.onmousedown = AutocompleteInput.prototype.addDownButtonListeners;

	//addEventListener(downButton, "mousedown", AutocompleteInput.prototype.addDownButtonListeners);
	//addEventListener(inputElement,"focus", AutocompleteInput.prototype.addDocumentListeners);
	//addEventListener(inputElement, "blur", AutocompleteInput.prototype.removeDocumentListeners); 
 	}
 	/**
 	 * Adds the keydown and keypress triggers to the document 
 	 * when the user enters into the textInput focus.
 	 *
 	 */
 	AutocompleteInput.prototype.addDocumentListeners = function(){
	  activeAutocompleteInput = this;
		if(this.isSafari){
			//This is a hack for Safari
			//which doesn't seem to like calling the 
			//cross browser addEventListener function
			document.addEventListener("keydown",keyDownTrigger,false); 
			document.addEventListener("keypress", keyPressTrigger,false);
		}
		addEventListener(document,"keydown", keyDownTrigger);
		addEventListener(document,"keypress", keyPressTrigger);
 	}
	
	
 	/**
 	 * Adds the keydown and keypress triggers to the document 
 	 * when the user enters into the textInput focus.
 	 *
 	 */
 	AutocompleteInput.prototype.addDownButtonListeners = function(evt){ 
	log.debug('adding downbutton listener');
	log.debug('downbuttonadd:' + this);
	log.debug('boo' + this.inputElement);
	stopEvent(evt);
		if(this.isSafari){
			//This is a hack for Safari
			//which doesn't seem to like calling the 
			//cross browser addEventListener function
			document.addEventListener("keydown",keyDownTrigger,false); 
			document.addEventListener("keypress", keyPressTrigger,false);
		}
		addEventListener(document,"keydown", keyDownTrigger);
		addEventListener(document,"keypress", keyPressTrigger);
		try{
		//addEventListener(inputElement, "blur", AutocompleteInput.prototype.removeDocumentListeners); 
		//addEventListener(document, "mousedown", AutocompleteInput.prototype.removeDocumentListeners); 
		activeAutocompleteInput = this.inputElement;
		autocompleteAction(0);
		activeAutocompleteInput.focus();
		
		}catch(e){
		log.warn(e.toString());
		}
		
 	}
 	
 	
 	/**
 	 * Removes the keydown and keypress triggers to the 
 	 * document
 	 *
 	 */
 	AutocompleteInput.prototype.removeDocumentListeners = function(){ 
	  activeAutocompleteInput = null;
		removeEventListener(document,"keydown", keyDownTrigger);
		removeEventListener(document,"keypress", keyPressTrigger);
		removeTipTable(); 
 	}
 	
 	function removeTipTable(){
		if (document.getElementById('tipTable')){ 
			document.body.removeChild(document.getElementById('tipTable')); 
		}
		this.selectedIndex = -1;
		this.tipTableIsOn = false;
	}
	
	

	
	createTipTable = function(){ 
	
		if (document.getElementById('tipTable')){ 
			this.tipTableIsOn = false;
			document.body.removeChild(document.getElementById('tipTable')); 
		} 
		
		//Create and append the table element
		a = document.createElement('table');
		a.cellSpacing='1px';
		a.cellPadding='2px';
		a.style.position='absolute';
		a.style.top = eval(findTopOffset(activeAutocompleteInput) + activeAutocompleteInput.offsetHeight) + "px";
		a.style.left = findLeftOffset(activeAutocompleteInput) + "px";
		//log.debug(inputElement.style.width);
		a.style.width = activeAutocompleteInput.offsetWidth + "px";
		a.style.backgroundColor= tableBackgroundColor;
		a.style.textAlign='left';
		a.style.direction='ltr';
		a.style.color = tableColor;
		a.style.cursor='pointer';
		a.style.border = tableBorder;
		a.id = 'tipTable';
		document.body.appendChild(a);
		
		for (var i=0;i< this.tipTableArray.length;i++){	
		//Iterate through the list of keywords that have been found
		
				var r = a.insertRow(-1);
				r.indexValue = i; 
				r.ac = this; 
				if(i == this.selectedIndex){
					r.style.backgroundColor = tableHighlightBackgroundColor; 
					r.style.color = tableHighlightColor;
				}else{
					r.style.color = tableColor;
					r.style.backgroundColor = tableBackgroundColor;
				}
				r.id = 'tipTableRow_'+(i);
				r.onmouseout = function(evt){ 	
					this.preventRemove = false; 
					this.style.backgroundColor = tableBackgroundColor;
					this.style.color = tableColor;
					} // 
				r.onmouseover = function(evt){ 	
					this.preventRemove = true; 
					try{
						if(typeof selectedIndex != "undefined" && selectedIndex > -1){
							var unhiliteRow = document.getElementById('tipTableRow_' + (selectedIndex)); 
							unhiliteRow.style.backgroundColor = tableBackgroundColor;
							unhiliteRow.style.color = tableColor;
						}
					}catch(e){}
					selectedIndex = this.indexValue; 
					this.style.backgroundColor = tableHighlightBackgroundColor;
					this.style.color = tableHighlightColor;
			 }
				r.onmousedown = function(evt) {  entryAction(13); }
				c = r.insertCell(-1);
				
				c.style.fontFamily = fontFamily;
				c.style.fontSize = fontSize;
				var currentTipItemArr = this.tipTableArray[i].split('[');
				c.innerHTML = currentTipItemArr[0]+'<span style="display:none">'+currentTipItemArr[1]+'</span>'; // this.tipTableArray[i];
				c.id = 'tipTableCell_'+(i);
				c.setAttribute('pos',i);
		}
		this.tipTableIsOn = true;
		selectedIndex = -1;
	}
	
	


	/**
	 * (this) in this function refers to document.
	 *
	 */
	function keyPressTrigger(evt){
	log.debug(this);
		if(this.isSafari){ 
			inputElement.blur();
		}
			
		activeAutocompleteInput.focus();
		
		if (!evt) var evt = window.event;
		if (caretHasMoved) stopEvent(evt);
		return !caretHasMoved; 
	}
	
	function keyDownTrigger(evt){
		if (!evt) var evt = window.event;
		a = evt.keyCode;
		caretHasMoved = 0; 
		switch (a){
			case 38:
				arrowUpAction();
				caretHasMoved = 1;
				return false;
				break;
			case 40:
				arrowDownAction(); 
				caretHasMoved= 1;
				return false;
				break;
			case 13: 
				if (tipTableIsOn && selectedIndex > -1){
					caretHasMoved = 1;
					entryAction(a);
					if(submitOnEnter ==1){
						return true;
					}else {
						return false;
					}
				}else{
					return true;
				}
				break;
			case 9:
				if (tipTableIsOn){
					caretHasMoved = 1;
					entryAction(a);
					return false;
				}else{
					return true;
				}
				break;
			default:
				if(this.tipTableIsOn){ 
					selectedIndex = -1;
				}
				setTimeout(function(){autocompleteAction(a)},50);
				break;
		}
	}
	
	/*
	var tableColor = "#000000";
var tableBackgroundColor = "#ffffff";
var tableHighlightColor = "#ffffff";
var tableHighlightBackgroundColor = "#0066CC";var tableColor = "#000000";
var tableBackgroundColor = "#ffffff";
var tableHighlightColor = "#ffffff";
var tableHighlightBackgroundColor = "#0066CC";
*/
	function arrowUpAction(){ 
		if(!this.tipTableIsOn) return;
	 	if(selectedIndex >= 0){
			try{
				if(typeof selectedIndex != "undefined" && selectedIndex > -1){
					var unhiliteRow = document.getElementById('tipTableRow_' + (selectedIndex)); 
					unhiliteRow.style.backgroundColor = tableBackgroundColor;
					unhiliteRow.style.color = tableColor;
				}
			}catch(e){}
			selectedIndex--;
			if(typeof selectedIndex != "undefined" && selectedIndex >= 0){
			var hiliteRow = document.getElementById('tipTableRow_'+(selectedIndex));
			hiliteRow.style.backgroundColor = tableHighlightBackgroundColor;
			hiliteRow.style.color = tableHighlightColor;
			}
			
		}
	}
	
	function arrowDownAction(){
		if(!this.tipTableIsOn) return;
		if(selectedIndex + 1 < tipTableArray.length){ 
			try{
				if(typeof selectedIndex != "undefined" && selectedIndex > -1){
					var unhiliteRow = document.getElementById('tipTableRow_' + (selectedIndex)); 
					unhiliteRow.style.backgroundColor = tableBackgroundColor;
					unhiliteRow.style.color = tableColor;
				}
			}catch(e){}
			selectedIndex++;
			var hiliteRow = document.getElementById('tipTableRow_'+(selectedIndex));

			hiliteRow.style.backgroundColor = tableHighlightBackgroundColor;
			hiliteRow.style.color = tableHighlightColor;
			
		}
	}
	
	function entryAction(kc){ 
	
		log.debug('entryaction' + this);
		if(!this.tipTableIsOn || selectedIndex < 0) {  log.debug('entry'); return; }
		if(submitOnEnter == 1 && kc == 13) { 
		    log.debug('woohoo');
			log.debug('this.tipTableIsOn' + this.tipTableIsOn);
			log.debug('selectedIndex' + selectedIndex);
		    var orgStr=this.tipTableArray[selectedIndex];
			if (orgStr.indexOf("span")!=-1) { 
				var selectedStrArr=this.tipTableArray[selectedIndex].split('<span style="display:none">') 
			} else {
				var selectedStrArr=this.tipTableArray[selectedIndex].split('[') 
			}
			var selectedStr=selectedStrArr[1];
			try { selectedStr=selectedStr.replace(']',''); } catch(e) {}
			try { selectedStr=selectedStr.replace('</span>',''); } catch(e) {}
			goSearch(selectedStr);
		} else if(this.selectedIndex >= 0) { 
			log.debug('activeAutocompleteInput.selectedIndex'  + selectedIndex);
			activeAutocompleteInput.value = this.tipTableArray[selectedIndex];
			removeTipTable();
		}

	}
	
	
	function autocompleteAction(kc){
		//log.debug('autocomplete this' +activeAutocompleteInput.value); 
		if (kc == 38 || kc == 40 || kc == 13) { 
			return;
		} 
		
		//if(activeAutocompleteInput.value.length <= 0) {
			//removeTipTable(); 
		//} 
		
		var i; 
		this.tipTableArray = null; 
		if(activeAutocompleteInput.value == undefined || activeAutocompleteInput.value == null || activeAutocompleteInput.value.length == 0){
			log.debug('ohhyeah');
			this.tipTableArray = activeAutocompleteInput.completionArray;
		} else{
		log.debug(activeAutocompleteInput.value);
		log.debug(activeAutocompleteInput.value.length);
		
		this.tipTableArray = new Array();
// next: custom by Amir to support
//       if only a single char typed in then push results back to array, after matching by 1st char
// or,   if more then a single char typed in then push results back to array, after matching if chars appear anywhere in target string
		for(i = 0; i < activeAutocompleteInput.completionArray.length; i++){
		var orgSearchStr=activeAutocompleteInput.completionArray[i];
		searchStrArr=orgSearchStr.split('[');
		searchStr=searchStrArr[0];
		if (activeAutocompleteInput.value.length<3) { 
			if(searchStr.toLowerCase().substring(0, activeAutocompleteInput.value.length) == activeAutocompleteInput.value.toLowerCase()){
				var outputSearchStr=searchStr+'<span style="display:none">'+searchStrArr[1]+'</span>';
				tipTableArray.push(outputSearchStr); 
			}
		} else {
			if(searchStr.toLowerCase().indexOf(activeAutocompleteInput.value.toLowerCase())!= -1){
				var outputSearchStr=searchStr+'<span style="display:none">'+searchStrArr[1]+'</span>';
				tipTableArray.push(outputSearchStr); 
			}
		}
		}
		}
		
		if(tipTableArray.length <= countThreshold || countThreshold < 0 ){
			createTipTable();
		}
	}
 
 	
 
 
/**
 * Adds an event listener to an element object.
 *
 * @param o - the object whose listener will be affected
 * @paran eventName - the event of the listener 
 * 					(should omit leading 'on')
 * @param triggerFunction - the function to trigger 
 *
 */
function addEventListener(o,eventName,triggerFunction){
	if (o.attachEvent){
		//Microsoft event registration model
		o.attachEvent("on"+eventName, triggerFunction);
	}else if(o.addEventListener){
		//W3C event registration model
		o.addEventListener(eventName,triggerFunction,false); 
	} else{
		o["on"+eventName] = triggerFunction;
	
	}
}	


/**
 * Removes an event listener from an element object.
 *
 * @param o - the object whose listener will be affected
 * @paran eventName - the event of the listener 
 * 					(should omit leading 'on')
 * @param triggerFunction - the function to trigger 
 *
 */
function removeEventListener(o,eventName,triggerFunction){
	if (o.detachEvent){
		//Microsoft event registration model
		o.detachEvent("on"+eventName,triggerFunction);
	}else if(o.removeEventListener){
		//W3C event registration model
		o.removeEventListener(eventName,triggerFunction,false);
	} else { 
		o["on"+eventName] = null;
	}
	
}


/**
 * Find the beginning caret position 
 *
 * @param o - the object whose caret position we are finding
 *
 */
function getCaretStartPosition(o){
	if(typeof o.selectionStart != "undefined"){
		return o.selectionStart;
	}else if(document.selection&&document.selection.createRange){
	
	
		var M=document.selection.createRange();
		try{
			var Lp = M.duplicate();
			Lp.moveToElementText(o);
		}catch(e){
			var Lp=o.createTextRange();
		}
		Lp.setEndPoint("EndToStart",M);
		var rb=Lp.text.length;
		try{
			if(rb>obj.value.length){
				return -1;
			}
		}catch(e){
			return -1; 
		}
		return rb;
	}
}

/**
 * Halts an executing event.
 *
 */
function stopEvent(evt){
	if (!evt) var evt = window.event;
	//evt || window.event;
	if (evt.stopPropagation){
		evt.stopPropagation();
		evt.preventDefault();
	}else if(typeof evt.cancelBubble != "undefined"){
		evt.cancelBubble = true;
		evt.returnValue = false;
	}
	return false;
}



/** 
 * Computes offset position 
 * from top edge of the screen 
 *
 */
function findTopOffset(obj){
	toreturn = 0;
	while(obj){
		toreturn += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return toreturn;
}

/**
 * Computes offset position
 * from left edge of screen
 *
 */
function findLeftOffset(obj){
	toreturn = 0;
	while(obj){
		toreturn += obj.offsetLeft;
		obj = obj.offsetParent;
	}
	return toreturn;
}
