/* the search as you type class library (works with JSON only) must be a singleton */

/* globals */

var _currentlySelectedIndex = 0;
var _getAllReturnedSelectableItems = null;
var _thirdPartySearch = null;
var _execFunct = null;
var _textFieldHasFocus = false;
var _enableThirdPartySearch = null;
var _thirdPartySearchUrl = null;
var _mouseIsOverBox = false;

/* interfaces / constructors */

function SearchType(labelContent,buttonContent,classStyle,itemToAppend,selectedFunction,monoUrl,showSubmitButton){
	this.labelContent = labelContent;
	this.buttonContent = buttonContent;
	this.classStyle = classStyle;
	this.itemToAppend = itemToAppend;
	this.executeFunct = selectedFunction;
	this.monoUrl = monoUrl;
        this.useExternalSearch = false;
        this.enableExternalSearch = enableThirdPartySearch;
        this.disableExternalSearch = disableThirdPartySearch;
        this.setThirdPartySearchFunction = setThirdPartySearchFunction;
	this.showSubmitButton = showSubmitButton;
	this.createSearchField = createSearchField;
        _execFunct = selectedFunction;
}

function SearchTypeLight(inputFieldToRead,monoUrl,selectedFunction){
	this.inputFieldToRead = inputFieldToRead;
        this.monoUrl = monoUrl;
	this.executeFunct = selectedFunction;
        this.createSearchField = createSearchField;
	this.monoUrl = monoUrl;
        this.useExternalSearch = false;
        this.enableExternalSearch = enableThirdPartySearch;
        this.disableExternalSearch = disableThirdPartySearch;
        this.setThirdPartySearchFunction = setThirdPartySearchFunction;
        _execFunct = selectedFunction;
}

function SearchTypeInputView(){
  
}

function Callback(){
	this.callBackObj = "";
}

function setThirdPartySearchFunction(farg){
    //console.log(farg);
    _thirdPartySearch = farg;
   // console.log(_thirdPartySearch);
    //console.log("type of: " + typeof(_thirdPartySearch));
}

/* prototypes */

// searchtype prototypes
SearchType.prototype.createSearchField = createSearchField;
SearchType.prototype.searchFieldResponseHandler = searchFieldResponseHandler;

/* implementations */
function hidePortkeyDropdown(obj){
    //console.log("hide portkey dropdown called");
    if(_mouseIsOverBox == false)
    {
      document.getElementById("resultsContainer").style.display = "none";
    }
}

function createSearchField(preCreatedInput){
    
	
        var mainDiv  = null;
        if(preCreatedInput == false){
            this.itemToAppend.innerHTML = "";
          mainDiv = createDivObject("portKeyContainer","portKeyContainer",this.classStyle,"");
		this.itemToAppend.appendChild(mainDiv);
		var labelSpan = createSpanObject("labelSpan","labelSpan","inherited",this.labelContent);
		mainDiv.appendChild(labelSpan);
		var inputBox = createInputObject("searchInput","searchInput","inherited");
			inputBox.onkeyup = function(evt){ loadFieldContent(this, evt) };
            inputBox.onfocus = function() { _textFieldHasFocus = true; };
            inputBox.onmouseover = function() { clearAllSelectedItems() };
            	//inputBox.disabled = "true";
		mainDiv.appendChild(inputBox);
                textFieldId = "searchInput";
        }else{
            mainDiv = this.inputFieldToRead.parentNode;
            this.inputFieldToRead.onkeyup = function(evt){ loadFieldContent(this, evt) };
            
		  this.inputFieldToRead.onfocus = function() { _textFieldHasFocus = true; };
              
            this.inputFieldToRead.onmouseover = function() { clearAllSelectedItems() };
            textFieldId = this.inputFieldToRead.id;
        }
        
		var hMono = createInputObject("hiddenMono","hiddenMono","hiddenInputClass");
			hMono.style.display = "none";
			hMono.value = this.monoUrl;
		mainDiv.appendChild(hMono);
		var hSelectedFunction = createInputObject("hiddenSelectedFunction","hiddenSelectedFunction","hiddenInputClass");
			hSelectedFunction.value = this.executeFunct;
			hSelectedFunction.style.display = "none";
		mainDiv.appendChild(hSelectedFunction);
		if(this.showSubmitButton){
			var submitSpan = createSpanObject("submitSpan","submitSpan","inherited",this.buttonContent);
			mainDiv.appendChild(submitSpan);
				submitSpan.onclick = function(){ loadFieldContent(this) };
		}
	var resultDiv = createDivObject("resultsContainer","resultsContainer","portKey_inherited","");
		resultDiv.style.display = "none";
                 resultDiv.onmouseover = function() { clearAllSelectedItems();_mouseIsOverBox = true; }
                 resultDiv.onmouseout = function() { _mouseIsOverBox = false; }
		mainDiv.appendChild(resultDiv);
                document.getElementsByTagName("body")[0].onclick = function() { hidePortkeyDropdown(true) };
                document.getElementsByTagName("body")[0].onkeydown = function(evt)
                { 
                    if(document.getElementById('resultsContainer').style.display == "block")
                    {
                            if(_textFieldHasFocus == false)
                            {
                              loadFieldContent(document.getElementById(textFieldId), evt);
                              return evt;
                            }
                        }
                    };
		
}

function enableThirdPartySearch()
{
    this.useExternalSearch = true;
    _enableThirdPartySearch = true;
    _thirdPartySearchUrl = this.thirdPartySearchUrl;
}

function disableThirdPartySearch(){
    this.useExternalSearch = false;
    _enableThirdPartySearch = false;
}

// super nasty hack

function clearAllSelectedItems(){
    var results = getAllReturnedSelectableItems();
    for(var i=0; i < results.length; i++){
        if(results[i].className != "childHaving" && results[i].className != "childHavingShownSelected" && results[i].className != "childHavingShown"){
          results[i].className = "inherited_drugres";
        }else{
            if(results[i].className == "childHavingShownSelected"){
                results[i].className = "childHavingShown";
            }else if(results[i].className == "childHavingShown"){
                results[i].className = "childHavingShown";
            }
            else{
                results[i].className = "childHaving";
            }
        }
    }
}

function loadFieldContent(sbox, evt, fromBody){
		if(sbox.value.match(/;|\(|\)|\[|\]|\{|\}|\?|\*/g,"")!= null){
			sbox.value = sbox.value.replace(/;|\(|\)|\[|\]|\{|\}|\?|\*/g,""); // remove ;()[]{}?* in IE and Safari replace sends the cursor to the end of the string, problem for left arrow
		}
		if(evt || event.keyCode)
        {
            //alert('event!');
            if(com.epocrates.online.common.toolLibrary.browserSniffer() != 1){
                var charCode = evt.which;
            }else{
                var charCode = event.keyCode;
            }
            //console.log(charCode);
            if(sbox.value.match(/^a-zA-Z0-9_,; /))
            {
                return;
            }
            /* if(_mouseIsOverBox == true){
                return;
            } */
            if(charCode == 38) // up arrow
            {
                var results = getAllReturnedSelectableItems();	
				// 3rd party search already was selected
				if (_enableThirdPartySearch == true && document.getElementById("thirdPartyLink").className == "portKey_inherited_selected") {
					document.getElementById("thirdPartyLink").className = "externalSearch";
					var lastResult = results.length - 1;
					results[lastResult].className = "portKey_inherited_selected";
					var element = com.epocrates.online.common.toolLibrary.getElementByClass(results, "portKey_inherited_selected");
					var childElement = com.epocrates.online.common.toolLibrary.getElementByClass(results, "childHavingShownSelected");
					return;
				}
				else { // 3rd party search was not already selected
                  var results = getAllReturnedSelectableItems();
                  var element = com.epocrates.online.common.toolLibrary.getElementByClass(results, "portKey_inherited_selected");
                  var childElement = com.epocrates.online.common.toolLibrary.getElementByClass(results, "childHavingShownSelected");
                  if(element != null || childElement != null){
                  	clearAllSelectedItems();
					_currentlySelectedIndex -= 1;
					
  					if(element == results[1] && results[0].className == "childHavingShown") { //first selected child element
						results[1].className = "portKey_inherited_selected";
						results[2].className = "portKey_inherited";
						_currentlySelectedIndex = 1;
						return;
					}else if(element == results[0]){ // first element without child
						results[0].className = "portKey_inherited_selected";
						_currentlySelectedIndex = 0;
						
						return;
							
					} else {
						if(results[_currentlySelectedIndex].className == "childHavingShown" || results[_currentlySelectedIndex].className == "childHaving"){
                               results[_currentlySelectedIndex].className = "childHavingShownSelected";
                               results[_currentlySelectedIndex].className = "childHavingShown";
                              _currentlySelectedIndex --;
                              results[_currentlySelectedIndex].className = "portKey_inherited_selected";
                          }else{
                              results[_currentlySelectedIndex].className = "portKey_inherited_selected";
                          }
                      }
                  }
				  
                  return;
				}
            }
			else if (charCode == 8) // backspace
			{	// do nothing and don't return
			}
 			else if (charCode == 46) // delete key
 			{	// do nothing and don't return
			}
 			else if (charCode == 16) // shift
 			{	// do nothing and don't return
			}
            else if(charCode == 40) // down arrow
            {
							
                results = getAllReturnedSelectableItems();
                element = com.epocrates.online.common.toolLibrary.getElementByClass(results, "portKey_inherited_selected");
                childElement = com.epocrates.online.common.toolLibrary.getElementByClass(results, "childHavingShownSelected");
                clearAllSelectedItems();
				
				//if 3rd party search is selected do nothing
				if (_enableThirdPartySearch == true && document.getElementById("thirdPartyLink").className == "portKey_inherited_selected") { 
						return;
				}
				else {
					if (element == results[0] || element != null || childElement == results[0] || childElement != null) {
						_currentlySelectedIndex += 1;
						if (_currentlySelectedIndex >= results.length) {  //end of results
							_currentlySelectedIndex = (results.length - 1);
							if (_enableThirdPartySearch == true) { //last result select third party
								document.getElementById("thirdPartyLink").className = "portKey_inherited_selected";
								return;
							}else{
								//last result but no third party
								results[_currentlySelectedIndex].className = "portKey_inherited_selected";
								return;
							}
						}
						if (results[_currentlySelectedIndex].className == "childHavingShown" || results[_currentlySelectedIndex].className == "childHaving") {
							results[_currentlySelectedIndex].className = "childHavingShownSelected";
							itemId = results[_currentlySelectedIndex].id;
							document.getElementById(itemId + "_child").style.display = "block";
							results[_currentlySelectedIndex].className = "childHavingShown";
							_currentlySelectedIndex++;
							results[_currentlySelectedIndex].className = "portKey_inherited_selected";
						}
						else {
							results[_currentlySelectedIndex].className = "portKey_inherited_selected";
						}
					}
					else {
						_currentlySelectedIndex = 0;
						if (results[0].className == "childHavingShown" || results[0].className == "childHaving") {
							results[0].className = "childHavingShownSelected";
						}
						else {
							results[0].className = "portKey_inherited_selected";
						}
					}
				}
                return;
            }
            else if(charCode == 13 || sbox.value.length < 1) // enter key
            {
                var searchString = sbox.value;
				//if 3rd party search is selected	
				if(_enableThirdPartySearch == true && document.getElementById("thirdPartyLink") != null && document.getElementById("thirdPartyLink").className == "portKey_inherited_selected") { 
						var searchString = document.getElementById(textFieldId).value;
						_thirdPartySearch(searchString);
				}else{
				
	                if (searchString.length > 0) {
						results = getAllReturnedSelectableItems();
						try {
							if (results[_currentlySelectedIndex].className != "childHavingShownSelected") {
								selectedNode = results[_currentlySelectedIndex];
								loadMonograph(selectedNode);
							}
						} 
						catch (e) { // no matches with input and enter was pressed
							if (_enableThirdPartySearch == true) {
								var searchString = document.getElementById(textFieldId).value;
								_thirdPartySearch(searchString);
							}else{
								return; //do nothing if no matches and no 3rd party
							}
						}
					}
					else {
						document.getElementById('resultsContainer').innerHTML = "";
						document.getElementById('resultsContainer').style.display = "none";
						if (com.epocrates.online.common.toolLibrary.browserSniffer() == 1) { //IE not 7 or 8
							if((navigator.userAgent.toLowerCase().indexOf("7.0;") == -1) && (navigator.userAgent.toLowerCase().indexOf("8.0;") == -1)){
								if (document.getElementById("formId") != null) {
									var selectBoxToHide = document.getElementById("formId");
									selectBoxToHide.style.visibility = "visible";
									delete (selectBoxToHide);
								}
							}
						}
					}	
                }
                return;
            }
         }   
	searchString = sbox.value;
	searchString = encodeURIComponent(searchString);
	if(sbox.id == "submitSpan"){
		
		window.location.href = "/public/portkey/?monograph=" + searchString + "&src=PK";
		return;
	}
	var dUrl = document.getElementById("hiddenMono").value;
         //console.log(dUrl);
	if(searchString == ""){
              var elementId = document.getElementById("resultsContainer").id;
		document.getElementById(elementId).style.display = "none";
                if(com.epocrates.online.common.toolLibrary.browserSniffer() == 1){ //IE not 7 or 8
                	if((navigator.userAgent.toLowerCase().indexOf("7.0;") == -1) && (navigator.userAgent.toLowerCase().indexOf("8.0;") == -1)){
                      if(document.getElementById("formId") != null){
                        var selectBoxToHide = document.getElementById("formId");
                        selectBoxToHide.style.visibility = "visible";
                        delete(selectBoxToHide);
                      }
                    }
                }
		return;
	}
	var cb = new Callback();
	var typeReq = new Request(dUrl + searchString,'searchFieldResponseHandler','text');
	typeReq.doXmlhttp();
        return false;
}

function searchFieldResponseHandler(argText){
	var arrayText = argText.replace("portkey.serviceCallback(","");
	arrayText = arrayText.replace(/&lt;/g,"<");
	var subText = arrayText.substring(0,arrayText.lastIndexOf(")"));
	responseObj = new Callback();
		this.eval("responseObj.callBackObj = { 'drugInfo' : " + subText + "}");
                if(_enableThirdPartySearch != true){
                  if(responseObj.callBackObj.drugInfo.length < 1){
                      document.getElementById('resultsContainer').innerHTML = "";
                      document.getElementById('resultsContainer').style.display = "none";
                      return;
                  }
                }
		buildResponseList(responseObj,document.getElementById('resultsContainer'));
}

function showMonograph(csItem){
	//this.childNodes[1].value
	var mArr = csItem.split("|");
	//alert("/u/" + mArr[1] + "?src=PK");
	document.getElementById("searchInput").value = mArr[0];
	window.location.href = "/u/" + mArr[1] + "?src=PK";
}

function dxLoadMonograph(obj){
    if(!obj){
        if(_enableThirdPartySearch){
            doThirdPartySearch(null);
        }else{
            return;
        }
    }
    var mSection = obj.lang.substring(2,4);
    var mId = obj.lang.substring(4,obj.lang.length);
    window.location.href = "/dx/full.do?ActiveSectionId=" + mSection + "&MonographId=" + mId;
    //alert("/u/" + obj.lang);
    //dx/full.do?Type=1&MonographId=424&ActiveSectionId=11
}

function dxLoadLaunchApi(obj){
    document.getElementById("resultsContainer").style.display = "none";
	window.location.href = "/u/" + obj.lang;
}

function loadMonograph(obj){
    /*var mSection = obj.lang.substring(2,4);
    var mId = obj.lang.substring(4,obj.lang.length);
    window.location.href = "/dx/full.do?ActiveSectionId=" + mSection + "&MonographId=" + mId;
    //alert("/u/" + obj.lang);
    //dx/full.do?Type=1&MonographId=424&ActiveSectionId=11 */
    document.getElementById("resultsContainer").style.display = "none";
	//IE6 needs visibility put back if formulary select was hidden
	if(document.getElementById("formularySelect") != null) {
		document.getElementById("formularySelect").style.visibility = "visible";
	}
	//document.getElementById("searchInput").value = "";
    _execFunct(obj);

}

function getAllReturnedSelectableItems(){
    var itemArray;
    if(!_getAllReturnedSelectableItems){
      var nodes = document.getElementById("resultsContainer").getElementsByTagName("div");
      itemArray = new Array();
      for(var i=0; i < nodes.length; i++){
          if(nodes[i].lang){
              itemArray.push(nodes[i]);
          }
      }
      _getAllReturnedSelectableItems = itemArray;
    }else{
        itemArray = _getAllReturnedSelectableItems;
    }
    return itemArray;
}

function buildResponseList(arrayObj,resultsContainer){
	var titlestring = null;
	var inChild = false;
        _getAllReturnedSelectableItems = null;
	var parentTitle = "";
	var clickFunction = resultsContainer.parentNode.childNodes[3].value;
	resultsContainer.innerHTML = "";
	resultsContainer.style.display = "block";
	for(var i=0;i<arrayObj.callBackObj.drugInfo.length;i++){
		titlestring = arrayObj.callBackObj.drugInfo[i][0].toString().replace(/<span>/g,"").replace(/<\/span>/g,"").replace(/'/g,"&#146\;");
		if(arrayObj.callBackObj.drugInfo[i].length < 3 ){
			inChild = false;
			var drugHtml = "<a href='#' title='" + titlestring + "'>" + arrayObj.callBackObj.drugInfo[i][0] + "</a>";
		}else if(arrayObj.callBackObj.drugInfo[i][2] == "1"){
			inChild = true;
			parentTitle = "drug_" + i;
			var drugHtml = "<a href='#' onmousedown='showHideDrugChild(this)' title='" + titlestring + "'>" + arrayObj.callBackObj.drugInfo[i][0] + "</a>";
		}else{
			var drugHtml = "<a href='#' title='" + titlestring + "'>" + arrayObj.callBackObj.drugInfo[i][0] + "</a>";
		}
		var cdiv = createDivObject("drug_" + i,"drug_" + i,"inherited_drugres",drugHtml);
			if(inChild == true && arrayObj.callBackObj.drugInfo[i].length == 3 && arrayObj.callBackObj.drugInfo[i][2] == 1){
				cdiv.firstChild.onmousedown = function() { showHideDrugChild(this); }
				cdiv.className = "childHaving";
                                cdiv.lang =  arrayObj.callBackObj.drugInfo[i][1];
				//cdiv.onmousedown = function() { return false; };
                                //cdiv.onmouseover = function() { this.className = "portKey_inherited_hover"; };
                                //cdiv.onmouseout = function() { this.className = "portKey_inherited"; };
				var childDivObj = createDivObject("drug_" + i + "_child","drug_" + i + "_child","inherited_drugchildnode","");
					childDivObj.style.display = "none";
				cdiv.appendChild(childDivObj);
			}else{
				if(inChild == false){
					cdiv.onmousedown = function() { loadMonograph(this); }
                                         cdiv.lang =  arrayObj.callBackObj.drugInfo[i][1];
				}else{
					cdiv.onmousedown = function() { loadMonograph(this); }
                                         cdiv.lang =  arrayObj.callBackObj.drugInfo[i][1];
				}
			}
		var hinput = createInputObject("hiddenParam_" + i,"hiddenParam_" + i, "hiddenInputClass");
			hinput.value = arrayObj.callBackObj.drugInfo[i].join("|");
			hinput.style.display = "none";
			cdiv.appendChild(hinput);
		if(inChild == true && arrayObj.callBackObj.drugInfo[i].length == 3 && arrayObj.callBackObj.drugInfo[i][2] == 2){
			document.getElementById(parentTitle + "_child").appendChild(cdiv);
			
		}else{
			resultsContainer.appendChild(cdiv);
		}
	}
        if(_enableThirdPartySearch){
            var thirdPartyDiv = createDivObject("thirdPartyLink","thirdPartyLink","externalSearch","");
                thirdPartyDiv.onmousedown = function() { doThirdPartySearch(this) };
            var thirdPartyP = document.createElement("a");
                thirdPartyP.href = "#";
                thirdPartyP.innerHTML = "Search";
              thirdPartyDiv.appendChild(thirdPartyP);
            resultsContainer.appendChild(thirdPartyDiv);
        }
	_currentlySelectedIndex = 0;
	var results = document.getElementById("resultsContainer").childNodes;
	if(results[0].className != "childHaving") { //select first result if it has no children
		results[0].className = "portKey_inherited_selected";
		results[0].style.display = "block"; //IE 
	}else{ //open first result and select first child
		results[0].className = "childHavingShown";
		document.getElementById("drug_0_child").style.display = "block";
		document.getElementById("drug_1").className = "portKey_inherited_selected";
		_currentlySelectedIndex = 1;
	}
        if(arrayObj.callBackObj.drugInfo.length > 0 ){
          if(com.epocrates.online.common.toolLibrary.browserSniffer() == 1){ //IE not 7 or 8
        	  if((navigator.userAgent.toLowerCase().indexOf("7.0;") == -1) && (navigator.userAgent.toLowerCase().indexOf("8.0;") == -1)){
                if(document.getElementById("formId") != null){
                  var selectBoxToHide = document.getElementById("formId");
                  selectBoxToHide.style.visibility = "hidden";
                  delete(selectBoxToHide);
                }
              }
          }
        }else{
            if(com.epocrates.online.common.toolLibrary.browserSniffer() == 1){
              if(document.getElementById("formId") != null){
                var selectBoxToHide = document.getElementById("formId");
                selectBoxToHide.style.visibility = "visible";
                delete(selectBoxToHide);
              }
          }
            
        }
}

function doThirdPartySearch(obj){
    if(_enableThirdPartySearch == null || _enableThirdPartySearch == false)
    {
        // do nothing
    }else{
      var searchString = document.getElementById(textFieldId).value;
      _thirdPartySearch(searchString);
    }
}

function googleSearch(arg){
    
    window.location = _thirdPartySearchUrl + arg;
}


/* utils */

function showHideDrugChild(item){
    
	if(item.parentNode.lastChild.previousSibling.style.display == "block"){
		item.parentNode.lastChild.previousSibling.style.display = "none";
		item.parentNode.className = "childHaving";
		//item.parentNode.getElementsByTagName("img")[0].src = "start/arr.gif";
	}else{
		item.parentNode.lastChild.previousSibling.style.display = "block";
		item.parentNode.className = "childHavingShown";
		//item.parentNode.getElementsByTagName("img")[0].src = "start/arr_exp.gif";
	}
        return false;
}

function createSpanObject(itemId,itemName,itemClassName,contentHtml){
	if(com.epocrates.online.common.toolLibrary.browserSniffer() != 1){
		var spn = document.createElement("span");
			spn.id = itemId;
			spn.name = itemName;
	}else{
		var spn = document.createElement("<span id='" + itemId + "' name='" + itemName + "'>");
	}
	spn.className = itemClassName;
	spn.innerHTML = contentHtml;
	return spn;
}

function createDivObject(itemId,itemName,itemClassName,contentHtml){
	if(com.epocrates.online.common.toolLibrary.browserSniffer() != 1){
		var dpn = document.createElement("div");
			dpn.id = itemId;
			dpn.name = itemName;
	}else{
		var dpn = document.createElement("<div id='" + itemId + "' name='" + itemName + "'>");
	}
	dpn.className = itemClassName;
	dpn.innerHTML = contentHtml;
	return dpn;
}

function createInputObject(itemId,itemName,itemClassName){
	if(com.epocrates.online.common.toolLibrary.browserSniffer() != 1){
		var ipn = document.createElement("input");
			ipn.id = itemId;
			ipn.name = itemName;
	}else{
		var ipn = document.createElement("<input id='" + itemId + "' name='" + itemName + "'>");
	}
	ipn.className = itemClassName;
	return ipn;
}
