/**
 * Initializes triple search and keyword search page.
 */

// anonymous function is defined and called immediately to avoid global namespace pollution
(function() {
	
	var Ylang = YAHOO.lang;
	var Ywdg = YAHOO.widget;
	var Ydom = YAHOO.util.Dom;
	var Yevt = YAHOO.util.Event;
	var Ycon = YAHOO.util.Connect;
	
	var formName = "searchForm";
	// database and navtype comboboxes
	var dbCombobox = Ydom.get("dbSelector");
	var navTypeCombobox = Ydom.get("navTypeSelector");
	var container = document.getElementById("textFileArea");
	var resultPage = document.getElementById("resultPageId");
	
	// common configuration object for data source objects
	var commonConfDS = {
		scriptQueryParam: "termsstr",
		queryMatchContains: true,
		maxCacheEntries: 0   // can't cache because database and navtype may be changed, giving different results
	};
	
	var schema = ["suggestions", "text"];
	
	// defining data sources
	var keywordDS = new Ywdg.DS_XHR("ajax/triple_search/suggest_terms.jsp", schema, commonConfDS);
	var subjectDS = new Ywdg.DS_XHR("ajax/triple_search/suggest_terms.jsp", schema, commonConfDS);
	var predicateDS = new Ywdg.DS_XHR("ajax/triple_search/suggest_terms.jsp", schema, commonConfDS);
	var objectDS = new Ywdg.DS_XHR("ajax/triple_search/suggest_terms.jsp", schema, commonConfDS);
	
	// this function alters the format of each autocomplete result item, highlighting the matches between them and the
	// user query terms
	function commonFormatResult(oResultItem, sQuery) {
		var result = oResultItem[0];
		sQuery = Ylang.trim(sQuery);
		
		var terms = sQuery.split(/\s+/);
		for (var i = 0; i < terms.length; i++) {
			// matches occur at the beginning of words and are case insensitive
			var regex = new RegExp("\\b" + terms[i], "gi");
			result = result.replace(regex, "<strong>$&</strong>");
		}
		
		return result;
	}
	
	// common configuration object for the autocomplete objects
	var commonConfAC = {
		maxResultsDisplayed: 30,
		formatResult: commonFormatResult,
		minQueryLength: 2
	};
	
	// defining autocomplete objects
	new Ywdg.AutoComplete("keywordInput", "keywordContainer", subjectDS, commonConfAC);
 	new Ywdg.AutoComplete("subjectInput", "subjectContainer", subjectDS, commonConfAC);
 	new Ywdg.AutoComplete("predicateInput", "predicateContainer", predicateDS, commonConfAC);
 	new Ywdg.AutoComplete("objectInput", "objectContainer", objectDS, commonConfAC);
 	
 	function executeSearch(e) {
 	 		var selectedDB = dbCombobox.options[dbCombobox.selectedIndex].value;
 	 		var selectedNavType = navTypeCombobox.options[navTypeCombobox.selectedIndex].value;
 	 		
 	 		Ycon.setForm(formName);
 	 		Ycon.asyncRequest("GET", "ajax/triple_search/search_results.jsp", {
 	 			
 		 		success: function(o) {
 	 			
 	 			var results = Ylang.JSON.parse(o.responseText).results;
 		 			Ydom.setStyle("textFileArea", "display", "block");
 		 			
 		 			Ydom.setStyle("absHeader", "visibility", "visible");
 		 			Ydom.setStyle("textFileArea", "visibility", "visible");
 		 			
 		 			Ydom.setStyle("histHeader", "visibility", "visible");
 		 			Ydom.setStyle("histAreaId", "visibility", "visible");
 		 			
 		 			Ydom.setStyle("homeHr", "visibility", "visible");
 		 			Ydom.setStyle("saveIconID", "visibility", "visible");
 		 			
 		 			if (results.length > 0) {
 		 				var resultsCode = "";
 		 				
 		 				for (var i = 0; i < results.length; i++) {
 		 					if(i==10)break;
 		 					//DELROY: 
 		 					if(Ydom.get("page").innerHTML == "keywordSearch"){//DELROY: HACK: keyword search
 			 					var token = (results[i].text).split(" ");
 			 					var newResultsCode = "";
 			 					for(var j=0; j<token.length; j++){
 			 						if(token[j].match("<span") != null){
 			 							var begin = token[j+1].indexOf(">")+1;
 			 							var term = token[j+1].substring(begin, token[j+1].length);
 			 							token[j] = token[j].replace(/<span/, "<span onmouseover=\"fadeBox.showTooltip(event,'Click for more options!');\" onclick=menu(event); onmouseout=restore(event);");
 			 							//onclick=spanHover(event,'"+term+"','t2','PopupId1'); 
 			 						}//end if
 			 						newResultsCode += token[j] + " ";	
 			 					}//end for
 			 					//DELROY: rename abstract ids to disambiguate from span ids
 			 					
 			 					results[i].pmid = "ABS"+results[i].pmid;
 			 					resultsCode += 
 			 						"<div id='"+results[i].pmid+"' class='abstract'>" +
 			 							
 			 						"<img class=\"divPromote\" src=\'img/promote.jpg\' onmouseover=\"fadeBox.showTooltip(event,'Click to promote');\"  onclick=\"promoteDemoteDIV('"+results[i].pmid+"', true);\"></img>" +	
 			 							"<img class=\"divClose\" src=\'img/exit.jpg\' onmouseover=\"fadeBox.showTooltip(event,'Click to remove');\" onclick=\"closeDIV('"+results[i].pmid+"');\"></img>" +
 			 							"<img class=\"pushPin\" src=\'img/unlock.gif\' onmouseover=\"fadeBox.showTooltip(event,'Keep this for next search');\" onclick=\"addRemoveBookmarkItem(event, '"+results[i].pmid+"');\"></img>" +
 			 							"<span class=\"origId\">"+ results[i].pmid +"</span>"+
 			 							"<span id=\"T"+results[i].pmid+"\" class=\"tempTrail\"></span>"+			 							
 			 							//"<div id='PMID" + results[i].pmid + "' class='PMID'><br/><a href='http://www.ncbi.nlm.nih.gov/sites/entrez?cmd=Retrieve&db=pubmed&dopt=AbstractPlus&list_uids="+results[i].pmid+"'>"+results[i].pmid+"</a></div>"+
 			 								"<div id='GeneRif" + results[i].pmid	+ "' class='GeneRif'>" + 
 			 									newResultsCode +
 			 								"</div>" +
 			 						"&nbsp;<p/></div>";
 		 						
 			 					}
 		 					else{ //triple search
 		 						results[i].pmid = "ABS"+results[i].pmid;	
 		 						resultsCode += 
 		 							"<div id='"+results[i].pmid+"' class='abstract'>" +
 		 							"<img class=\"divPromote\" src=\'img/promote.jpg\' onmouseover=\"fadeBox.showTooltip(event,'Click to promote');\" onclick=\"promoteDemoteDIV('"+results[i].pmid+"', true);\"></img>" +	
 		 							"<img class=\"divClose\" src=\'img/exit.jpg\' onmouseover=\"fadeBox.showTooltip(event,'Click to remove');\" onclick=\"closeDIV('"+results[i].pmid+"');\"></img>" +	
 		 							"<img class=\"pushPin\" src=\'img/unlock.gif\' onmouseover=\"fadeBox.showTooltip(event,'Keep this for next search');\" onclick=\"addRemoveBookmarkItem(event, '"+results[i].pmid+"');\"></img>" +
 		 							"<span>"+ results[i].pmid +"</span>"+
 		 							"<div id='GeneRif" + results[i].pmid	+ "' class='GeneRif'>" + 
 		 							results[i].text + "&nbsp;(<a href=\"/semantic_browser/validated_relationships.jsp?pmid=" + results[i].pmid +
 									"&databaseid=" + selectedDB +
 									"&navtype=" + selectedNavType +
 									"\">browse</a>)" +
 		 						"</div>" +
 		 						"&nbsp;<p/></div>";
 		 						
 		 		 			}
 		 				}//end for
 		 				//DELROY: update textarea with bookmarked items and result of new search
 		 				container.innerHTML = "";
 		 				$(container).insert(resultsCode);
 		 				
 		 				//create pagination
 		 				//resultPage.style.visibility = "visible";
 		 				var pages = parseInt(results.length)%10;
 		 				
 		 				var links;
 		 				var cntr = 0;
 		 				resultPage.innerHTML = "";
 		 				while(cntr <= pages){
 		 					resultPage.innerHTML = resultPage.innerHTML + " <a href=\"\">" + cntr + "</a>";
 		 					cntr++;
 		 				}
 		 				
 		 				var children = $(container).childElements();
 		 				if(children != null){//insert bookmarked items at beginning of div
 		 					//var tokens = bookmarkedItems.split("_");
 			 				for(var j = bookmarkArray.length-1; j >= 0 ; j--){ 
 			 					var child = document.getElementById(bookmarkArray[j].id);
 			 					if(child != null){ //only remove node if it existss
 			 						$(child).remove();
 			 					}//end if
 			 					$(container.firstChild).insert({'before': bookmarkArray[j]});
 			 				}//end for
 		 				}//end if
 		 			}
 		 			else {
 		 				//error message control
 		 				var errorMessage = "<p /><div class=\"errorMessage\">No results found</div>";
 		 				var answer = confirm("No results found for \""+ Ydom.get(keywordInput).value + "\". Would you like to keep the current results?");
 		 				if (answer){
 		 					//do nothing
 		 				}
 		 				else{
 		 					
 		 					container.innerHTML = "";
 		 					$(container).insert(errorMessage);
 		 				}
 		 			}//end if-else
 		 		}
 		 		
 		 	});
 		 	
 		 	Yevt.preventDefault(e);
 	 	
 	}

 	Yevt.on(formName, "submit", executeSearch);

	
	// changes the configuration of the Data Source objects corresponding to the user selection concerning database and navtype 
	function changeScriptQueryAppend() {
		var scriptQueryAppend = "";
		
		scriptQueryAppend += "databaseid=" + dbCombobox.options[dbCombobox.selectedIndex].value;
		scriptQueryAppend += "&navtype=" + navTypeCombobox.options[navTypeCombobox.selectedIndex].value;
		
		keywordDS.scriptQueryAppend = scriptQueryAppend + "&requestedterm=keyword";
		subjectDS.scriptQueryAppend = scriptQueryAppend + "&requestedterm=subject";
		predicateDS.scriptQueryAppend = scriptQueryAppend + "&requestedterm=predicate";
		objectDS.scriptQueryAppend = scriptQueryAppend + "&requestedterm=object";
		
	}
	
	// retrieves navtypes related to a database and displays them
	function retrieveNavTypes() {
		Ycon.setForm(formName);
		Ycon.asyncRequest("GET", "XMLGenerator.jsp?t15=true", {
			
			success: function(o) {
				var navTypes = o.responseXML.firstChild.childNodes;
				
				while (navTypeCombobox.hasChildNodes()) {
					navTypeCombobox.removeChild(navTypeCombobox.firstChild);
				}
				
				for (var i = 0; i < navTypes.length; i++) {
					var node = navTypes[i];
					
					if (node.nodeType === 1  /* Node.ELEMENT_NODE */) {
						var option = document.createElement("option");
						option.value = option.text = node.firstChild.data;
						navTypeCombobox.appendChild(option);
					}
				}
				
				changeScriptQueryAppend();
			}
			
		});
	}
	
	// retrieving existing databases
	Ycon.asyncRequest("GET", "XMLGenerator.jsp?t14=true", {
		
		success: function(o) {
			var databases = o.responseXML.firstChild.childNodes;
			
			for (var i = 0; i < databases.length; i++) {
				var node = databases[i];
				
				if (node.nodeType === 1  /* Node.ELEMENT_NODE */) {
					var option = document.createElement("option");
					option.value = option.text = node.firstChild.data;
					dbCombobox.appendChild(option);
				}
			}
			
			retrieveNavTypes();
		}
		
	});
 	
 	// defining behavior for database and navtype selectors
 	Yevt.on(dbCombobox, "change", retrieveNavTypes);
	Yevt.on(navTypeCombobox, "change", changeScriptQueryAppend);
 	
})();
