/**
 *  product support application functions
 *  psa_typeahead.js
 *  $Revision: 1.9 $
 *  README: init() begins on line 36 - events reference functions as handlers
 *     and do not prevent default behavior or stop propagation
 *     (Exception: cancelBubble is set to true for mousedown - necessary?)
 */
 
var url_suffix = "";
var url_prefix = "";

if (typeof(cdc) == "undefined"){
   var cdc = new Object();
}

cdc.includer.loadJs("/web/fw/lib/ntpagetag.js");

var suggestions = new Array();

function AutoSuggestControl(oTextbox) {
    // The currently selected suggestions.
    this.cur = -1;
    // The dropdown list layer.
    this.layer = null;    
    // The textbox to capture.
    this.textbox = oTextbox;
    // what the user typed in
    this.userinput = "";
    //initialize the control
    this.init();    
}

// Initializes the textbox with event handlers for autosuggest functionality.
AutoSuggestControl.prototype.init = function () {
	//save a reference to this object
	var oThis = this;
	
	var suggestObj = jQuery("#searchstring");
	
	suggestObj.keyup(function(oEvent) {
		//call the handleKeyUp() method with the event object
		oThis.handleKeyUp(oEvent);
	});
	
	suggestObj.mousedown(function(oEvent) {
		// there's an onmousedown handler on the body which
		// will hide the autosuggestions, so cancel the bubble
		oEvent.cancelBubble = true;
	});
	
	suggestObj.keydown(function(oEvent) {
		//call the handleKeyDown() method with the event object
		oThis.handleKeyDown(oEvent);
	});
	 
	jQuery("body").mousedown(function(){
		// hide suggestions when user clicks elsewhere on the page
		oThis.hideSuggestions();
	});
	
	jQuery("#pssubmitbutton").mousedown(function(){
		//redirect to search results on submit button click
		var searching = encodeURIComponent(jQuery("#searchstring").val());
		var searchUrl = jQuery("form[name=selectProduct]").attr('action') + "?q=" + searching + "&task=" + psa_autosuggest_task_name;
		window.parent.location.href = searchUrl;
	});

	jQuery("form[name=selectProduct]").submit(function() {
		return false;
	});

	jQuery("#pssubmitbutton").focus(function(){
		oThis.hideSuggestions();
	});
	
}

AutoSuggestControl.prototype.geturl = function (s) {
   if (s.indexOf("*")==0){
      return url_prefix + s.substring(1) + url_suffix;
   }
   return s;
};
   
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/,
                                                     bTypeAhead /*:boolean*/) { 
    //make sure there's at least one suggestion
    if (aSuggestions.length > 0) {
        if (bTypeAhead) {		
			this.hideSuggestions();
			//****************************************************************************************
			// uncomment below to prepopulate text input field while typing.  
			// Also uncomment/replace areas in suggestions_(product or technology).php
			//this.typeAhead(aSuggestions[0]);
			//****************************************************************************************
		}        
        this.showSuggestions(aSuggestions);
    } else {
        this.hideSuggestions();
    }
};

AutoSuggestControl.prototype.recordSearch = function (querymod){
  if (typeof ntptEventTag != "function"){
		return true;
	}

  ntptAddPair("ev","ngw");
  ntptAddPair("basepageUrl",window.location.href);
  ntptAddPair("basepageTitle",document.title);
  ntptAddPair("sitearea","supportPSA");
  
  if (this.textbox.value != null && this.textbox.value != "") {
	  ntptAddPair("searchPhrase",this.textbox.value);
  }	
  if (typeof psa_task_name != "undefined"){
		if (psa_task_name == "default"){
			ntptAddPair("task","product");
		} else {
			ntptAddPair("task",psa_task_name);
		}
	}
  if (typeof psa_clickCount != "undefined"){
		ntptAddPair("clickCount",psa_clickCount);
	}
  if (typeof psa_entitlement != "undefined"){
		ntptAddPair("entitlement",psa_entitlement);
	}
  if (typeof psa_current_mode != "undefined"){
		ntptAddPair("tab",psa_current_mode);
	}
  if ((typeof cdc.psa != "undefined")
			&& (typeof cdc.psa.user_state != "undefined")){
		if (cdc.psa.user_state == "loggedIn"){
			ntptAddPair("loggedIn","Yes");
			ntptAddPair("status","loggedIn");
		} else {
			ntptAddPair("loggedIn","No");
			if (cdc.psa.user_state.indexOf("recognized")>=0){
				ntptAddPair("status","Recognized");
			} else {
				ntptAddPair("status","Anonymous");
			}
		}
	}
  ntptEventTag(querymod);
};

/**
 * fire a unica event when user submits a search
 **/
AutoSuggestControl.prototype.submitForm = function () {
   // Unica
   this.recordSearch("action=search&search_type=freeform");
   return true;
};

AutoSuggestControl.prototype.jsonp_request = function(url){
    var script = document.createElement("script");
    script.setAttribute("src",url);
    script.setAttribute("type","text/javascript");
    document.body.appendChild(script);
};

/**
 * ajax call to retrieve list for autosuggest dropdown
 * calls are made after user types in 3 or more characters
 **/
AutoSuggestControl.prototype.requestSuggestions = function (bTypeAhead) {
   var oThis = this;
   var fragment = oThis.textbox.value.toLowerCase();
   
	if(fragment.length <= 2){
		this.hideSuggestions();
	}else{
  	var encoded_fragment = encodeURIComponent(fragment);
		encoded_fragment = encoded_fragment.replace(/%2F/,"/");
		var service_environment = (typeof psa_autosuggest_service_environment != "undefined")? "&" + psa_autosuggest_service_environment : "";
		var url = psa_autosuggest_service_root
				+ psa_autosuggest_service_prefix
				+ "autosuggest/"
				+ psa_autosuggest_task_name
				+ "/"
				+ psa_autosuggest_entitlement
				+ "/250/"
				+ encoded_fragment
				+ "?locale="+psa_autosuggest_languagecode
				+ service_environment
				+ "&callback=?";
		jQuery.getJSON(url,function(data){showtypeahead(data);});
	}
};

// Creates the dropdown layer to display multiple suggestions.
AutoSuggestControl.prototype.createDropDown = function () {
	var oThis = this;

	this.cur = -1;

	//create the layer and assign styles
	this.layer = document.createElement("div");
	this.layer.className = "suggestions";
	this.layer.style.visibility = "hidden";
	this.layer.style.width = this.textbox.offsetWidth-2;
	this.layer.style.overflow = "auto";
    
	//when the user clicks on the a suggestion, get the text (innerHTML)
	//and place it into a textbox ** needs to be rewritten
	this.layer.onmousedown = 
	this.layer.onmouseup = 
	this.layer.onmouseover = function (oEvent) {
		oEvent = oEvent || window.event;
		oTarget = oEvent.target || oEvent.srcElement;
		oTarget = oTarget.parentNode;

		if (oEvent.type == "mousedown") {
			if(oTarget.className.indexOf("current")>=0){
				var this_url = oThis.geturl(oTarget.childNodes[0].rel);
				var this_linktext = oTarget.childNodes[0].innerHTML;
				ntptAddPair("linkUrl",this_url);
				ntptAddPair("linkText",this_linktext);
				oThis.recordSearch("action=dclick&search_type=autosuggest");
				oThis.hideSuggestions();
				oThis.textbox.value="";
				//redirect to the indicated product page
				window.parent.location.href=this_url;
			} else { // on scrollbar?
				oEvent.cancelBubble = true ; 
			}
		} else if (oEvent.type == "mouseover") {
			oThis.highlightSuggestion(oTarget);
		} else {
			oThis.textbox.focus();
		}
	};
	oThis.textbox.form.appendChild(this.layer);
};

// Handles three keydown events.
// called by handler bound in the init() function
AutoSuggestControl.prototype.handleKeyDown = function (oEvent /*:Event*/) {
	switch(oEvent.keyCode) {
		case 38: //up arrow
			this.previousSuggestion();
			break;
		case 40: //down arrow 
			this.nextSuggestion();
			break;
		case 13: //enter
			// this will fire when the user presses enter to submit
			//  the search form or when an autosuggestion is highlighted 
			if (this.cur > -1){ // something is highlighted
				var url = this.geturl(this.layer.childNodes[this.cur].childNodes[0].rel);
				ntptAddPair("linkUrl",url);
				ntptAddPair("linkText",this.textbox.value);
				ntptAddPair("search_type","autosuggest");
				ntptAddPair("searchPhrase",this.textbox.value);
				this.hideSuggestions();
				this.textbox.value="";
				// redirect to indicated product page
				window.parent.location.href=url;
			} else { // user is submitting form
				this.hideSuggestions();
				// normalize input and redirect to search results
				validateInput();
				var searching = encodeURIComponent(jQuery("#searchstring").val());
				var searchUrl = jQuery("form[name=selectProduct]").attr('action') + "?q=" + searching + "&task=" + psa_autosuggest_task_name;
				window.parent.location.href = searchUrl;
			}
	}
};

AutoSuggestControl.prototype.getLeft = function (oNode){
	var iLeft = 0;
	while(oNode.tagName != "BODY") {
		iLeft += oNode.offsetLeft;
		oNode = oNode.offsetParent;        
	}
	return iLeft;
};

AutoSuggestControl.prototype.getTop = function (oNode){
	var iTop = 0;
	while(oNode.tagName != "BODY") {
		iTop += oNode.offsetTop;
		oNode = oNode.offsetParent;
	}
	return iTop;
};

// Handles keyup events.
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
	var iKeyCode = oEvent.keyCode;
	//for backspace (8) and delete (46), shows suggestions without typeahead
		if (iKeyCode == 8 || iKeyCode == 46) {
			this.userinput = this.textbox.value;
			this.requestSuggestions(this, false);        
    //make sure not to interfere with non-character keys
    } else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
			//ignore
    } else {
			//request suggestions from the suggestion provider with typeahead
			this.userinput = this.textbox.value;
			this.requestSuggestions(this, true);
    }
};

// Hides the suggestion dropdown.
AutoSuggestControl.prototype.hideSuggestions = function () {
	if (this.layer != null){
		if (this.layer.childNodes){
			while (this.layer.childNodes.length > 0){
				this.layer.removeChild(this.layer.firstChild);
			}
		}
		this.textbox.form.removeChild(this.layer);
		this.layer = null;
	}
};

// Highlights the given node in the suggestions dropdown.
AutoSuggestControl.prototype.highlightSuggestion = function (oSuggestionNode) {
	for (var i=0; i < this.layer.childNodes.length; i++) {
		var oNode = this.layer.childNodes[i];
		if (oNode == oSuggestionNode) {
			oNode.className = "ascurrent";
			this.cur = i;
		} else {
			oNode.className = "";
		}
	}
};

// Highlights the next suggestion in the dropdown and places the 
// suggestion into the textbox.
AutoSuggestControl.prototype.nextSuggestion = function () {
	var cSuggestionNodes = this.layer.childNodes;
	if (cSuggestionNodes.length > 0 && this.cur < cSuggestionNodes.length-1) {
		var oNode = cSuggestionNodes[++this.cur];
		this.highlightSuggestion(oNode);
		this.textbox.value = suggestions[this.cur].name; 
		if((oNode.offsetTop+oNode.offsetHeight) > oNode.offsetParent.offsetHeight){
			oNode.scrollIntoView(false);
		}
	}
};

// Highlights the previous suggestion in the dropdown and
//    places the suggestion into the textbox.
AutoSuggestControl.prototype.previousSuggestion = function () {
	var cSuggestionNodes = this.layer.childNodes;
	if (this.cur == 0){
		var oNode = cSuggestionNodes[this.cur--];
		oNode.className = ""      
		this.textbox.value = this.userinput;
	}else{
		if (cSuggestionNodes.length > 0 && this.cur > 0) {
			var oNode = cSuggestionNodes[--this.cur];
			this.highlightSuggestion(oNode);
			this.textbox.value = suggestions[this.cur].name;   
			if(oNode.offsetTop < oNode.offsetParent.scrollTop){
				oNode.offsetParent.scrollTop = oNode.offsetTop;
			}
		}
	}
};

// Selects a range of text in the textbox.
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*:int*/) {
	//use text ranges for Internet Explorer
	if (this.textbox.createTextRange) {
		var oRange = this.textbox.createTextRange(); 
		oRange.moveStart("character", iStart); 
		oRange.moveEnd("character", iLength - this.textbox.value.length);      
		oRange.select();
    //use setSelectionRange() for Mozilla
	} else if (this.textbox.setSelectionRange) {
		this.textbox.setSelectionRange(iStart, iLength);
	}     
	//set focus back to the textbox
	this.textbox.focus();      
}; 

// Builds the suggestion layer contents, moves it into position,
//    and displays the layer.
AutoSuggestControl.prototype.showSuggestions = function (aSuggestions /*:Array*/) {
	if (this.layer != null){
		this.hideSuggestions();
	}
	//   moved call to createDropDown to here from init()
	this.createDropDown();    

	var oDiv = null;
	var oDiv2 = null;
	var oDiv3 = null;
	//    this.layer.innerHTML = "";  //clear contents of the layer
    
	for (var i=0; (i < aSuggestions.length) && (i<10) ; i++) {
		oDiv = document.createElement("div");
		oDiv2 = document.createElement("div");
		oDiv2.className="psindent";
		oDiv2.rel=aSuggestions[i].url;
		oDiv2.innerHTML = aSuggestions[i].display;
		oDiv.appendChild(oDiv2);
		this.layer.appendChild(oDiv);
	}
	/* ck: added */ this.layer.style.marginLeft = "0";
	/* ck: added */ this.layer.style.marginTop = "-1px";
	this.layer.style.visibility = "visible";
	this.layer.style.height = this.layer.offsetHeight-14+"px"; /* ck -14 for b38 */
	if (aSuggestions.length < 10) { /* ck b537 */
		this.layer.style.overflow = "hidden";
	} else {
		this.layer.style.overflow = "auto";
	}
	for (var i=10; i < aSuggestions.length ; i++) {
		oDiv = document.createElement("div");
		oDiv2 = document.createElement("div");
		oDiv2.className="psindent";
		oDiv2.rel=aSuggestions[i].url;
		oDiv2.innerHTML = aSuggestions[i].display;
		oDiv.appendChild(oDiv2);
		this.layer.appendChild(oDiv);
	}
};

// Inserts a suggestion into the textbox, highlighting the 
//     suggested part of the text.
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {
	//check for support of typeahead functionality
	if (this.textbox.createTextRange || this.textbox.setSelectionRange){
		var iLen = this.textbox.value.length; 
		this.textbox.value = sSuggestion; 
		this.selectRange(iLen, sSuggestion.length);
	}
};

function showtypeahead(response){
   if(response.SearchResult.status=="SUCCESS"){
      suggestions = [];
      for (var i = 0; i<response.SearchResult.results.length; i++){
         var suggestion = new Object;
         suggestion.name=response.SearchResult.results[i].title;      
         suggestion.display=response.SearchResult.results[i].title;      
         suggestion.url=response.SearchResult.results[i].url;      
         suggestions.push(suggestion);
			}
	}
	oTextbox.autosuggest(suggestions,false);
}

/** 
 * validate search string before submitting. scrub input of: < > " ' &lt; &gt; 
 **/
function validateInput() {
	var i = document.selectProduct.q.value;
	i = i.replace(/<|>|&lt;|&gt;/g,"");
	i = i.replace(/'/g,"&#39;");
	i = i.replace(/"/g,"&#34;");
	document.selectProduct.q.value = i;
}

// create AutoSuggest
var oTextbox = new AutoSuggestControl(document.getElementById("searchstring"));