/**
 *  product support application functions
 *  psa_typeahead.js
 *  $Revision: 1.3 $
 */


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 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;      

/* character bolding removed from spec 3/6/09 */
/*         if (typeof response.SearchResult.searchPhrase != "undefined"){
            var str = suggestion.display.toLowerCase();
            var phrase = response.SearchResult.searchPhrase.toLowerCase();
            var p=-1;
            var cur = 0;
            suggestion.display = "";
            while ((p = str.substring(cur).indexOf(phrase))>=0){
              suggestion.display += suggestion.name.substring(cur,cur+p);
              suggestion.display += "<b>"+suggestion.name.substring(cur+p,cur+p+phrase.length)+"</b>";
              cur += (p + phrase.length);
              }
            suggestion.display += suggestion.name.substring(cur);
            }
*/

         suggestions.push(suggestion);
         }
      }
   oTextbox.autosuggest(suggestions,false);
   }

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();
    
}
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) {
	//****************************************************************************************
	// 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();
    }
};

// following function not used
AutoSuggestControl.prototype.recordDocumentClick = function (url,text){
  if (typeof ntptEventTag != "function"){
     return true;
     }

  ntptAddPair("ev","ngw");
  ntptAddPair("basepageUrl",window.location.href);
  ntptAddPair("basepageTitle",document.title);
  ntptAddPair("linkUrl",url);
  ntptAddPair("linkText",text);
  ntptAddPair("sitearea","supportPSA");
  ntptAddPair("path","");
  ntptAddPair("action","search");

  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();
  };

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);
  };

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);
    };

AutoSuggestControl.prototype.requestSuggestions = function (bTypeAhead) {
   var oThis = this;
   var fragment = oThis.textbox.value.toLowerCase();
   var encoded_fragment = encodeURIComponent(fragment);
   encoded_fragment = encoded_fragment.replace(/%2F/,"/");
   var url = psa_autosuggest_service_root
            +psa_autosuggest_service_prefix
            +"autosuggest/"
            +psa_autosuggest_task_name
            +"/"
            +psa_autosuggest_entitlement
            +"/250/"
            +encoded_fragment+"?callback=showtypeahead";
   if (typeof psa_autosuggest_service_environment != "undefined"){
      url += "&" + psa_autosuggest_service_environment;
      }
   if (fragment.length > 2){
      this.jsonp_request(url);
      }
   else{
      this.hideSuggestions();
      }

   };

// 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
    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;
//            	 for (var found=false, i=0; (found==false) && i<asLinks.length; i++){
//            	 	   found = (oTarget.childNodes[0].rel==asLinks[i].url);
//            	 	  }
//            	 var this_text = "";
//            	 if (found==true){
//            	 	  this_text = asLinks[--i].name;
//            	 	}
		ntptAddPair("linkUrl",this_url);
		ntptAddPair("linkText",this_linktext);
               oThis.recordSearch("action=dclick&search_type=autosuggest");
               oThis.hideSuggestions();
               oThis.textbox.value="";
               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.
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="";
               this.textbox.form.action=url;
               // missing: linkUrl, linkText; do not fire because the search is already recorded via the submit event
//               this.recordSearch("action=dclick&search_type=autosuggest");
               }
            else { // user is submitting form
               this.hideSuggestions();
               // call Unica code because submit method will not trigger onsubmit
               this.recordSearch("action=search&search_type=freeform");
               this.textbox.form.submit();

               }

        }
   };

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;
//       this.cur = -1;
       }

};

// 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 = "";
            }
        }
};

// Initializes the textbox with event handlers for autosuggest functionality.
AutoSuggestControl.prototype.init = function () {

    //save a reference to this object
    var oThis = this;
    
    //assign the onkeyup event handler
    this.textbox.onkeyup = function (oEvent) {
    
        //check for the proper location of the event object
        if (!oEvent) {
            oEvent = window.event;
        }    
        
        //call the handleKeyUp() method with the event object
        oThis.handleKeyUp(oEvent);
    };
    
    this.textbox.onmousedown = function (oEvent) {
        //check for the proper location of the event object
        if (!oEvent) {
            oEvent = window.event;
        }    
        // there's an onmousedown handler on the body which
        // will hide the autosuggestions, so cancel the bubble
        oEvent.cancelBubble = true;
        }

    //assign onkeydown event handler
    this.textbox.onkeydown = function (oEvent) {
    
        //check for the proper location of the event object
        if (!oEvent) {
            oEvent = window.event;
        }    
        
        //call the handleKeyDown() method with the event object
        oThis.handleKeyDown(oEvent);
    };
    
    document.body.onmousedown = function(oEvent){
        oThis.hideSuggestions();
        }

    this.textbox.form.onsubmit = function(){
        return oThis.submitForm();
        }

    document.getElementById("pssubmitbutton").onfocus = function(){
        oThis.hideSuggestions();
        }

    //create the suggestions dropdown
//    no... create it each time it gets displayed so that
//    the height can be set each time based on number of suggestions
//    this.createDropDown();
};

// 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.scrollIntoView(true);
           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;
//        oDiv3 = document.createElement("SPAN");
        oDiv2.innerHTML = aSuggestions[i].display;
//        oDiv2.appendChild(document.createTextNode(aSuggestions[i].name));
        oDiv.appendChild(oDiv2);
//        oDiv2.appendChild(oDiv3);
        this.layer.appendChild(oDiv);
    }
    // ck: removed this.layer.style.left = this.getLeft(this.textbox) + "px";
    // ck: removed this.layer.style.top = (this.getTop(this.textbox)+this.textbox.offsetHeight) + "px";
    /* 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;
//        oDiv3 = document.createElement("SPAN");
        oDiv2.innerHTML = aSuggestions[i].display;
//        oDiv2.appendChild(document.createTextNode(aSuggestions[i].name));
        oDiv.appendChild(oDiv2);
//        oDiv2.appendChild(oDiv3);
        this.layer.appendChild(oDiv);

    }
	//this.layer.style.zIndex="15";

};

// 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);
    }
};

// create AutoSuggest
var oTextbox = new AutoSuggestControl(document.getElementById("searchstring"));

