//////     Detail Panel
//
	function DetailPanel(divID) {   // detailsDiv  ... detailsLabel
	  var $ = x$;
		this.jContainer = x$("#" + divID);
		this.curXhr = null;
		this.labelCell = $("#detailsLabel");
		this.curType = "";
		this.maxTitleLen = 65;
		this.listObjs = [];   // the list objects by type

		this.cancelXhr = function() {
			if (this.curXhr &&  this.curXhr.readyState != 4) {
				this.curXhr.abort();
			}
				
			this.curXhr = null;
		};

    this.resize = function(wide, hi) {
    //  if (! wide) wide = 300;
    //  if (! hi) hi = $("#detailsParentDiv").height();
    //  var detailTitleHeight = $("#detailsTitle").outerHeight() +$("#dControls").outerHeight() +$("#detailLabelDiv").outerHeight() +30;
    //  var navHeight = $("#selectionNavControls").outerHeight() +5;
    //  $("#detailsParentDiv").height(hi);
    //  $("#detailDiv").height(hi -detailTitleHeight - navHeight);
    //  $("#detailsParent").width(wide);
    };

		// get a list of the buttons
		this.cntrls = $("#dControls > .button");

		// remove any existing events
		this.cntrls.un();

		// add click events
		this.cntrls.click(function() {
			if ($(this).hasClass('buttonDisabled')) return;

			var selObj, selTopic;
			var curSelection = selectionMgr.get();
			if(curSelection.obj) {
				selObj = curSelection.obj;
				selTopic = selObj.getTopic();
			} else {
				selObj = null;
				selTopic = null;
			}

			switch(this.id) {
				case "detailAdd":
					contextMgr.changeContext("add", selTopic, selObj, selObj.getGeneList());
          if (window.details) details.set();
					break;
				case "detailFocus":
					contextMgr.changeContext("focusOn", selTopic, selObj, selObj.getGeneList());
          if (window.details) details.set();
					break;
				case "detailInsight":
					if(insights && details) insights.add(selObj, details.curType, null);
					break;
			}
		});

		this.controls = {};

		this.controls.get = function(cName) {
			var cID;
			switch(cName) {
				case "focus":
					cID = "detailFocus";
					break;
				case "add":
					cID = "detailAdd";
					break;
				case "insight":
					cID = "detailInsight";
					break;
			}

			return $("#" + cID);
		};

		this.controls.enable = function(cName) {
			var control = this.get(cName);
			control.removeClass('buttonDisabled');
		};

		this.controls.disable = function(cName) {
			var control = this.get(cName);
			control.addClass('buttonDisabled');
		};

    // this.jContainer.mouseover(function(e) {
    //  bioTip.forceHide();
    // });

		this.setTitle = function(title, subTitle) {
			// remove "canonical" from pathway category
			var re = /canonical pathway/i;
			subTitle = subTitle.replace(re, "pathway");

			// make sure the text isn't too long
			if (title.length + subTitle.length > this.maxTitleLen) {
				var str = title.substring(0, this.maxTitleLen -subTitle.length) + "...";
				title = '<span title="' + title + '">' + str + '</span>';
			}

			// set the title fields in the panel
			$("#detailLabel2").html(title);
			$("#detailsLabel").html("<span class='medGray'> (" + subTitle + ")</span>");
		};

		this.set = function(type, obj) {
		  
			var selList = [];
			if (!type || !obj) {
				// refresh the panel
				type = this.curType;
				obj = this.curObj;
			} else {
				this.curType = type;
				this.curObj = obj;
			}
			
			// perform checks to determine what buttons should be enabled

			// check whether we have a molecule
			if (obj && typeof obj != "string") {
				// get the genes for the current selection
				selList = obj.getGeneList();
			}

			if (selList.length == 0) {
				// disable all the buttons
				this.controls.disable("focus");
				this.controls.disable("add");
				this.controls.enable("insight"); // enable for all selections - except CP nodes in CPs 
			} else {
				// enable all the buttons
				this.controls.enable("focus");
				this.controls.enable("add");
				this.controls.enable("insight");
			}
			// get the genes in the current context
			var contextList = contextMgr.getGeneList();

			// get the intersection of the genes in the context and selection
			var intersect = arrayIntersection(contextList, selList);

			if (intersect.length == selList.length) {
				if (contextList.length == selList.length) {
					// disable both filter buttons
					this.controls.disable("focus");
					this.controls.disable("add");
				} else if (contextList.length > selList.length) {
					// disable the Add button
					this.controls.disable("add");
				}
			}

			// fill 'er up.
			var objType = type.toLowerCase();
			this.hideAll();
			
      // var isWheelPage = (gSelType == pageHeaders["context"].topic.toLowerCase());
      // var isGeneTablePage = (gSelType == pageHeaders["gene table"].topic.toLowerCase());

      var isWheelPage = false;
      var isGeneTablePage = false;
      
			if(objType.indexOf("disease")>=0)  {
				
				if (gSelType == pageHeaders["diseases"].topic.toLowerCase() || isWheelPage || isGeneTablePage) {
					if(!obj.topicObj) {
						this.showDisease(obj); this.curType = "disease";
					} else {
						this.showCategory(obj); this.curType = "category";
					}
				} else {
					this.showAdHocGeneSet(obj, obj.genes);
					this.curType = "adhocGenes";
				}
				
			} else if(objType.indexOf("pathway")>=0)  {
				
				if (gSelType == pageHeaders["pathways"].topic.toLowerCase() || isWheelPage || isGeneTablePage) {
					if(!obj.topicObj) {
						this.showPathway(obj); this.curType = "pathway";
					} else {
						this.showCategory(obj); this.curType = "category";
					}
				} else {
					this.showAdHocGeneSet(obj, obj.genes);
					this.curType = "adhocGenes";
				}
				
			} else if(objType.indexOf("process")>=0)  {

				if (gSelType == pageHeaders["processes"].topic.toLowerCase() || isWheelPage || isGeneTablePage) {
					if(!obj.topicObj) {
						this.showProcess(obj); this.curType = "process";
					} else {
						this.showCategory(obj); this.curType = "category";
					}
				} else {
					this.showAdHocGeneSet(obj, obj.genes);
					this.curType = "adhocGenes";
				}
			} else if(objType.indexOf("category")>=0 || objType.indexOf("location")>=0 || objType.indexOf("profamily")>=0) {
				if (isWheelPage || isGeneTablePage) {
					this.showCategory(obj); 
					this.curType = "category";
				} else {
					this.showAdHocGeneSet(obj, obj.getGeneList());
					this.curType = "adhocGenes";
				}
			} else if(objType.indexOf("adhoc")>=0)     {
				this.showAdHocGeneSet(obj, obj.getGeneList());
				this.curType = "adhocGenes";
			}
			else if(objType.indexOf("gene")>=0)     {this.getMoleculeInfo(obj.id, obj, this.showMolecule); this.curType = "gene";}
			else if(objType.indexOf("interaction") >= 0){this.showCategory(obj); this.curType = "interaction";}
			// This molecule may or may not be part of the dataset. Also it may be a gene or chemical.
			// Currently this scenario occurs mainly in the pathways and findings. obj.id should be the molecule DID.
			else if(objType.indexOf("nondatasetconcept")>=0)  {this.getMoleculeInfo(obj.id, obj, this.showMolecule);this.curType = "nondatasetconcept";}
			else if(objType.indexOf("groupcomplex")>=0) {this.getMoleculeInfo(obj.parentId, obj, this.showMolecule);this.curType = "groupcomplex";}

			this.resize();
		};

		this.showAdHocGeneSet = function(obj, ahGenes) {
			var adhocSet = null;
			//check if the object is already in history.
			var hi = selectionMgr.history.getItem(obj.id);
			if (hi != null) {
				adhocSet = hi.adhocGeneSet;
			} else {
				adhocSet = new AdHocGeneSet(obj.name, ahGenes, obj);
				adhocSet.calculateCommonality();
			}
			
			var commons = adhocSet.commons;
			
			// g is a hierarchy object
			this.setTitle('Genes in "' + adhocSet.name + '"', adhocSet.getTopicLabel());
			this.listObjs["genes"] = new SortableDetailsList(adhocSet, "genes", "dAdhocGeneList", false);
			this.listObjs["adhocGenes"] = new SortableDetailsList(adhocSet, "adhocGenes", "dAdhocObjList", true);
			
			$("#adhocGenesDetail").css({display:"inline"});
		};
		
		this.showCategory = function(g) {
			// g is a hierarchy object
			this.setTitle(g.name.toTitleCase(), g.getTopicLabel() + " category");
			$("#categoryDetail").css({display:"inline"});
			this.listObjs["genes"] = new SortableDetailsList(g, "genes", "dcatGeneList", false);
			var childOs = removeArrayDups(g.getChildObjects());
			//console.log(g.getChildObjects())
			if(childOs.length > 0) {
				this.listObjs["category"] = new SortableDetailsList(childOs, g.getTopic(), "dcatCatList", true);
			} else {
				$("#dcatCatList").html("");
			}
		};

		// Pass gene if it exists in dataset, else pass null;
		this.getMoleculeInfo = function(molid, gene, displayFunction) {
      
      var options = {
        method: 'get',
        async: true,
        callback : function() { 
          var molInfoJson = JSON.parse(this.responseText);
          displayFunction(molid, molInfoJson, gene) }
      }
      // Because we are going cross-domain with no access to the policy, lets just proxy this
      x$(window).xhr('/bda/data/genes/moleculeview/' + molid, options);
		};

		this.showMolecule = function(molid, molInfo, geneInfo) {
			var mol = molInfo[molid];
			showBasicMoleculeInfo(mol);

			if (mol.isGroupOrComplex == "true") {
				updateNonDatasetConcept(geneInfo, molInfo[geneInfo.id]);
				showGroupOrComplex(molid, molInfo);
			} else {
				hideGroupComplexInfo();

				var gene = geneInfo;

				// mol is a geneInDataset object
				if (gene.topic != "nondatasetconcept") {
					addGeneInDatasetInfo(gene);
					unhideDetailedInfo();
				} else {
					updateNonDatasetConcept(gene, molInfo[geneInfo.id]);
					hideDetailedInfo();
				}
			}
			
			function updateNonDatasetConcept(ndc, ndcInfo) {
				ndc.name = ndcInfo.name == "" ? ndcInfo.symbol : ndcInfo.name;
				ndc.symbol = ndcInfo.symbol;
				ndc.desc = ndcInfo.desc;
				ndc.type = ndcInfo.type;
			}

			function showBasicMoleculeInfo(mol) {
				var label2 = x$("#detailLabel2");
				x$("#geneDetail").css({display:"inline"});
				details.setTitle(mol.symbol + ": " + mol.name, mol.type);
				x$("#gdFunction").html("Function<br><hr ><span class='gdCatVals'>" + mol.proFamily + "</span>");
				x$("#gdLocation").html("Location<br><hr ><span class='gdCatVals'>" + mol.location + "</span>");
				x$("#gdDesc").html(mol.summary);

				// call resize again because we've been called asynchronously
        details.resize();
			};

			function addGeneInDatasetInfo(gene) {
        // var txt="<img src='../images/chip.png' style='background-color:" + gene.getExpColor() + "'/> ";
				$("#gdExpression").html("Expression<br /><hr /><span class='gdCatVals'>" + Math.round(gene.foldChange*1000)/1000 + "</span>");
				if(pageType == "interactions") {
					var ncount = 0;
					// add lists for neighbors by relationship, function, location... does location make sense?
					details.listObjs["relations"] = new SortableDetailsList(gene, "int-relationships", "gdRelList", false);
				} else {
					$(".interactionRow").css({display:"none"});
				}
				details.listObjs["diseases"] = new SortableDetailsList(gene, "diseases", "gdDiseaseList", false);
				details.listObjs["processes"] = new SortableDetailsList(gene, "processes", "gdProcessList", false)
				details.listObjs["pathways"] = new SortableDetailsList(gene, "pathways", "gdPathwayList", false)
			};

			// rootMolId is the ID of the root of the group/complex.
			// This param is needed since some members may also be groups/complexes.
			function showGroupOrComplex(rootMolId, gcInfo) {
				hideDetailedInfo();
				// show the members of the Group/Complex here.
				details.listObjs["groupComplex"] = new SortableDetailsList(gcInfo, "groupComplex", "gdGroupComplexList", false);
				$("#gdGroupComplexList").css({display:"block"});
			};

			function hideGroupComplexInfo() {
				$("#gdGroupComplexList").css({display:"none"});
			}

			function unhideDetailedInfo() {
				$("#gdRelList").css({display:"block"});
				$("#gdFunList").css({display:"block"});
				$("#gdLocList").css({display:"block"});
				$("#gdDiseaseList").css({display:"block"});
				$("#gdProcessList").css({display:"block"});
				$("#gdPathwayList").css({display:"block"});

				//$("#gdExpression").css({display:"inline"});
				$("#gdCitation").css({display:"inline"});
			}

			function hideDetailedInfo() {
				$("#gdRelList")     .css({display:"none"});
				$("#gdFunList")     .css({display:"none"});
				$("#gdLocList")     .css({display:"none"});
				$("#gdDiseaseList") .css({display:"none"});
				$("#gdProcessList") .css({display:"none"});
				$("#gdPathwayList") .css({display:"none"});
				$("#gdExpression")  .css({display:"none"});
				$("#gdCitation")    .css({display:"none"});
				$("#interactionRow").css({display:"none"});
			}
		};
    // END of showMolecule Render Method

		this.showDisease = function(d) {
			this.setTitle(d.name, "disease");
			var txt="<img src='../images/rank" + quartile(d.pValue,diseases.rankRange) + ".png'> ";
			$("#ddRank").html("pValue<br><hr width='80%'><span class='gdCatVals'>" + txt + Math.toScientific(d.pValue) + "</span>");
			this.listObjs["genes"] = new SortableDetailsList(d, "genes", "ddGeneList", false);
			if(d.topicObj) {
				d.topicObj.updateDescription();
			} else {
				d.updateDescription();
			}
			$("#diseaseDetail").css({display:"inline"});
		};

		this.showProcess = function(d) {
		  

			this.setTitle(d.name, "biological process");
			var txt="<span class='rank" + quartile(d.pValue,bioProcesses.rankRange) + "'>" + quartile(d.pValue,bioProcesses.rankRange) + "</span> ";
			x$("#dbpRank").html("pValue<br /><hr width='80%' /><span class='gdCatVals'>" + txt + Math.toScientific(d.pValue) + "</span>");
			this.listObjs["genes"] = new SortableDetailsList(d, "genes", "dbpGeneList", false);

      if(d.topicObj) {
       d.topicObj.updateDescription();
      } else {
       d.updateDescription();
      }
      $("#dbpDesc").html(d.desc);
			x$("#processDetail").css({display:"inline"});
		};

		this.showPathway = function(d) {
			this.setTitle(d.name, "pathway");
			$("#dpRank").html("pValue<br><hr width='80%'><span class='gdCatVals'>" + Math.toScientific(d.pValue) + "</span>");
			this.listObjs["genes"] = new SortableDetailsList(d, "genes", "dpGeneList", false);
      if(d.topicObj) {
       d.topicObj.updateDetails();
      } else {
       d.updateDetails();
      }
			$("#pathwayDetail").css({display:"inline"});
		};

    // TODO RE - XHR Error Handle - Not being used.
		this.errorHandler = function() {
			// cannot use "this" since the error handling is being invoked after a XHR request.
			details.controls.disable("focus");
			details.controls.disable("add");
			details.controls.disable("insight");
			details.hideAll();
		};
		
		this.hideAll = function() {
			x$("#detailsLabel").html('');
			x$("#detailLabel2").html('');
			x$("#diseaseDetail").css({display:"none"});
			x$("#geneDetail").css({display:"none"});
			x$("#pathwayDetail").css({display:"none"});
			x$("#processDetail").css({display:"none"});
			x$("#interactionDetail").css({display:"none"});
			x$("#biomarkerDetail").css({display:"none"});
			x$("#categoryDetail").css({display:"none"});
			x$("#adhocGenesDetail").css({display:"none"});
		};

	}

	function setSortableHandlers(topic, type, listObj) {
    var pageType = gSelType;
		var selector = listObj.selector;
		x$("#" + selector + " .inContext,#" + selector + " .notInContext,#" + selector + " .notInDatasetGene").click(function(e) {  // click
			if(type == "relations") {
				var gl = x$(this).attr("indices")[0].split(",");
				var geneObj = genes.byIndex(gl[gl.length - 1]); // relies on the last index being the index of the gene for which this group was created.
				var groupId = x$(this).attr("groupid")[0];
				var groupName = x$(this).attr("groupname")[0];

				// add this to the top level to avoid IE garbage collection issues when we switch chapters
				adHoc.geneIndices = x$(this).attr("indices")[0];
				adHoc.groupName = groupName;
				adHoc.geneObj = geneObj;
				adHoc.groupId = groupId;
				adHoc.createGeneSet();

			} else {
				if(type == "groupComplex") {
					selectionMgr.set(genes.list[$(this).attr("index")]);
				} else {
					if (pageType.match(new RegExp(type)) || type == "adhocGenes" ||
							(pageType == "interactions" && type == "genes") ||
							(pageType == "gene table" && type == "genes")) {
						// change the selection in the rank table

						// TODO RE - This just scrolls the grid and selects it.
						
            // var grid = Ext.getCmp('gridRankTable');
            // var searchIdx = $(this).attr("index");
            // var idx = grid.store.find('idx',searchIdx, 0, false, false, true);
            //  if (grid) grid.selectNScroll(idx);
            
            selectionMgr.set(topic.list[x$(this).attr("index")]);
					} else {
						selectionMgr.set(topic.list[x$(this).attr("index")]);
					}
				}		
				
        // if (pageType == "pathways" && type == "genes") {
        //  pathwayPanel.selectNodes([$(this).attr("index")]);
        // }
			}
		})
		/*
		.hover(function(e) { // over
			if(type == "relations") {
				gl = $(this).attr("indices").split(",");
			} else {
				var gl = topic.list[$(this).attr("index")].getGenesInContext();
			}
			if(pageType == "context") {
				wheel.center.hiliteList(gl);
				var hnodes = [];
				var ctop = topic.list[$(this).attr("index")];				
				otopic= ctop.getTopic(); 
				if(otopic != "nondatasetconcept" && otopic != "groupComplex" && otopic.indexOf("gene")<0)  {
				for (var m=0; m<ctop.hierarchyNodes.length; m++) {
					hnodes.push(ctop.hierarchyNodes[m].getRimObject());
				}
				wheel.rim.showHoverWedges(hnodes);
			}
			}
			if(isMatrixPage)      geneMatrix.hiliteList(gl);
			if (pageType == "pathways") {
				pathwayPanel.highlightNodes(gl);
			};
		}, function(e) {      // out
			//$(this).css("cursor", "normal").css("text-decoration","none");
			if(isMatrixPage)          geneMatrix.dehiliteList();
			if (pageType == "pathways") {
				pathwayPanel.highlightNodes();
			};
			if(pageType == "context") {
				wheel.center.dehiliteList();
				wheel.rim.hideHoverWedges();
			}
		});
		*/
		
		/*
		// TODO - RE Do we need this?!?
		if(type != "relations" && type != "adhocGenes") {  // interactions aren't sortable
			// the sort button rounding and events ....
			var btn = x$("#"+ listObj.selector + " .dtlSortBtn");
			if(x$("#"+selector).find("span").length == 0) btn.hide();
			var btnImg = x$(btn).find("img");
			if(listObj.sortType == "alpha") {
				if(listObj.type.indexOf("gene")>=0) {
					btnImg.attr("src", "../images/sortColor.png");
				} else {
					btnImg.attr("src", "../images/rankSml3.png");
				}
			} else {
				btnImg.attr("src", "../images/sortAbc.png");
			}
			var dtype = (listObj.isCategory)? "category": listObj.type;		
			btn.data("type", dtype);
			btn.click(function() {
				var dt = $(this).data("type");
				details.listObjs[dt].sort();
			});
		}
		*/
	}
	
	function SortableDetailsList(o, type, selector, isCategory) {
		this.o = o;
		this.type =  type;
		this.isCategory = isCategory;
		this.selector = selector;
		this.tableObj = x$("#" + selector);
		this.sortType = (type.indexOf("gene")>=0)? "alpha": "rank";
		if(this.type.indexOf("gene")>=0) {
			this.sortType = detailsViewOptions.genes;
		} else {
			this.sortType = detailsViewOptions.topics;  
		}
		
		this.sort = function() {
			if(this.sortType == "alpha") {
				this.sortType = "rank";
				//this.tableObj.find(".dtlSortBtn").text("Rank Sort");
				if(this.type.indexOf("gene")>=0) {
					detailsViewOptions.genes = "rank";
				} else {
					detailsViewOptions.topics = "rank";  // subsequent ones will be rank sorted
				}
			} else {
				this.sortType = "alpha";
				//this.tableObj.find(".dtlSortBtn").text("Alpha Sort");
				if(this.type.indexOf("gene")>=0) {
					detailsViewOptions.genes = "alpha";
				} else {
					detailsViewOptions.topics = "alpha";  // subsequent ones will be rank sorted
				}
			}
			this.create();
		}
		
		this.create = function() {
		  
			var ol = [];
			var txt = "<table cellspacing='0' cellpadding='0' border='0'>";
			txt+= "<tr><td class='detailChildrenTitle'>";
		//
		// Diseases 
		//
			if(this.type.indexOf("disea")>=0) {
				if(this.isCategory) {
					txt+= "Disease Categories (";
					for (var i=0; i<this.o.length; i++) {
						ol.push(this.o[i].topicObj);
						}
				} else {
					txt+= "Diseases (";
					for (var i=0; i<this.o.diseases.length; i++) {
						ol.push(diseases.list[this.o.diseases[i]]);
						}
					}
				txt+=  ol.length + ")";

				txt+="</td><td align='right'><div class='dtlSortBtn' style='display:none;'>Sort</div></td></tr>";
				txt+= "<tr><td colspan='2' class='detailChildrenList'>";
				if(this.sortType == "alpha") {
					ol.sort(function(a,b) { return (a.name.toLowerCase() > b.name.toLowerCase())? 1: -1;});
				} else {
					ol.sort(function(a,b) { return a.pValue - b.pValue;});
				};
					for (var i=0;i<ol.length; i++) {
						inc = (ol[i].inContext)? "inContext" : "notInContext";
					txt += "<span class='" + inc + "' index='" + ol[i].getIndex();
					txt+=  "' rank='" + (ol.length-i) + "' >";
					txt+= "<span class='" + ol[i].getRankQuartile() + "'></span>";
					txt+= ol[i].name + ",</span>";
					}
				txt = removeLastInstanceOfPattern(txt, ",");
				txt+= "</td></tr></table>";
				x$("#" + this.selector).html(txt);
				// use timer to allow single threaded javascript to update the dom before jquery does the selection search
				// otherwise its a race condition
        // if(this.isCategory) {
        //  window.setTimeout(function() {setSortableHandlers(diseases, "diseases", details.listObjs["category"]);}, 0);
        // } else {
        //  window.setTimeout(function() {setSortableHandlers(diseases, "diseases", details.listObjs["diseases"]);}, 0);
        // }
			}
			
		//
		// Pathways 
		//
			if(this.type.indexOf("pathw")>=0) {
			  
        if(this.isCategory) {
          for (var i=0; i<this.o.length; i++) {
            ol.push(this.o[i].topicObj);
          }
          txt+= "Pathway Categories (";
        } else {  // o is a gene
          for (var i=0; i<this.o.pathways.length; i++) {
						ol.push(pathways.list[this.o.pathways[i]]);
					}
          txt+= "Pathways ("
				}
				
				txt+=  ol.length + ")";
			

				txt+="</td><td align='right'><div class='dtlSortBtn' style='display:none;'> Sort</div></td></tr>";
				txt+= "<tr><td colspan='2' class='detailChildrenList'>";
				if(this.sortType == "alpha") {
					ol.sort(function(a,b) { return (a.name.toLowerCase() > b.name.toLowerCase())? 1: -1;});
				} else {
					ol.sort(function(a,b) { return a.pValue - b.pValue;});
				};
					for (var i=0;i<ol.length; i++) {
						inc = (ol[i].inContext)? "inContext" : "notInContext";
					txt += "<span class='" + inc + "' index='" + ol[i].getIndex();
					txt+=  "' rank='" + (ol.length-i) + "' >";
					txt+= "<span class='rankSml" + ol[i].getRankQuartile() + "'></span>";
					txt+= ol[i].name + ",</span>";
					}
				txt = removeLastInstanceOfPattern(txt, ",");
				txt+= "</td></tr></table>";
				x$("#" + this.selector).html(txt);
        // if(this.isCategory) {
        //  window.setTimeout(function() {setSortableHandlers(pathways, "pathways", details.listObjs["category"]);}, 0);
        // } else {
        //  window.setTimeout(function() {setSortableHandlers(pathways, "pathways", details.listObjs["pathways"]);}, 0);
        // }
			}
		//
		// Processes 
		//
			if(this.type.indexOf("process")>=0) {
				if(this.isCategory) {
					ol = [];
					for (var i=0; i<this.o.length; i++) {
						ol.push(this.o[i].topicObj);
					}
					txt+= "Process Categories (";
				} else {  // o is a gene
					ol = [];
					for (var i=0; i<this.o.bioProcesses.length; i++) {
						ol.push(bioProcesses.list[this.o.bioProcesses[i]]);
					}
					txt+= "Processes (";
				}
				txt+=  ol.length + ")";

				txt+="</td><td align='right'><div class='dtlSortBtn' style='display:none;'>Sort</div></td></tr>";
				txt+= "<tr><td colspan='2' class='detailChildrenList'>";
				if(this.sortType == "alpha") {
					ol.sort(function(a,b) { return (a.name.toLowerCase() > b.name.toLowerCase())? 1: -1;});
				} else {
				ol.sort(function(a,b) { return a.pValue - b.pValue;});
				};
				for (var i=0;i<ol.length; i++) {
					inc = (ol[i].inContext)? "inContext" : "notInContext";
					txt += "<span class='" + inc + "' index='" + ol[i].getIndex();
					txt+=  "' rank='" + (ol.length-i) + "'>";
					txt+= "<span class='rankSml" + ol[i].getRankQuartile() + "'></span> ";
					txt+= ol[i].name + ",</span>";
				}
				txt = removeLastInstanceOfPattern(txt, ",");
				txt+= "</td></tr></table>";
				x$("#" + this.selector).html(txt);				
        // if(this.isCategory) {
        //  window.setTimeout(function() {setSortableHandlers(bioProcesses, "processes", details.listObjs["category"]);}, 0);
        // } else {
        //  window.setTimeout(function() {setSortableHandlers(bioProcesses, "processes", details.listObjs["processes"]);}, 0);
        //  }
				}
		//
		// Genes 
		//
			if(this.type.indexOf("gene")>=0) {
				
					ol = this.o.getGeneList();  // ol is an array of indices 
					txt+= "Genes (" + ol.length + ")";

					txt+="</td><td align='right'><div class='dtlSortBtn' style='display:none;'>Sort</div></td></tr>";
					txt+= "<tr><td colspan='2' class='detailChildrenList'>";
					if(this.sortType == "alpha") {
						ol.sort(function(a,b) {  
							var as = genes.list[a].symbol + "";  // make sure its a string
							var bs = genes.list[b].symbol + "";
							return (as.toUpperCase() > bs.toUpperCase())? 1: -1;});
					} else {
						ol.sort(function(a,b) { return genes.list[b].foldChange - genes.list[a].foldChange;});  
					};
					for (var i=0;i<ol.length; i++) {
						var inc = (genes.list[ol[i]].inContext)? "inContext" : "notInContext";
						txt += "<span class='" + inc + "' index='" + ol[i];
						txt+=  "' rank='" + genes.list[ol[i]].foldChange + "' title='click to select'>";
						txt+= "<a href='#' style='background-color:" + genes.list[ol[i]].getExpColor() + "'>" + genes.list[ol[i]].symbol+ "</a>,</span>";
					}
					txt = removeLastInstanceOfPattern(txt, ",");
					txt+= "</td></tr></table>";
					x$("#" + this.selector).html(txt);
					
          // window.setTimeout(function() {setSortableHandlers(genes, "genes", details.listObjs["genes"]);}, 0); 
        }
		//
		// GroupComplex 
		//	
			
			if(this.type.indexOf("group")>=0) {
				// makeDetailsList(gcInfo, "groupComplex", "gdGroupComplex");
				var gcInfo = this.o;
				var gl = new Array();
				var nonDatasetGenes = new Object();
				for (var i in gcInfo) {
					var mol = gcInfo[i];
					var g = genes.byId(mol.id);
					if (g != null) {
						gl.push(g);
					} else {
						// Skip adding the root molecule. The dataset should not contain any group/complex.
						if (mol.isRoot == undefined || mol.isRoot == "false") {
							nonDatasetGenes[mol.id] = mol;
						}
					}

				}
				txt+= "Group/Complex Molecule (" + gl.length + ")";

				txt+="</td><td></td></tr>";
				txt+= "<tr><td colspan='2' class='detailChildrenList'>";
				gl.sort(function(a,b) {  
					var sa = a.symbol + "";
					var sb = b.symbol + "";
					return (sa.toLowerCase() > sb.toLowerCase())? 1: -1;});

				for (var i=0;i<gl.length; i++) {
					var inc = (gl[i].inContext)? "inContext" : "notInContext";
					txt += "<span class='" + inc + "' index='" + genes.indexById(gl[i].id) + "' title='click to select'>";
					txt+= "<a href='#' style='background-color:" + gl[i].getExpColor() +  "'>" + gl[i].symbol+ "</a>,</span>";
				}

				for (var i in nonDatasetGenes) {
					var mol = nonDatasetGenes[i];
					txt += "<span class='nonDatasetGene' index='" + mol.id + "'>" + mol.symbol + ":" + mol.name + ", </span>";
				}
				$("#" + selector).html(txt);
        // window.setTimeout(function() {setSortableHandlers(genes, "groupComplex", details.listObjs["groupComplex"]);}, 0);
      }
		//
		// interaction Groups on wheel rim 
		//
			if(this.type.indexOf("interaction")>=0){
				if(this.isCategory) {  // has to be a category, correct??  Then why test??
					ol = [];
					for (var i=0; i<this.o.length; i++) {
						ol.push(this.o[i].topicObj);
					}
				} 
				txt+=  "Molecular Interactions (" + ol.length + ")";
				txt+="</td><td></td></tr>";
				txt+= "<tr><td colspan='2' class='detailChildrenList'>";
				ol.sort(function(a,b) { return (a.name.toLowerCase() > b.name.toLowerCase())? 1: -1;});
				
				for (var i=0;i<ol.length; i++) {
					inc = "inContext";
					txt += "<span class='" + inc + "' index='" + ol[i].getIndex() + "' title='click to select'> <a href='javascript:void(0)'>";
					txt+= ol[i].name + "</a>";
					if (i < ol.length -1) txt+= ",";
					txt+= "</span>";
				}
				txt = removeLastInstanceOfPattern(txt, ",");
				txt+= "</td></tr></table>";
				$("#" + this.selector).html(txt);				

        // if(this.isCategory) {
        //  window.setTimeout(function() {setSortableHandlers(interactionTypeGroups, "interaction", details.listObjs["category"]);}, 0);
        // } else {
        //  window.setTimeout(function() {setSortableHandlers(interactionTypeGroups, "interaction", details.listObjs["interaction"]);}, 0);
        // }
			}
		//
		// interaction relationships 
		//	
			if(this.type.indexOf("int-rel")>=0) {
			  // RE Not needed in iPad
        // // get neighbor list
        // rels = this.o.getInteractionsInContext();
        // // build relationship groups
        // 
        // var rgrps = [];
        // 
        // var neighborMap = this.o.getNeighborMap();
        // for(var key in neighborMap){
        //  var neighbor = neighborMap[key];
        //  if(!rgrps[neighbor.type]) rgrps[neighbor.type] = [];
        //  rgrps[neighbor.type].push(neighbor.index);
        // }
        // 
        // var ii =0;
        // var tmp = [];
        // for (i in rgrps) {
        //  tmp[ii] = i;
        //  ii++;
        // }
        // tmp.sort(function(a,b) {
        //  return (a.toLowerCase()>b.toLowerCase())? 1:-1;
        // });
        // // sort these alphabetically
        // txt+= "Neighbor Relation Types (" + ii + ")</td><td></td></tr>";
        // txt+= "<tr><td colspan='2' class='detailChildrenList'>";
        // for (j=0; j<tmp.length; j++) {
        //  var nm = tmp[j];
        //  for (i in rgrps) {
        //    if(i == nm) {
        //      txt+= "<span class='inContext' groupid='" + "nrelt-" + i.toTitleCase() + "-" + this.o.getIndex() + "'"
        //      + " groupname='" + i.toTitleCase() + " Interactions of " + this.o.symbol + "'"
        //      + " indices='" + rgrps[i].join(",") + "," + this.o.getIndex() + "'"
        //      + " title='click to select'> <a href='javascript:void(0)'>" + i.toTitleCase() + "(" + rgrps[i].length + ")</a>,</span>";
        //    }
        //  }
        // }
        // txt = removeLastInstanceOfPattern(txt, ",");
        // txt+= "</td></tr></table>";
        // x$("#" + this.selector).html(txt);
        // window.setTimeout(function() {setSortableHandlers(genes, "relations", details.listObjs["relations"]);}, 0); 
			}
			
			//Adhoc Geneset
			if(this.type.indexOf("adhocGenes")>=0) {
				ol = [];
				var allObjs = genes;
				var max = 10;
				var listType = "Top ";
				var count = 0;
				switch(pageType) {
					case "diseases":
						listType += "Diseases";
						allObjs = diseases;
						count = Math.min(max, o.commons.sortedDiseases.length);
						for (var i = 0;  i < count; i++) {
							ol.push(o.commons.sortedDiseases[i]);
						}
						break;
					case "processes":
						listType += "Processes";
						allObjs = bioProcesses;
						count = Math.min(max, o.commons.sortedBioProcesses.length);
						for (var i = 0;  i < count; i++) {
							ol.push(o.commons.sortedBioProcesses[i]);
						}
						break;
					case "interactions":
						listType += "Genes by Neighbor Count";
						allObjs = genes;
						count = Math.min(max, o.commons.sortedInteractions.length);
						for (var i = 0;  i < count; i++) {
							ol.push(o.commons.sortedInteractions[i]);
						}
						break;
					case "pathways":
						listType += "Pathways";
						allObjs = pathways;
						count = Math.min(max, o.commons.sortedPathways.length);
						for (var i = 0;  i < count; i++) {
							ol.push(o.commons.sortedPathways[i]);
						}
						break;
					default: 
						// to be changed
						listType += "Diseases";
						allObjs = diseases;
						count = Math.min(max, o.commons.sortedDiseases.length);
						for (var i = 0;  i < count; i++) {
							ol.push(o.commons.sortedDiseases[i]);
						}
						// What to show in gene table?
				}
				
					txt+= "<div class='commonalityHeader'>" + listType + " (" + ol.length + ") common to these genes" + "</div>";
					txt+= "</td></tr>";

				txt+= "<tr><td class='detailChildrenList'>";
				var isGenesList = (listType.indexOf("Genes by Neighbor Count") >= 0);
				for (var i=0;i<ol.length; i++) {
					inc = (ol[i].obj.inContext)? "inContext" : "notInContext";
					if (isGenesList) {
						txt += "<span class='" + inc + "' index='" + ol[i].obj.getIndex() + "' title='click to select'>";
						txt+= "" + ol[i].obj.symbol 
						+ "[" + ol[i].percentage + "%]"
						+ ",</span> ";						
					} else {
						txt+= "<span class='" + inc + "' index='" + ol[i].obj.getIndex();
						txt+=  "' rank='" + (ol.length-i) + "' >";
						txt+= "" + ol[i].obj.name 
						+ "[" + ol[i].percentage + "%]"
						+ ",</span> ";
					}
				}
				txt = removeLastInstanceOfPattern(txt, ",");
				txt+= "</td></tr></table>";				
				x$("#" + this.selector).html(txt);				

        // window.setTimeout(function() {setSortableHandlers(allObjs, "adhocGenes", details.listObjs["adhocGenes"]);}, 0);
			}
		};
		
		this.create();
	}
	

  	function EvidencePanel(divId) {
  		this.jContainer = x$("#" + divId);
  		this.curType = "";
  		this.defaultFilter = 'allEvidence';
  		this.curTypeFilter = this.defaultFilter;
  		this.callbacks = new Object();
  		this.min = true;	// default of small size
  		this.expandBtnLoc = "../js/third_party/extJS4/resources/themes/images/gray/grid/group-expand.gif"; //"../images/buticonplus.gif";
  		this.collapseBtnLoc = "../js/third_party/extJS4/resources/themes/images/gray/grid/group-collapse.gif"; //"../images/buticonminus.gif";

  		this.curXhr = null;

      // this.jContainer.mouseover(function(e) {
      //  bioTip.forceHide();
      // });

  		this.cancelXhr = function() {
  			if (this.curXhr &&  this.curXhr.readyState != 4) {
  				this.curXhr.abort();
  			}

  			this.curXhr = null;
  		};

  		this.hideAll = function() {
  		  x$("#referencesLabel").html("Publications and Findings (0)");
  		  x$("#evidenceList").css({display : "none"});
  			if (pageType && pageType == "diseases") {
  				x$("#BiomarkerEvidence").html('Biomarker');
  				x$("#DrugEvidence").html('Drug');
  				x$("#ExpressionEvidence").html('Expression');
  				x$("#MutationEvidence").html('Mutation');
  				x$("#UnclassifiedEvidence").html('Unclassified');
  			}
  		};

  		this.clear = function() {   // used when the context is changed
  			this.jContainer.empty();
  			this.curTypeFilter = this.defaultFilter;
  		};

      // RE Should not be needed.
  		this.size = function(wide, hi) {
  			tabHi = 0;
  			if (pageType && pageType == "diseases") tabHi = 20;
  			$("#refParent").height(hi); // leaving this at the default height
  			$("#referencesDiv").height(hi);
  			var refTitleHeight = $("#referencesLabel").height();
  			$("#evidencePanelDiv").height(hi -refTitleHeight -tabHi); // latter for tabs which aren't displayed when sized;
  		};

  		this.addCallback = function(eventName, cbFunction) {
  			var callbacks = evidencePanel.callbacks;
  			if (callbacks[eventName] == null || callbacks[eventName] == undefined) {
  				callbacks[eventName] = new Array();
  			}

  			callbacks[eventName].push(cbFunction);
  		};

  		this.removeCallbacks = function(eventName) {
  			var callbacks = evidencePanel.callbacks;
  			if (callbacks[eventName] != null) {
  				callbacks[eventName] = null;
  			}
  		};

  		this.set = function(type, paramsObj, evidence, evContext) {
  			var pageType = gSelType;  		  
  			
  			this.hideAll();
  			this.curTypeFilter = this.defaultFilter;

  			var pt = type.toLowerCase();
  			if (pageType.indexOf(evContext) >= 0) {
          x$("#evidenceList").html('<span>  Loading...</span>').css({display: "inline"});
  			if(pt.indexOf("disease")>=0)  {
            // this.showProcessEvidence(evidence, paramsObj, this.displayEvidence, evContext); 
  					this.curType = "disease";
  			} else if(pt.indexOf("pathwayNode")>=0)  {
            // this.showPathwayEvidence(evidence, paramsObj, this.displayEvidence, evContext); 
  					this.curType = "pathwayNode";
  			} else if(pt.indexOf("pathway")>=0)  {
            // this.showPathwayEvidence(evidence, paramsObj, this.displayEvidence, evContext); 
  					this.curType = "pathway";
  			} else if(pt.indexOf("findings")>=0)  {
          // this.showEvidenceForFindingIds(evidence, paramsObj, this.displayEvidence, evContext); 
  				this.curType = "findings";
  			} else if(pt.indexOf("process")>=0)  {
          // RE - Hide this for now
          // this.showProcessEvidence(evidence, paramsObj, this.displayEvidence, evContext); 
  				this.curType = "process";
  			}
  			else if(pt.indexOf("gene")>=0) {
  				if (evContext != undefined) {
  					if(evContext.indexOf("process") >= 0 || evContext.indexOf("disease")>=0)  {
  						var lic = new Array();
  						if(evContext.indexOf("process")>=0) {
  							var licIndex = bioProcesses.listInContext();

  							for (var i in licIndex) {
  								lic.push(bioProcesses.byIndex(licIndex[i]));
  							}
  							
  						} else {
  							var licIndex  = diseases.listInContext();
  							for (var i in licIndex) {
  								lic.push(diseases.byIndex(licIndex[i]));
  							}
  						}

              
  						var pids = '';
  						for (var i in lic) {
  						  // RE - House keeping
  						  if (lic[i] != undefined)
  							  pids += lic[i].id + ',';
  						}

  						if (pids.length > 0) {
  							pids = pids.substring(0, pids.length - 1);
  						}

  						var gid = paramsObj.id;
              this.showGeneEvidenceInContext(evidence, gid, pids, this.displayEvidence, evContext);

  						this.curType = "gene";
  					} else if (evContext.indexOf("interactions")>=0) {
  						var finids = '';
  						var pArray = [];
  						var tmp = [];
  						var compArray = [];
  						var p, xaction, i;

  						// check whether we have an array - allows us to handle multiple objects
  						if (paramsObj.constructor != Array) {
  							pArray.push(paramsObj);
  						} else {
  							pArray = paramsObj;
  						}

  						var pLen = pArray.length;

  						// get the finding ids for all of the objects
  						for (p=0; p < pLen; p++) {
  							tmp =  pArray[p].getInteractionsInContext();
  							compArray[p] = [];

  							// store the ids for each object
  							for (i in tmp){
  								compArray[p].push(tmp[i].findingId);
  							}
  						}

  						if (compArray.length == 1) {
  							xaction = compArray[0];
  						} else if (compArray.length > 1) {
  							xaction = arrayIntersection(compArray);
  						}

  						// turn the result into a comma separated string
  						if (xaction) finids = xaction.join();

  						if (finids.length > 0) {
                // this.showEvidenceForFindingIds(evidence, finids, this.displayEvidence, evContext);
  						} else {
  							x$("#evidenceList").html('<span style="font-weight: bold">No related evidence found.</span>').css("display", "inline");
  						}

  						this.curType = "gene";
  					} else if (evContext.indexOf("pathway")>=0 && curPwyGCInfo) {
  						var gcParents = curPwyGCInfo["nodeId2gcIdMap"][paramsObj.id];
  						var po = {id:pathwayPanel.getPathway().id, nodeids:[paramsObj.id]};
  						if (gcParents != null) {
  							for (var j in gcParents) {
  								po.nodeids.push(gcParents[j]);
  							}
  						}
              // this.showPathwayEvidence(evidence, po, this.displayEvidence, evContext); 
  						this.curType = "gene";
  					} else if (evContext.indexOf("gene table") >= 0) {
              // this.showGeneEvidenceInReport(evidence, paramsObj.id, this.displayReferences, evContext);
  					} else {
              // x$("#evidenceList").html('<span style="font-weight: bold">No related evidence found.</span>').css({display: "inline"});
            }
  				}

  			};
  			}
  		};

  		this.showEvidenceForFindingIds = function(evidence, paramsObj, handleResponse, evContext) {
  			this.cancelXhr();

  			var sids = paramsObj.split(",ING:").join(",").replace("ING:","");
  			this.curXhr = $.ajax({  // Using POST here since there could be a lot of Finding IDs to pass to the server.
  				  type: 'POST',
  				  url: '/bda/data/evidence/finding/ids',
  				  data:  {ids: sids},
  				  dataType: 'json',
  				  success: function(json) {
  						populateEvidence(json, evidence, evContext);
  						resetOptions();
  						handleResponse(evidence);
  				  },
  				  error: function(jqXHR, textStatus, errorThrown) {
  					  evidencePanel.hideAll();
  				  },
  				  complete: function() {
  						if (evidencePanel) {
  							evidencePanel.curXhr = null;
  						} 
  					}
  			});
  		};

  		this.showProcessEvidence = function(evidence, processObj, handleResponse, evContext) {
  			this.cancelXhr();

  			var processId = processObj.id;
  			var processMemberIds = '';
  			//var genelist = parent.comm.genes;
  			var glIndices = processObj.getGeneList();
  			for (var i in glIndices) {
  				var gene =  genes.byIndex(glIndices[i]);
  				if (gene.inContext) {
  					processMemberIds += gene.id + ',';
  				}
  			}

  			if (processMemberIds.length > 0) {
  				processMemberIds = processMemberIds.substring(0, processMemberIds.length - 1);

  				var isCategorized = evContext.indexOf("disease") >= 0;
  				var url = '/bda/data/evidence/finding/' + (isCategorized ? 'category/' : '')  + processId + '/' + processMemberIds;
  				this.getAndShowEvidence(url, handleResponse, evContext);
  			} else {
  				this.hideAll();
  			}
  		};

  		this.showPathwayEvidence = function(evidence, paramsObj, handleResponse, evContext) {
  			var url = '/bda/data/evidence/pathway/' + paramsObj.id;
  			if (paramsObj.nodeids && paramsObj.nodeids.length > 0) {
  				url += '/';
  				for (var nid in paramsObj.nodeids) {
  				  url += paramsObj.nodeids[nid] + ',';
  				}

  				url = url.substring(0, url.length - 1);
  			}

  			this.getAndShowEvidence(url, handleResponse, evContext);
  		};

  		this.showGeneEvidenceInContext = function(evidence, geneIds, objIds,  handleResponse, evContext) {
  			this.cancelXhr();

  			if (objIds.length > 0 && geneIds.length > 0) {
  				var isCategorized = evContext.indexOf("disease") >= 0;
  				var url = '/bda/data/evidence/finding/' + (isCategorized ? 'category/' : '') + objIds + '/' + geneIds;
  				this.getAndShowEvidence(url, handleResponse, evContext);
  			}  else {
  				this.hideAll();
  			}
  		};

  		this.showGeneEvidenceInReport = function(evidence, geneIds,  handleResponse, evContext) {
  			var url = '/bda/data/evidence/report/' + parent.reportid + '/' + geneIds;
  			this.getAndShowEvidence(url, handleResponse, evContext);
  		};

  		this.getAndShowEvidence = function (evUrl, handleResponse, evContext) {
        // this.cancelXhr();
        // this.curXhr = $.ajax({
        //    type: 'GET',
        //    url: evUrl,
        //    dataType: 'json',
        //    success: function(json) {
        //      populateEvidence(json, evidence, evContext);
        //      resetOptions();
        //      handleResponse(evidence);
        //    },
        //    error: function(jqXHR, textStatus, errorThrown) {
        //      evidencePanel.hideAll();
        //    },
        //    complete: function() {
        //      if (evidencePanel) {
        //        evidencePanel.curXhr = null;
        //    }
        //    }
        // });

        var options = {
          callback : function() {
            var json = JSON.parse(this.responseText);
            populateEvidence(json, evidence, evContext);
            resetOptions();
            handleResponse(evidence);
          },
        }
        x$(window).xhr(evUrl,options);
  		};

  		this.expandEvidence = function(refId) {
  			x$("div:regex(id, refDiv.*" + refId + ")").show();
  			x$("img:regex(id, expand.*" + refId + ")").unbind('toggle');
  			x$("img:regex(id, expand.*" + refId + ")").attr("src", evidencePanel.collapseBtnLoc);
  			x$("img:regex(id, expand.*" + refId + ")").toggle(
  					 function(){ $(this).attr("src", evidencePanel.expandBtnLoc); },
  					 function(){ $(this).attr("src", evidencePanel.collapseBtnLoc); }		
  			);
  		};

  		this.collapseEvidence = function(refId) {
  			x$("div:regex(id, refDiv.*" + refId + ")").hide();
  			x$("img:regex(id, expand.*" + refId + ")").unbind('toggle');
  			x$("img:regex(id, expand.*" + refId + ")").attr("src", evidencePanel.expandBtnLoc);
  			x$("img:regex(id, expand.*" + refId + ")").toggle(
  					 function(){ $(this).attr("src", evidencePanel.collapseBtnLoc); },
  					 function(){ $(this).attr("src", evidencePanel.expandBtnLoc); }		
  			);

  		};

  		var populateEvidence = function(evList, evidence, evContext) {

        // RE - This was causing problems
        // evidence.clear();
        // 
        // var keggRef = null;
        // for (var i in evList.findings) {
        //  var fin = evList.findings[i];
        // 
        //  if (fin.refIds.length == 0) {
        //    keggRef = new Reference('KEGGRef', null, null, null, null, 'Kyoto Encyclopedia of Genes and Genomes (KEGG)', null, null, null, null, evList.findings.length);
        //    evidence.addReference(keggRef);
        //    break;
        //  }
        // }
        // 
        //  for (var refid in evList.references) {
        //    var ref = evList.references[refid];
        //    evidence.addReference(new Reference(refid, ref.source, ref.url, ref.sourceid, ref.author, ref.title, ref.citation, ref.journal, ref.reference, ref.publicationDate, ref.findingCount));
        //  }
        // 
        //           
        //  for (var i in evList.findings) {
        //    var fin = evList.findings[i];
        //    evidence.addFinding(new Finding(fin.did, fin.nlg, (fin.refIds.length == 0 ? [keggRef.did] : fin.refIds), fin.type));
        //  }
        // 
        // evidence.updateValues();
  		};

  		var resetOptions = function() {
  		  
  		  // TODO - RE Re-implement this.
  		  
  		  /*
  			// reset properties of the previous sorted btn.
  			$(".sortedBtn").css("background-color", "#eee").css("border", "1px solid #eee");
  			$(".sortedBtn").mouseover(
  				function() {
  					$(this).css("background-color", hiliteColor).css("border", "1px solid #fff");
  				});
  			$(".sortedBtn").mouseout(
  				function() {
  					$(this).css("background-color", "#eee").css("border", "1px solid #eee");
  				});
  			$(".sortedBtn").removeClass("sortedBtn").addClass("sortBtn");


  			// reset properties of the previous filtered btn.
  			$(".filteredBtn").css("background-color", "#eee").css("border", "1px solid #eee");
  			$(".filteredBtn").mouseover(
  				function() {
  					$(this).css("background-color", hiliteColor).css("border", "1px solid #fff");
  				});
  			$(".filteredBtn").mouseout(
  				function() {
  					$(this).css("background-color", "#eee").css("border", "1px solid #eee");
  				});
  			$(".filteredBtn").removeClass("filteredBtn").addClass("filterBtn");

  			$(".filterBtn").each(function(){
  				var lbl = $(this).text();
  				var x = lbl.indexOf(' (');
  				$(this).html(lbl.substring(0, x > -1 ? x : lbl.length) + ' (0)');
  			});
  			*/
  		};

  		this.displayReferences = function(evidence) {

        $("#referencesLabel").html("Publications (" + evidence.refIds.length + ")");
  			var evhtml = '';
  			if (evidence.refTypesList.length == 0) {
  				evhtml = '<span style="font-weight: bold">No related evidence found.</span>';
  			} else {
  				evhtml += '<ol>';
  			}

  			for (var rtli in evidence.refTypesList) {
  				var rti = evidence.refTypesList[rtli];
  				var refTypeIds = evidence.refTypes[rti];
  				for (var refIndex in refTypeIds) {
  					var ref = evidence.references[refTypeIds[refIndex]];
  					evhtml += '<li class="evidenceRefList">';
  					var evDivId = 'ev' + ref.did;
  					var refDivId = 'refdiv' + ref.did;
  					//evhtml += '<div class="evidenceRef" style="display: list-item">';

  					if (ref.title != null) {
  						evhtml += '<span style="font-weight: bold; font-size: 11px;">'+ ref.title + '; </span>';
  					}

  					evhtml += '<span>';
  					if (ref.author != null) {
  						evhtml +=  ref.author + '; ';
  					}
  					if (ref.citation != null) {
  						evhtml +=  ref.citation + '; ';
  					}

  					if (ref.source != null && ref.sourceid != null) {
  						if (ref.url != null) {
  							evhtml += '<a href="'+ ref.url + '" target="_blank">';
  						}

  						evhtml += ref.source + ':' + ref.sourceid;

  						if (ref.url != null) {
  							evhtml += '</a>';
  						}

  						evhtml += '; ';
  					}

  					if (ref.pubDate != null) {
  						evhtml +=  getFormattedDate(new Date(ref.pubDate)) + '; ';
  					}

  					evhtml += '</span>';
  					evhtml += '</li>';
  				}
  			}

  			evhtml += '</ol>';

        $("#evidenceList").html(evhtml);
        $("#evidenceList").css("display", "inline");
        $("#evidencePanelDiv").effect("highlight", {color:"#05EBE7"}, 3000);

  			var callbacks = evidencePanel.callbacks;
  			if (callbacks['evidenceLoaded'] != null) {
  				// iterate through the callbacks
  				for (var cb in callbacks['evidenceLoaded']) {
  					callbacks['evidenceLoaded'][cb]();
  				}
  			}

  		};

  		this.displayEvidence = function(evidence, typeFilter) {
  		  var pageType = gSelType;
        x$("#referencesLabel").html("Publications and Findings (" + evidence.finIds.length + ")");
  			var evhtml = '';
  			if (evidence.refTypesList.length == 0) {
  				evhtml = '<span style="font-weight: bold">No related evidence found.</span>';
  			}

  			var evTypeFilter = evidencePanel.curTypeFilter;
  			if (arguments.length > 1) {
  				evTypeFilter = typeFilter;
          evidencePanel.curTypeFilter = evTypeFilter;
  			} else if (pageType == "diseases") {
  				for (var rtli in evidence.refTypesList) {
  					var rti = evidence.refTypesList[rtli];
  					if (evidence.refTypesCounts[rti] > 0) {
  						evTypeFilter = rti;
  						evidencePanel.curTypeFilter = evTypeFilter;
  						$('#'+rti+'Evidence').click();
  						return;
  					}
  				}
  			}

  			if (pageType == "diseases") {
  				for (var type in evidenceTypes.types) {
  					var catName = evidenceTypes.types[type].name;
  					var catColor = evidenceTypes.types[type].color;
  					var catCount = evidence.refTypesCounts[catName] != null ? evidence.refTypesCounts[catName] : 0;

  					if ((catName+'Evidence') == evTypeFilter) {
  						$('#'+catName+'Evidence').html(catName + ' (' + catCount + ')');
  					} else {
  						$('#'+catName+'Evidence').html('<img src="../images/chip.png" style="background-color:' + catColor +' "/>' + ' ' + catName + ' (' + catCount + ')');
  					}
  				}
  			}

  			var refDivIds = new Array();
  			for (var rtli in evidence.refTypesList) {
  				var rti = evidence.refTypesList[rtli];
  				var refTypeIds = evidence.refTypes[rti];

  				if (pageType == "diseases") {
  					if (evTypeFilter != 'allEvidence') {
  						if (evTypeFilter.indexOf(rti) == -1) {
  							continue; // skip the type.
  						}
  					} 
  				}

  				for (var refIndex in refTypeIds) {
  					var ref = evidence.references[refTypeIds[refIndex]];

  					if (ref.findingTypes.hasOwnProperty(rti)) {
  						var evDivId = 'ev' + rti + ref.did;
  						var refDivId = 'refdiv' + rti + ref.did;
  						var expDivId = 'expand' + rti + ref.did;
  						refDivIds.push(refDivId);

  						evhtml += '<li id="' + evDivId + '" class="evidence">';
  						evhtml += '<div class="evidenceRef">';

  						if (ref.title != null) {
  							evhtml += '<span>'+ ref.title + '; </span>';
  						}

  						evhtml += '<span>';
  						
  						if (ref.author != null) { evhtml +=  ref.author + '; '; }
  						if (ref.citation != null) { evhtml +=  ref.citation + '; '; }

  						if (ref.source != null && ref.sourceid != null) {
  						  
  							if (ref.url != null) { evhtml += '<a href="'+ ref.url + '" target="_blank">'; }
  							evhtml += ref.source + ':' + ref.sourceid;
  							if (ref.url != null) { evhtml += '</a>'; }

  							evhtml += '; ';
  						}

  						if (ref.pubDate != null) {
  							evhtml +=  getFormattedDate(new Date(ref.pubDate)) + '; ';
  						}

  						evhtml += '</span>';
  						evhtml += '<div id="' + refDivId + '" refdid="' + ref.did + '" reftype="' + rti + '"></div>';
  						evhtml += '</div></li>'; // end class="evidenceRef", end class="evidence"
  					}
  				}
  			}

        x$("#evidenceList").html(evhtml);

  			for (var rtli in evidence.refTypesList) {
  				var rti = evidence.refTypesList[rtli];
  				var refTypeIds = evidence.refTypes[rti];

  				if (pageType == "diseases") {
  					if (evTypeFilter != 'allEvidence') {
  						if (evTypeFilter.indexOf(rti) == -1) {
  							continue; // skip the other types.
  						}
  					} 
  				}

  				for (var refIndex in refTypeIds) {
  					var ref = evidence.references[refTypeIds[refIndex]];

  					if (ref.findingTypes.hasOwnProperty(rti)) {
  						var evDivId = 'ev' + rti + ref.did;
  						var refDivId = 'refdiv' + rti + ref.did;
  						var expDivId = 'expand' + rti + ref.did;

              //  x$("#evidenceList").find("div[id*='" + refDivId + "']").hide();
              //  x$("#evidenceList").find("img[id*='" + expDivId + "']").toggle(
              //      function(){ $(this).attr("src", evidencePanel.collapseBtnLoc); },
              //      function(){ $(this).attr("src", evidencePanel.expandBtnLoc); }
              // ).click(function() {
                // var expDivId = this.id;
                // var refDivId = "refdiv" + this.id.substring('expand'.length);
                // var findingsListDiv = x$("#evidenceList").find("div[id*='" + refDivId + "']");
                // var isVisible = findingsListDiv.is(":visible");

                // if (!isVisible) {
                  // var findingsHtml = '<span style="font-weight: bold;">Findings </span>';
                  // findingsHtml += '<ol>';

                  // var refId = findingsListDiv.attr("refdid");
                  // var refType = findingsListDiv.attr("reftype");
                  // var ref = evidence.references[refId];
                  // for (var i in ref.findingIds) {
                  //  var finid = ref.findingIds[i];
                  //  if (evidence.findings[finid].type == refType) {
                  //    findingsHtml += '<li>' + evidence.findings[finid].nlg + '</li>';
                  //  }
                  // }
                  // findingsHtml += '</ol>';
                  // findingsListDiv.html(findingsHtml);
                // } else {
                //  findingsListDiv.html("");
                // }

                // findingsListDiv.toggle();
              // });
  					}
  				}
  			}
        x$("#evidenceList").css({display: "inline"});

  			var callbacks = evidencePanel.callbacks;
  			if (callbacks['evidenceLoaded'] != null) {
  				for (var cb in callbacks['evidenceLoaded']) {
  					callbacks['evidenceLoaded'][cb]();
  				}
  			}
  		};
  	}

/// END EVIDENCE PANEL ----



/**
 * Gene Table Chapter
 *
 * All chapter logic should eventually be migrated here
 *
 */

function genetable() {
	this.init = function() {
		var scope = this;
		setTimeout(function() {scope.rankLoad()},200);
	};

	this.rankTable = function(div) {

    // TODO RE - Not sure I still need these
		this.grid.topicArray = genes;
		this.grid.render(div);
	};

	this.rankLoad = function() {
	  
	  x$("#geneTable TABLE").html("");
	  
		// make a copy of the data to be sure it doesn't affect other parts of the app

		var listData = [];
		var l;
		var lLen = genes.list.length;
		
		for (l=0; l < lLen; l++) {
			if(!genes.list[l].inContext) continue;
			listData.push(genes.list[l]);
			listData[listData.length -1].interaction_count = genes.list[l].upstreamInx + genes.list[l].downstreamInx + genes.list[l].bindingInx;
		}

		// modify the rank table label
		x$("#geneTableLabel").html("Genes (" + listData.length + ")");

    var rowData  = " <tr>";
        rowData += "   <td>Symbol:Name</td>";
        rowData += "   <td>Fold Change</td>";
        rowData += "   <td>Molecular Function</td>";
        rowData += "   <td>Location</td>";
        rowData += "   <td>Pathways</td>";
        rowData += "   <td>Processes</td>";
        rowData += "   <td>Diseases</td>";
        rowData += "   <td>Interactions</td>";
        rowData += " </tr>";

    x$("#geneTable TABLE").top(rowData);

    function sortByFold(a, b) { return a.foldChange - b.foldChange; }
    listData = listData.sort(sortByFold);
    
		var lLen = (gDisplayData == 0) ? listData.length : gDisplayData;              

    for (var i = 0; i < lLen; i++) {
      var symName = listData[i].getSymbol() + " : " + listData[i].getName();
      var fold = "<span style='float: left;width:10px;height:10px;background-color:"+listData[i].getExpColor()+ "'></span>" +  listData[i].foldChange;
      
      var rowData  = " <tr>";
          rowData += "  <td>" + symName + "</td>";
          rowData += "  <td>" + fold + "</td>";
          rowData += "  <td>" + listData[i].proFamily + "</td>";
          rowData += "  <td>" + listData[i].location + "</td>";
          rowData += "  <td>" + listData[i].pathways.length + "</td>";
          rowData += "  <td>" + listData[i].bioProcesses.length + "</td>";
          rowData += "  <td>" + listData[i].diseases.length + "</td>";
          rowData += "  <td>" + listData[i].interactions.length + "</td>";
          rowData += " </tr>";

      x$("#geneTable TABLE").bottom(rowData);
    }

	};
}

