var suggestCache = new Array();

var executingURL = '';
var busy = false;
var queuedURL = '';
var activeSuggestions = null;

var xhttp = null;

var isie = ( navigator.userAgent.toLowerCase() == "msie" );

function Suggest(objTextbox, objSource, objDiv, singular, check, didxElements)
{
	if (!objTextbox)
		return;
						
	//alert(objTextbox.disabled)
	if (objTextbox.disabled == true)
		return		
	
	this.textbox = objTextbox;
	this.didxElements = didxElements;
	this.textbox.setAttribute("autocomplete","off");
	this.source = objSource;

	this.results = objDiv;

	this.selectedItem = null;

	this.singular = singular || false;

	if (check)
		this.check = check;

	this.init();
}

Suggest.prototype.getCurrentWord = function ()
{
	if (this.singular)
	{
		return this.textbox.value.toLowerCase();
	}
	else
	{
		var wordStartsAt = this.textbox.value.lastIndexOf(" ");
		return Trim(this.textbox.value.substring(wordStartsAt, this.textbox.selectionStart).toLowerCase());
	}
}

Suggest.prototype.updateSelected = function (newSelectedItem) 
{
	if (this.selectedItem)
	{
		this.selectedItem.className = 'item';
		this.selectedItem = newSelectedItem;
		this.selectedItem.className = 'itemSelected';
	}
}

Suggest.prototype.nextItem = function ()
{
	if (this.selectedItem.nextSibling)
	{
		this.updateSelected ( this.selectedItem.nextSibling )
	}
}

Suggest.prototype.previousItem = function ()
{
	if (this.selectedItem.previousSibling)
	{
		this.updateSelected ( this.selectedItem.previousSibling )
	}
}

Suggest.prototype.selectItem = function ()
{
	if (this.textbox.createTextRange || this.textbox.setSelectionRange)
	{
	    var iLen = this.textbox.value.length; 
	    var sPos = this.textbox.value.lastIndexOf(" ");		
			        
	    this.selectRange(sPos + 1, iLen)
	}
}

Suggest.prototype.showResults = function ()
{
	this.results.className = "showResults";
}

Suggest.prototype.hideResults = function ()
{
	this.results.className = "hideResults";
}

Suggest.prototype.positionResults = function ()
{
	if (!this.textbox || !this.textbox.offsetWidth)
		return;
		
	//this.hideResults();
	this.results.style.left = this.getLeft() + "px";;
	this.results.style.top  = this.getTop() + this.textbox.offsetHeight - 1 + "px";;

	if (isie)
	{
		this.results.style.width = this.textbox.offsetWidth + "px";
	}
	else
	{
		this.results.style.width = this.textbox.offsetWidth - 2 + "px";
	}

	//this.textbox.focus();
}

Suggest.prototype.getLeft = function ()
{
    var oNode = this.textbox;
    var iLeft = 0;
	
    while(oNode && oNode.tagName != "BODY" && oNode.tagName != "HTML") 
	{
		iLeft += oNode.offsetLeft;
        oNode = oNode.offsetParent;
    }
				
    return iLeft;
};

Suggest.prototype.getTop = function ()
{
    var oNode = this.textbox;
    var iTop = 0;

    while(oNode && oNode.tagName != "BODY" && oNode.tagName != "HTML")
    {
        iTop += oNode.offsetTop;

        oNode = oNode.offsetParent;
    }

    return iTop;
};

Suggest.prototype.handleKeyUp = function (objEvent) 
{
	if (!objEvent || (this.check && this.check.checked == false) || this.textbox.value.length < 4)
	{
		this.hideResults();
		return;
    }
    
	this.positionResults();

	var intKeyCode = objEvent.keyCode;

	//alert(intKeyCode);

	if (this.textbox.value.length == 0)
	{
		this.hideResults();
		queuedURL = '';
	}

	if (intKeyCode == 40)
	{
		this.nextItem();
		this.selectItem();
		queuedURL = '';
	}
	else if(intKeyCode == 39)
	{
		this.selectItem();
		this.hideResults();
		queuedURL = '';
	}
	else if(intKeyCode == 38)
	{
		this.previousItem();	
		this.selectItem();
		queuedURL = '';
	}	
	else if(intKeyCode == 27)
	{
		this.hideResults();
		queuedURL = '';
	}	
	else if (intKeyCode == 32)
	{
		if (this.singular == false)
			this.hideResults();
		queuedURL = '';
	}

	if ((intKeyCode >= 48 && intKeyCode <= 57) || (intKeyCode >= 65 && intKeyCode <= 90) || (intKeyCode >= 96 && intKeyCode <= 105) || (intKeyCode == 8) || (intKeyCode == 16))
	{
		this.source.getSuggestions(this);
	}
}

Suggest.prototype.init = function () 
{
	var objThis = this;
	
	this.textbox.setAttribute("autocomplete","off");
		
	this.textbox.onkeyup = function (objEvent) 
	{		
		if (!objEvent)
		{
			objEvent = window.event;
		}		

		objThis.handleKeyUp(objEvent);
	}
	
	this.textbox.onblur = function ()
	{
		objThis.hideResults();
		if (this.ondblclick)
		{
			this.ondblclick();
		}
	}

	window.onfocus = function (oEvent)
	{ 
		oEvent = oEvent || window.event;
		oTarget = oEvent.target || oEvent.srcElement;	 
		//alert(oTarget);
		if (oEvent && (oTarget == null || oTarget == "[object HTMLDocument]")) {
			//alert(oTarget);
			objThis.hideResults();		
		}	
	}

	window.onresize = function (oEvent) 
	{ 
		oEvent = oEvent || window.event;
		oTarget = oEvent.target || oEvent.srcElement;	 
					
		objThis.positionResults();
		//objThis.showResults();		
	}

	this.positionResults();
}

Suggest.prototype.selectRange = function (iStart , iLength ) 
{
	if (this.selectedItem == null)
		return;

	if (this.singular == true)
	{
		this.textbox.value = this.selectedItem.firstChild.innerHTML;
	}
	else
	{
		if (this.textbox.createTextRange) 
		{
			var oRange = this.textbox.createTextRange(); 
			oRange.moveStart("character", iStart); 
			oRange.moveEnd("character", iLength - this.textbox.value.length);     
			oRange.select();
	
	        oRange.text = this.selectedItem.firstChild.innerHTML;

			oRange = this.textbox.createTextRange();
			oRange.moveStart("character", iLength + this.textbox.value.length);
			oRange.moveEnd("character", iLength + this.textbox.value.length);
			oRange.select();
			
			//use setSelectionRange() for Mozilla
		} 
		else if (this.textbox.setSelectionRange) 
		{
       		this.textbox.setSelectionRange(iStart, iLength);
	
			var selectionStart = this.textbox.selectionStart;
			var selectionEnd = this.textbox.selectionEnd;
			this.textbox.value = this.textbox.value.substring(0, selectionStart)
					+ this.selectedItem.firstChild.innerHTML;
					+ this.textbox.value.substring(selectionEnd);
	
			//document.selection = this.selectedItem.firstChild.innerHTML;
			this.textbox.setSelectionRange(this.textbox.value.length, this.textbox.value.length);
		}     
	}

	//set focus back to the textbox
	//this.textbox.focus();      
}

Suggest.prototype.formatResults = function (arrSuggestions)
{
	var oThis = this;
	this.results.innerHTML = "";	

	if (arrSuggestions.length > 0)
	{
    	for (var i=0; i < arrSuggestions.length; i++)
    	{ 
			var item = document.createElement('div');
			item.setAttribute('id', 'Item' + i);

			if (i == 0)
			{
				item.className = 'itemSelected';
				this.selectedItem = item;
			}
			else
			{
				item.className = 'item';
			}

			var term = document.createElement('span');
			term.className = 'highlighted';			

			term.innerHTML = arrSuggestions[i][0];

			var highlight = document.createElement('span');
			highlight.className = 'termfound';			

			highlight.innerHTML = this.highLightWord(arrSuggestions[i][0], this.getCurrentWord());

			var count = document.createElement('span');
			count.className = 'matches';			

			count.innerHTML = arrSuggestions[i][1];

			item.appendChild(term);
			item.appendChild(highlight);
			item.appendChild(count);

			item.onmousedown = item.onmouseup =
			item.onmouseover = function (oEvent) 
			{ 
				oEvent = oEvent || window.event;
				oTarget = oEvent.target || oEvent.srcElement;	 

				if (oTarget.className != 'item' && oTarget.className != 'itemSelected')
				{	
					// Handles the nested spans in the item
					oTarget = oTarget.parentNode;

					while (oTarget.className != 'item' && oTarget.className != 'itemSelected' && oTarget != null )
					{
						oTarget = oTarget.parentNode;
					}
				}

				if (oEvent.type == "mousedown")
				{
					oThis.selectedItem = oTarget;
					oThis.selectItem();
				}
				else if (oEvent.type == "mouseover")
				{
			        oThis.updateSelected(oTarget);
		        }
		        else
		        {
		            oThis.textbox.focus();
		        }
			}

			this.results.appendChild(item);
        }

		this.showResults();
	}
	else
	{
		this.hideResults();
	}
}

Suggest.prototype.highLightWord = function (item ,word)
{
	var replacement = word.replace(/\W+/g,"");
	var criteria = word.replace(/\?/g,".").replace(/\*/g, ".+");  //  ? --> .   * --> .+
	var re = new RegExp("(" + criteria + ")", "g");

	return item.replace(re, '<strong>$1</strong>');
}

function Suggestions()
{
	this.sugg ;
	this.init();
}

Suggestions.prototype.init = function ()
{
	if (window.XMLHttpRequest) {
		if (xhttp == null)
		{
			xhttp = new XMLHttpRequest();
		}
		// branch for IE/Windows ActiveX version
	} 
	else if (window.ActiveXObject) 
	{
		if (xhttp == null)
		{
			xhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
		}
	}				
}

function callInProgress () 
{
    switch ( xhttp.readyState ) {
        case 1, 2, 3:
            return true;
        break;
	
        // Case 4 and 0
        default:
            return false;
        break;
    }
}

xhttpLookup2 = function (flag)
{
	if (busy)
	{
		//setTimeout('xhttpLookup2()', 50);
		//alert('dropped');
		return;
	}
	
	busy = true;
	
	if (callInProgress())
	{
		xhttp.abort();
	}
		
	executingURL = queuedURL;
	queuedURL = '';
	
	if (suggestCache[executingURL] != null)
	{
		activeSuggestions.arrSuggestions = suggestCache[executingURL] ;
		Suggestions.sugg.formatResults(activeSuggestions.arrSuggestions);
		busy = false;
		return;
	}
			
	if (window.XMLHttpRequest) 
	{
		xhttp = new XMLHttpRequest();

		if (xhttp) 
		{
			xhttp.onreadystatechange = activeSuggestions.ReadyStateChange;
			xhttp.open("GET", executingURL, true);
			xhttp.send(null);
		}					
	}	
    else if (window.ActiveXObject) // branch for IE/Windows ActiveX version
	{
		xhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
	
		if (xhttp) 
		{
			xhttp.open("GET", executingURL, true);
			xhttp.onreadystatechange = activeSuggestions.ReadyStateChange;
			xhttp.send();
		}
	} 
}

Suggestions.prototype.xhttpLookup = function (strTerm, strField, didxInfo)
{
	var url = "./inline.aspx?sb=" + strTerm.replace(/~[\w\*\?]+/g,"") + "&fld=" + strField + "&didx=" + didxInfo;

	if (suggestCache[url] != null)
	{
		this.arrSuggestions = suggestCache[url] ;
		Suggestions.sugg.formatResults(this.arrSuggestions);
		return;
	}
	
	queuedURL = url;
	xhttpLookup2();
}

Suggestions.prototype.ReadyStateChange = function ()
{
	var arrSuggestions = new Array();
	var i = 0;

	if ( xhttp.readyState == 4 && xhttp.responseXML)
	{								
		if (isie)
		{
			var nodes = xhttp.responseXML.selectNodes("//item/title");
			var matches = xhttp.responseXML.selectNodes("//item/id");

			for (var i=0; i<nodes.length; i++)
			{
				arrSuggestions.push( new Array(nodes(i).text, matches(i).text) );
			}
		}
		else
		{
			var nodes = xhttp.responseXML.getElementsByTagName('item');
			
			for (i = 0;  i < nodes.length; i++ ) 
			{
				arrSuggestions.push ( new Array(nodes.item(i).childNodes.item(1).firstChild.nodeValue,  
							nodes.item(i).childNodes.item(0).firstChild.nodeValue) );
			}
		}
		
		busy=false;
		//this.arrSuggestions = arrSuggestions;
		suggestCache[executingURL] = arrSuggestions;
		Suggestions.sugg.formatResults(arrSuggestions);
		
		if (queuedURL != "")
			setTimeout('xhttpLookup2()', 50);
	}
}

Suggestions.prototype.getSuggestions = function (Suggest)
{
	activeSuggestions = this;
	var sTextboxValue = Suggest.getCurrentWord();
	
	if (sTextboxValue.length > 0)
	{
		if (xhttp)
		{
			Suggestions.sugg = Suggest;
			this.xhttpLookup(sTextboxValue, Suggest.textbox.id, getCheckedValues(Suggest.didxElements));
		}
	}
}

function Trim(str)
{	
    while(str.charAt(0) == (" "))
	{
		str = str.substring(1);
	}
	while(str.charAt(str.length-1) == " ")
	{
		str = str.substring(0,str.length-1);
	}

	return str;
}

function getCheckedValues(elements)
{
	if (!elements) return '';
	
	var values = '';
	var countCheckBoxes = elements.length;
	
	if(!countCheckBoxes)
		return '';
	else
		for (var i=0; i <= countCheckBoxes -1; i++)
		{
			//alert(document.forms[0].checks[i].checked )
			if (elements[i].checked == true)
			{
				values +=  elements[i].value + ",";
				//alert(values)
			}
		}
		
	return values.substring(0, values.length - 1)
}
