// Constructor -- pass a REST request URL to the constructor
//
function JSONscriptRequest(fullUrl, query) {
    // REST request path
    this.fullUrl = fullUrl; 
    // Keep IE from caching requests
    //this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
    // Get the DOM location to put the script tag
    this.headLoc = document.getElementsByTagName("head").item(0);
    // Generate a unique script tag id
    this.timeStamp = (new Date()).getTime();
    this.scriptId="JscriptId"+this.timeStamp;
    //this.scriptId = query;
}

// Static script ID counter
JSONscriptRequest.scriptCounter = 1;

// buildScriptTag method
//
JSONscriptRequest.prototype.buildScriptTag = function () {
    // Create the script tag
    this.scriptObj = document.createElement("script");
    
    // Add script object attributes
    this.scriptObj.setAttribute("type", "text/javascript");
    this.scriptObj.setAttribute("charset", "utf-8");
    this.scriptObj.setAttribute("src", this.fullUrl + "&reqID=" + this.scriptId);
    this.scriptObj.setAttribute("id", this.scriptId);
    return this.scriptId;
};
 
// removeScriptTag method
// 
JSONscriptRequest.prototype.removeScriptTag = function () {
    // Destroy the script tag
    this.headLoc.removeChild(this.scriptObj);  
};

JSONscriptRequest.removeScriptTagById = function (id) {
    var jScriptTag = document.getElementById(id);
    var parentNode = jScriptTag.parentNode;
    parentNode.removeChild(jScriptTag);
};

// addScriptTag method
//
JSONscriptRequest.prototype.addScriptTag = function () {
    // Create the script tag
    this.headLoc.appendChild(this.scriptObj);
};


function ISuggest()
{
	//RFCID for search suggest
	var _RFCID = '114';
	
	//original RFCID
	var _originalRFCID = null;
	
	//holds reference to RFCID element
	var _rfcidElements = null;
	
	//holds the xmlHttpRequest object
	var _requestClient = null;
	
	//holds reference to textbox for which suggestions are requested
	var _trackingElement = null;
	
	//text box which has current focus
	var _activeElement = null;
	
	//the query which was last requested and being displayed
	var _activeQuery = new function(){
			this.query = null;
			this.response = null;
		};
	
	//time to wait before creating request.
	var _timeoutPeriod = 500;
	
	//index of current selected suggestion
	var _currentSelection = -1;
	
	//selected suggestion
	var _selectedValue = null;
	
	//reference to div used for display
	var _suggestionsPanel = null;
	
	var _jsonClient = null;
			
	//get the absolute position of an object 
	var _findPos = function ( obj ) {
			var curleft = curtop = 0;
			try{
				if (obj.offsetParent) {
					do {
						curleft += obj.offsetLeft;
						curtop += obj.offsetTop;
					} while (obj = obj.offsetParent);
					
					return {left:curleft, top:curtop};
				}
			}
			catch(e){}
			return null;
		};
	
	//sets the RFCID element values
	var _setRFCID = function(){
			for(var j=0; j<_rfcidElements.length; j++){			
			_rfcidElements[j].value = _RFCID;		
		     }
		};
	
	//resets the RFCID element values
	var _resetRFCID = function(){
			for(var j=0; j<_rfcidElements.length; j++){
				_rfcidElements[j].value = _originalRFCID;
			}
		};
	
	//selects previous suggestion
	var _selectPrevious = function(){
			if(_currentSelection >= 0)
			_suggestionsPanel.childNodes[_currentSelection].className = 'suggest_link';
			
			if(_currentSelection == 0 || _currentSelection == -1)
				_currentSelection = _suggestionsPanel.childNodes.length - 1;
			else
				_currentSelection--;
			_suggestionsPanel.childNodes[_currentSelection].className = 'suggest_link_over';
			
			if(_currentSelection > -1){
				var value = _suggestionsPanel.childNodes[_currentSelection].childNodes[0].nodeValue;
				_activeQuery.query = value;
				_activeQuery.response = null;
				_activeElement.value = value;
				_selectedValue = value;
				_setRFCID();
			}
		};

	//selects next suggestion
	var _selectNext = function(){
			if(_currentSelection >= 0)
				_suggestionsPanel.childNodes[_currentSelection].className = 'suggest_link';
			
			if(_currentSelection == (_suggestionsPanel.childNodes.length - 1))				
				_currentSelection = 0;
			else
				++_currentSelection;
			
			_suggestionsPanel.childNodes[_currentSelection].className = 'suggest_link_over';
			
			if(_currentSelection > -1){
				var value = _suggestionsPanel.childNodes[_currentSelection].childNodes[0].nodeValue;
				_activeQuery.query = value;
				_activeQuery.response = null;
				_activeElement.value = value;
				_selectedValue = value;
				_setRFCID();
			}
		};
		
	//displays the suggestions panel
	var _showSuggestions = function(){			
			_suggestionsPanel.style['display'] = 'block';
			_currentSelection = -1;
			
			var pos = _findPos(_trackingElement);
			
			_suggestionsPanel.style['left'] = pos.left + 'px';
			_suggestionsPanel.style['top'] = pos.top + _trackingElement.offsetHeight + 'px';
			_suggestionsPanel.style['width'] = _trackingElement.offsetWidth + 'px';
		};
	
	//hides suggestion panel
	var _hideSuggestions = function(){
			_suggestionsPanel.innerHTML = '';
			_suggestionsPanel.style['display'] = 'none';
			//_trackingElement = null;
		};
	
	this.insertScriptTag = function(){
		if(!_activeElement || _activeElement.value == _activeQuery.query) return;
		
		_trackingElement = _activeElement;			
		var str = escape(_activeElement.value);
		
		if(str == ''){
			_suggestionsPanel.style['display'] = 'none';
			return;
		}
		
		_activeQuery.query = str;
		
		// The web service call
		//var req  = 'http://localhost:8080/QuerySuggest/SuggestServlet?prefix=' + str;
		var req  = 'http://suggest.infospace.com/QuerySuggest/SuggestServlet?prefix=' + str;
		jsonClient = new JSONscriptRequest(req, str);
		// Build the dynamic script tag
		jsonClient.buildScriptTag(); 
		// Add the script tag to the page
		jsonClient.addScriptTag();
	};
	
	//handles keyUp event on input edit boxes
	var _onEditKeyUp = function(e){
			if (!e) var e = window.event;
			var code;
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;
			
			if(_activeElement.value == "") _resetRFCID();
			else
			if(_selectedValue != null)
			{
				if(_selectedValue.indexOf(_activeElement.value) != 0) _resetRFCID();
			}
			
			if(code != 27 && code != 40 && code != 38 && code != 13)
			window.setTimeout("iSuggest.insertScriptTag()", _timeoutPeriod);
		};
			
	//handles the global keyboard events 
	this.onKeyUp = function (e){
			if(_suggestionsPanel.style['display'] != 'block' && _suggestionsPanel.childNodes.length == 0) return;
			
			var code;
			if (e.keyCode) code = e.keyCode;
			else if (e.which) code = e.which;
			
			//alert(code);
			switch(code)
			{
				case 40: //handle key down
					_selectNext();
					break;
				case 38: //handle key up
					_selectPrevious();
					break;
				case 27: //handle esc
						_hideSuggestions();
						_activeQuery.query = null;
						_activeQuery.response = null;
					break;
			}
		};	
	
	this.PopulateResults = function(suggestions, reqID){
		_suggestionsPanel.innerHTML = '';
		_currentSelection = -1;
		
		if(suggestions){
			for(var i=0; i < suggestions.length; i++) {
				var suggest = '<div onmouseover="javascript:iSuggest.suggestOver(this);" onmouseout="javascript:iSuggest.suggestOut(this);" onclick="javascript:iSuggest.setSearch(this.childNodes[0].nodeValue);" class="suggest_link" id="suggest_link_'+ i + '">' + suggestions[i] + '</div>';
				_suggestionsPanel.innerHTML += suggest;
			}
		}
		
		JSONscriptRequest.removeScriptTagById(reqID);
		
		if(_suggestionsPanel.innerHTML == "" || suggestions == null)
			_hideSuggestions();
		else
			_showSuggestions();
	};
	
	//global onclick event. used to hide suggestions
	this.onMouseClick = function(){
			_hideSuggestions();
			_activeQuery.query = null;
			_activeQuery.response = null;
		};
	
	//Mouse over function
	this.suggestOver = function (div_value) {	div_value.className = 'suggest_link_over'; };
	
	//Mouse out function
	this.suggestOut = function (div_value) {	div_value.className = 'suggest_link';	};
	
	//Click function
	this.setSearch = function (value) {
			_activeQuery.query = value;
			_activeQuery.response = null;
			
			_hideSuggestions();
			_activeElement.value = value;
			_setRFCID();
			_activeElement.defaultButton.click();
			
			return false;
		};
	
	//initializes the component
	this.init = function(inputToTrack, rfcidFields){
			_rfcidElements = new Array();
			for(var j=0; j<rfcidFields.length; j++)
			{
			if(document.getElementById(rfcidFields[j])!=null)
			{
				_rfcidElements[j] = document.getElementById(rfcidFields[j]);
			}
			}
			
			_originalRFCID = _rfcidElements[0].value;
			
			_suggestionsPanel = document.createElement('div');
			_suggestionsPanel.className = 'suggestPanel';
			_suggestionsPanel.id = 'suggestPanel';
			
			document.body.insertBefore(_suggestionsPanel, document.body.firstChild);
			
			for(var i=0; i<inputToTrack.length; i++){
				this.addField(inputToTrack[i].txt, inputToTrack[i].btn);
			}
		};
	
	//adds a text field to be tracked for suggestions
	this.addField = function(txtID, btnID){
            var textBox = document.getElementById(txtID);
			var button = document.getElementById(btnID);
			if(textBox !=null && button !=null)
			{
			textBox.defaultButton = button;
			
			textBox.oldOnFocus = (textBox.onfocus) ? textBox.onfocus : function() {};
			function newOnFocus(e) {_activeElement = this; this.oldOnFocus();}
			textBox.onfocus = newOnFocus;
			
			textBox.oldOnBlur = (textBox.onblur) ? textBox.onblur : function() {};
			function newOnBlur(e) {if(_suggestionsPanel.style['display'] != 'block')_activeElement = null; this.oldOnBlur();}
			textBox.onblur = newOnBlur;
			
			textBox.oldEditKey = (textBox.onkeyup) ? textBox.onkeyup : function() {};
			function newEditKeyUp(e) {_activeElement = this; this.oldEditKey(); if (!e) var e = window.event; _onEditKeyUp(e);}
			textBox.onkeyup = newEditKeyUp;
			}
        };
    
    //removes a field from tracking for suggestions
    this.removeField = function(txtID){
            var textBox = document.getElementById(txtID);
            textBox.onfocus = textBox.oldOnFocus;
            textBox.onblur = textBox.oldOnBlur;
            textBox.onkeyup = textBox.oldEditKey;
        };
}

//global suggest client object
var iSuggest;

//Initializes the page for suggestions.
function Initialize() {	
	//oldOnload(); 
	iSuggest = new ISuggest();
	iSuggest.init(txtElements, rfcIDElements);
	
	//hook events
	var oldOnClick = (document.onclick) ? document.onclick : function() {};
	function newOnClick(e) {oldOnClick(); if (!e) var e = window.event; iSuggest.onMouseClick(e);}
	document.onclick = newOnClick;
	
	var oldOnKeyUp = (document.onkeyup) ? document.onkeyup : function() {};
	function newOnKeyUp(e) {oldOnKeyUp(); if (!e) var e = window.event; iSuggest.onKeyUp(e);}
	document.onkeyup = newOnKeyUp;
}