// branch test
EventHierarchyPane = function () {};

Object.extend(EventHierarchyPane.prototype, {
	eventhierarchydtree : null,
	eventsearchresultshierarchydtree : null,
	focus_pathway_id : null,
	treehighlitesurl : '/cgi-bin/entitylevelview/treehighlites',
	treehighlites1 : new Array(), //db_id of the current event instance (if it is an event)
	treehighlites2 : new Array(), //db_ids of the ancestors of the current event
	
	/*
	 *  Defines the shade of green tree nodes will be coloured. ancestors of selected node are different shade.
	 *  1cls for currently selected node, 2cls for ancestors
	 */
	treehighlites1cls : 'highlitedTreeNode1',
	treehighlites2cls : 'highlitedTreeNode2',
	focustreetrunkcls : 'focustreetrunkcls',
        searchResultsList : null,
	searchResultsIdList : null,
	searchresultstreehighlites1 : new Array(), //db_id of the current event instance (if it is an event)
	searchresultstreehighlites2 : new Array(), //db_ids of the ancestors of the current event

	
	treeTrunkLoadedEvent : new YAHOO.util.CustomEvent("TreeTrunkLoadedEvent", this),
	treeNodeMouseOverEvent : new YAHOO.util.CustomEvent("TreeNodeMouseOverEvent", this),
	treeNodeMouseOutEvent : new YAHOO.util.CustomEvent("TreeNodeMouseOutEvent", this),
	treeNodeClickEvent : new YAHOO.util.CustomEvent("TreeNodeClickEvent", this),
	searchResultsLoadedEvent : new YAHOO.util.CustomEvent("SearchResultsLoadedEvent", this),
	newSpeciesTreeLoadedEvent : new YAHOO.util.CustomEvent("NewSpeciesTreeLoadedEvent", this),
	
	/*
	 * Previous species pathway id is used when switching species. It is the id of the currently displayed pathway and is used
	 * to retrieve identifier of orthologous pathway in the new species.
	 */
	loadNodeData : function (node, fnLoadComplete, prevSpeciesPathwayId)  {
		var t = this;
		//prepare URL for XHR request:
		var sUrl = "/cgi-bin/entitylevelview/yuieventhierarchy?DB=" + this.db;
		if (this.focus_species_id) sUrl += "&FOCUS_SPECIES_ID=" + this.focus_species_id;
		if (node.data.dbid ) sUrl += "&ID=" + node.data.dbid;
		var ol;
		if (!node.data.dbid && $("hierarchytab").parentNode && $("hierarchytab").parentNode.parentNode) {
			ol = overlayElementWithTimeIndicator($("hierarchytab").parentNode.parentNode);
		}
		
		//prepare our callback object
		var callback = {
		
			//if our XHR call is successful, we want to make use
			//of the returned data and create child nodes.
			success: function(oResponse) {
				//log("oResponse.responseText = " + oResponse.responseText);
				var oResults = eval(oResponse.responseText);
				if((oResults) && (oResults.length)) {
					for (var i=0, j=oResults.length; i<j; i++) {
						var html = '<span class="nowrap">';
                        
                        html += '<span class="icon-' + oResults[i].cls + '">';
						if (oResults[i].status) {
							html += '<span class="neworupdated"> ' + oResults[i].status + ' </span> ';
						}
						html += '<a href="javascript:void(0)">' + oResults[i].name + '</a></span>';
						var tempNode = new YAHOO.widget.HTMLNode(
							{"html" : html, "dbid" : oResults[i].id, "name" : oResults[i].name,"hasdiagram" : oResults[i].hasdiagram }, node, false, true);
					//	tempNode.contentStyle = "icon-" + oResults[i].cls;
						if (! oResults[i].expands) tempNode.isLeaf = true;
					}
				}
				
				//When we're done creating child nodes, we execute the node's
				//loadComplete callback method which comes in via the argument
				//in the response object (we could also access it at node.loadComplete,
				//if necessary):
				oResponse.argument.fnLoadComplete();
				//Have to bind the listeners only after the nodes have been rendered
				$A(node.children).each(function(n){
					var el = $(n.getEl()).down('a');
					Event.observe(el, 'mouseover', t.fireTreeNodeMouseOverEvent.bindAsEventListener(t, n.data.dbid));
					Event.observe(el, 'mouseout', t.fireTreeNodeMouseOutEvent.bindAsEventListener(t));
					Event.observe(el, 'click', t.handleClickOnEventHierarchy.bindAsEventListener(t));
				});
				//Can highlite only after rendering
				t.highliteTreeNodeToBeHighlited();
				if (ol) ol.remove();
				log("t.treehighlites2 = " + t.treehighlites2);
				log("node.children = " + node.children);
				// Also have to have the following bit here as at the time Node.expand is called
				// the child nodes haven't been highlited yet.
				$A(node.children).each(function(n){
					if (t.treehighlites2.include(n.data.dbid)) {
						t.scrollToNode(n);
						n.expand();
					}
				});
				if(prevSpeciesPathwayId){
					t.newSpeciesTreeLoadedEvent.fire(prevSpeciesPathwayId);
				}
			},
			
			//if our XHR call is not successful, we want to
			//fire the TreeView callback and let the Tree
			//proceed with its business.
			failure: function(oResponse) {
				YAHOO.log("Failed to process XHR transaction.", "info", "example");
				oResponse.argument.fnLoadComplete();
				if (ol) ol.remove();
			},
			
			//our handlers for the XHR response will need the same
			//argument information we got to loadNodeData, so
			//we'll pass those along:
			argument: {
				"node": node,
				"fnLoadComplete": fnLoadComplete
			}
		};
		
		//With our callback object ready, it's now time to 
		//make our XHR call using Connection Manager's
		//asyncRequest method:
		YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
	},
	loadSearchResultsNodeData : function (node, fnLoadComplete, searchResultsHierarchy)  {
		var t = this;
		//prepare URL for XHR request:
		var sUrl = "/cgi-bin/entitylevelview/yuieventhierarchy?DB=" + this.db;
		if (this.focus_species_id) sUrl += "&FOCUS_SPECIES_ID=" + this.focus_species_id;
		if (node.data.dbid) sUrl += "&ID=" + node.data.dbid;
		var ol;
		if (!node.data && $("searchresultstab").parentNode && $("searchresultstab").parentNode.parentNode) {
			ol = overlayElementWithTimeIndicator($("searchresultstab").parentNode.parentNode);
		}
		
		//prepare our callback object
		var callback = {
		
			//if our XHR call is successful, we want to make use
			//of the returned data and create child nodes.
			success: function(oResponse) {
				//log("oResponse.responseText = " + oResponse.responseText);
				var oResults = eval(oResponse.responseText);
				
				if(searchResultsHierarchy){
				   t.searchResultsIdList = searchResultsHierarchy;
				}

				oResults = t.filterSearchResults(oResults, t.searchResultsIdList);
				if((oResults) && (oResults.length)) {
	for (var i=0, j=oResults.length; i<j; i++) {
						var html = '<span class="nowrap">';
                        
                        html += '<span class="icon-' + oResults[i].cls + '">';
						if (oResults[i].status) {
							html += '<span class="neworupdated"> ' + oResults[i].status + ' </span> ';
						}
						html += '<a href="javascript:void(0)">' + oResults[i].name + '</a></span>';
						var tempNode = new YAHOO.widget.HTMLNode(
							{"html" : html, "dbid" : oResults[i].id, "name" : oResults[i].name,
							"hasdiagram" : oResults[i].hasdiagram}, node, false, true);
					//	tempNode.contentStyle = "icon-" + oResults[i].cls;
						if (! oResults[i].expands) tempNode.isLeaf = true;
					}
				}
				
				//When we're done creating child nodes, we execute the node's
				//loadComplete callback method which comes in via the argument
				//in the response object (we could also access it at node.loadComplete,
				//if necessary):
				oResponse.argument.fnLoadComplete();
				var childNodes = new Array();
				var childNodesIndex=0;
				//Have to bind the listeners only after the nodes have been rendered
				$A(node.children).each(function(n){
					if(t.searchResultsIdList){
                                          for(var i=0; i<t.searchResultsIdList.length; i++){
						if(n.data.dbid == t.searchResultsIdList[i]){
							childNodes[childNodesIndex] = n;
							childNodesIndex++;
						}
					  }
					}
				});
				for(var i=0, childNodesLength = childNodes.length; i<childNodesLength; i++){
					var el = $(childNodes[i].getEl()).down('a');
					Event.observe(el, 'mouseover', t.fireTreeNodeMouseOverEvent.bindAsEventListener(t, childNodes[i].data.dbid));
					Event.observe(el, 'mouseout', t.fireTreeNodeMouseOutEvent.bindAsEventListener(t));
					Event.observe(el, 'click', t.handleClickOnSearchResultsHierarchy.bindAsEventListener(t));

				}
				//Can highlite only after rendering
//				t.highliteTreeNodeToBeHighlited();
				if (ol) ol.remove();
				log("t.treehighlites2 = " + t.treehighlites2);
				log("node.children = " + node.children);
				// Also have to have the following bit here as at the time Node.expand is called
				// the child nodes haven't been highlited yet.
				$A(node.children).each(function(n){
					if (t.treehighlites2.include(n.data.dbid)) {
						t.scrollToNode(n);
						n.expand();
					}
				});
			},
			
			//if our XHR call is not successful, we want to
			//fire the TreeView callback and let the Tree
			//proceed with its business.
			failure: function(oResponse) {
				YAHOO.log("Failed to process XHR transaction.", "info", "example");
				oResponse.argument.fnLoadComplete();
				if (ol) ol.remove();
			},
			
			//our handlers for the XHR response will need the same
			//argument information we got to loadNodeData, so
			//we'll pass those along:
			argument: {
				"node": node,
				"fnLoadComplete": fnLoadComplete
			}
		};
		
		//With our callback object ready, it's now time to 
		//make our XHR call using Connection Manager's
		//asyncRequest method:
		YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
	},
        // FIX: search results
        filterSearchResults: function(nodes, searchResultsHierarchy){
              var filteredArray = new Array();
              var filteredIndex=0;
	      for (var index = 0, len = nodes.length; index < len; ++index) {
		  
		  for (var resultsIndex = 0, resultsLen = searchResultsHierarchy.length; resultsIndex < resultsLen; resultsIndex++){
                     if(nodes[index].id == searchResultsHierarchy[resultsIndex]){
				filteredArray[filteredIndex] = nodes[index];
				filteredIndex++;
			}
		  }
	          
        }
	    return filteredArray;
	},

	/*
	 * Current id is used when switching species. It is the id of the currently displayed pathway and is used
	 * to retrieve identifier of orthologous pathway in the new species.
	 */
	buildEventHierarchy : function (currentId) {
		var t = this;
		YAHOO.util.Event.onDOMReady(function() {
		   	t.eventhierarchydtree = new YAHOO.widget.TreeView("hierarchytab");
		   	t.eventhierarchydtree.setDynamicLoad(t.loadNodeData.bind(t), 1);
	   		var root = t.eventhierarchydtree.getRoot();
	   		t.loadNodeData(root, t.completeLoadingTreeTrunk.bind(t), currentId);
	   		t.eventhierarchydtree.subscribe("expand",t.highliteTreeNodeToBeHighlited,t,true);
		})	
	},
        buildSearchResultsHierarchy : function (hierarchy) {
		var t = this;
		YAHOO.util.Event.onDOMReady(function() {
		   	t.eventsearchresultshierarchydtree = new YAHOO.widget.TreeView("searchresultstab");
		   	t.eventsearchresultshierarchydtree.setDynamicLoad(t.loadSearchResultsNodeData.bind(t), 1);
	   		var root = t.eventsearchresultshierarchydtree.getRoot();
	   		t.loadSearchResultsNodeData(root, t.completeLoadingSearchResultsTreeTrunk.bind(t), hierarchy);
	   		t.eventsearchresultshierarchydtree.subscribe("expand",t.highliteTreeNodeToBeHighlited,t,true);
		})	
	},

	highliteTreeNodeToBeHighlited : function () {
		this.highliteTreeNodesByEventDbIds(this.treehighlites1,this.treehighlites1cls);
		this.highliteTreeNodesByEventDbIds(this.treehighlites2,this.treehighlites2cls);
	},
	completeLoadingTreeTrunk : function () {
		this.eventhierarchydtree.draw();
		var treenode = this.eventhierarchydtree.getNodeByProperty('dbid',this.focus_pathway_id);
		if (treenode) {
			treenode.highlite(this.focustreetrunkcls);
			treenode.highlite(this.treehighlites1cls);
		}
		//this.tabView.set('activeTab',this.tabView.getTab(1),true);
		this.treeTrunkLoadedEvent.fire();
		this.scrollToFocusPathway();
		
		
	},
	completeLoadingSearchResultsTreeTrunk : function () {
		this.eventsearchresultshierarchydtree.draw();
		var treenode = this.eventsearchresultshierarchydtree.getNodeByProperty('dbid',this.focus_pathway_id);
		this.searchResultsLoadedEvent.fire();
		this.removeSearchResultsTreeNodeHilites();
	},

	scrollToFocusPathway : function () {
		//log("scrollToFocusPathway " + this.focus_pathway_id);
		var treenode = this.eventhierarchydtree.getNodeByProperty('dbid',this.focus_pathway_id);
		if ((treenode != null) && $("hierarchytab").parentNode) {
			this.scrollToNode(treenode);
		}
	},
	

	scrollToNode : function (treenode) {
		//log("scrollToNode " + treenode);
		var el = treenode.getEl();
		var y = YAHOO.util.Dom.getY(el) - YAHOO.util.Dom.getY("hierarchytab");
		y = el.offsetTop - (el.firstElementChild.offsetHeight*2.5);
		var anim = new YAHOO.util.Scroll($("hierarchytab"), {scroll: { to: [0, y] }});
		anim.animate();
	},
	

	handleClickOnEventHierarchy : function (event) {
        var el = Event.element(event);
		var node = this.eventhierarchydtree.getNodeByElement(el);
        this.handleNodeClick(node);
        var leftpanel = $("leftpanel");
	},
    handleNodeClick : function (node){
   		var topNode = this.getTopNodeForNode(node);
		this.removeTreeNodeHilites();
		node.highlite(this.treehighlites1cls);
		node.highliteAncestors(this.treehighlites2cls);
		this.treeNodeClickEvent.fire(topNode, node);
    },
    selectPathway : function (dbid){
        var rootnode = this.eventhierarchydtree.getNodeByProperty("dbid", dbid);
        if(rootnode == null) return "false";
        this.handleNodeClick(rootnode);
    },
	handleClickOnSearchResultsHierarchy : function (event) {
		var el = Event.element(event);
		var node = this.eventsearchresultshierarchydtree.getNodeByElement(el);
		var topNode = this.getTopNodeForNode(node);
		this.removeSearchResultsTreeNodeHilites();
		node.highlite(this.treehighlites1cls);
		node.highliteAncestors(this.treehighlites2cls);
		this.treeNodeClickEvent.fire(topNode, node);
	},

	initSpeciesList: function(){
		var t = this;
		var callback = {
				success: function(oResponse){
				if(oResponse.responseText.length == 0){
					return;
				}
				var data = eval("(" + oResponse.responseText +")");
				var speciesDropdown = $("specieslistdropdown");
				if(speciesDropdown){
					for(var speciesId in data){
						 var elOptNew = document.createElement('option');
						 elOptNew.text = data[speciesId];
						 elOptNew.value = speciesId;
						 if(speciesId == t.focus_species_id){
							elOptNew.selected="true";
						 }
					    try{
					    	speciesDropdown.add(elOptNew, null); // standards compliant; doesn't work in IE
					    }catch(err){
					    	speciesDropdown.add(elOptNew);
					    }
					}
				}
				
				
				},
				failure: function(oResponse){
									
				}
		};
		YAHOO.util.Connect
			.asyncRequest(
					'POST',
					"/ReactomeGWT/entrypoint/elv/ELVUtilsServlet",
					callback,
					'action=listspecies');

	},
	
	removeTreeNodeHilites : function () {
		this.treehighlites1.clear();
		this.treehighlites2.clear();
		$A($("hierarchytab").getElementsByClassName(this.treehighlites1cls)).invoke('removeClassName',this.treehighlites1cls);
		$A($("hierarchytab").getElementsByClassName(this.treehighlites2cls)).invoke('removeClassName',this.treehighlites2cls);
	},
	removeSearchResultsTreeNodeHilites : function () {
		this.searchresultstreehighlites1.clear();
		this.searchresultstreehighlites2.clear();
	
		$A($("searchresultstab").getElementsByClassName(this.treehighlites1cls)).invoke('removeClassName',this.treehighlites1cls);
		$A($("searchresultstab").getElementsByClassName(this.treehighlites2cls)).invoke('removeClassName',this.treehighlites2cls);
	},

	getTopNodeForNode : function (node) {
	     // added check for hasdiagram to accommodate subpathways that have diagrams
         if (node.parent && node.parent.parent && node.data.hasdiagram == false) {
	         return this.getTopNodeForNode(node.parent);
         } else {
		     return node;
         }
	},
	highliteNodeInEventHierarchy: function(diagramNode, activateHierarchyTab) {
		this.removeTreeNodeHilites();
		var treenode = this.eventhierarchydtree.getNodeByProperty('dbid',this.focus_pathway_id);
		if (treenode != null) {
			treenode.highlite(this.focustreetrunkcls);
			treenode.highlite(this.treehighlites2cls);
		}
		this.treehighlites1 = [diagramNode.userObject.id];
		treenode = this.eventhierarchydtree.getNodeByProperty('dbid',diagramNode.userObject.id);
		if (treenode != null) {
			treenode.highlite(this.treehighlites1cls);
			this.scrollToNode(treenode);
		}
		var sUrl = this.treehighlitesurl + '?DB=' + this.db + '&ID=' + diagramNode.id + '&FOCUS_SPECIES_ID=' + this.focus_species_id;
		var callback = {
			scope: this,
			success: function(oResponse) {
				var o = eval(oResponse.responseText );
				this.treehighlites2 = $A(o.highlites).without(this.treehighlites1);
				this.highliteTreeNodesByEventDbIds(this.treehighlites2,this.treehighlites2cls);
			}, 
			failure: function(oResponse) {
				//log(oResponse.statusText);
			}
		};
	
		YAHOO.util.Connect.asyncRequest('GET', sUrl, callback);
	},
	highliteTreeNodesByEventDbIds : function (dbids,hlcls) {
		for (var i = 0, len = dbids.length; i < len; ++i) {
			var treenodes = this.eventhierarchydtree.getNodesByProperty('dbid',dbids[i]);
			$A(treenodes).invoke('highlite',hlcls);
		}
	},
	fireTreeNodeMouseOverEvent : function (event, dbId) {
		this.treeNodeMouseOverEvent.fire(dbId);
	},
	fireTreeNodeMouseOutEvent : function () {
		this.treeNodeMouseOutEvent.fire();
	},
	fireTreeNodeClickEvent : function (e, dbId) {
		this.treeNodeClickEvent.fire(dbId);
	},
	toString: function() {
		return "EventHierarchyPane";
	}
});

/*
 * Extend YAHOO.widget.HTMLNode (used in the event hierarchy) so that it can highlite
 * itself and its ancestors.
 */
YAHOO.extend(YAHOO.widget.HTMLNode, YAHOO.widget.HTMLNode, {
	highlite : function (hlcls) {
		$(this.getEl()).down('a').addClassName(hlcls);
	},
	highliteAncestors : function (hlcls) {
		if (this.parent && this.parent.parent) {
			this.parent.highlite(hlcls);
			this.parent.highliteAncestors(hlcls);
		}
	}
});

