// constructor and methods for pathways object

//   name, desc, lpV, ratio, rank, id, index, gns
function Pathway(name, desc, lpV, ratio, rank, id, index, gns, molRank, adjRank) {
	this.name = name.toTitleCase();
	this.pValue = lpV;
	this.hasRank = true;
	this.rank = 0;
	this.rankMi = molRank; 
	this.rankAp = adjRank; 
	this.ratio = ratio;
	this.id = id;
	this.index = index;
	this.topic = "pathways";
	this.topicLabel = "Canonical Pathway";
	this.topicArray = pathways;
	this.desc = this.name + ": " + desc;
	this.genes = new Array();
	this.fullGeneList = gns;
	this.genesNotInDataset = [];
	this.inContext = true;
	this.citations = [];
	this.graphics={wheel:null, matrix:null};
	
	// the fullGeneList is all genes in this process
	// this.genes are the genes in this dataset which are in the pathway..
	for (var i=0; i<this.fullGeneList.length; i++) {
		var gt = genes.indexById(this.fullGeneList[i]);
		if(gt != -1) {
			this.genes.push(gt);
			genes.list[gt].pathways.push(this.index);   // add this pathway to the gene's list
		} else {
			this.genesNotInDataset.push(this.fullGeneList[i]);
		}
	}
	
	this.getRank = function() {
		return this.rank;
	};
	
	this.getPVRank = function() {
		this.rank = 1.0 - (this.pValue - pathways.rankRange.min)*pathways.rankRange.inv;
		return this.rank;
	};
	
	
	this.fillDetails = function() {
		$("#detailsLabel").html(this.name);
		getPathwayDesc(this.id);
		$("#pathwayDetail").css("display", "inline");
		$("#pathwayGeneTitle").text(this.genes.length + " Genes");
		var genesInPwy="";
		for (i=0;i<this.genes.length; i++) {
			var gid = this.genes[i];
			genesInPwy+= "<img src='../images/chip.png' style='background-color:" +
				     genes.list[gid].getExpColor() +  "'>" + genes.list[gid].symbol + "</img>, ";
		}
		genesInPwy = genesInPwy.substring(0, genesInPwy.length-2);
		$("#pathwayGeneList").html(genesInPwy);
	};

	this.select = function() {
	};
	
	this.updateDetails = function(){
		this.fillDetails();
		 var geneDids = new Array();
		 
		 for (i = 0; i < this.genes.length; i++) {
			 var gid = this.genes[i];
			 geneDids[i] = genes.list[gid].id;
		 }		 
		 if(parent.view.$("#GraphExplorer")[0] != null)
			 getGroupComplexInfo(geneDids, this.showPathway, this);		
	}
	
	this.showPathway = function(gcJson, pwy) {

		var pathwayUrl = window.location.protocol + "//" + window.location.host + "/bda/pathways/" + pwy.id.replace(':','_') +".xml";
		var hiliteNodes = new Object();
		for (i=0;i<pwy.genes.length; i++) {
			var gid = pwy.genes[i];
			var gdid = genes.list[gid].id;
			var expColor = genes.list[gid].getExpColor().replace('#','0x');
			var colorObj = new Object();
			colorObj["color1"] = expColor;
			colorObj["color2"] = expColor;
			hiliteNodes[gdid] = colorObj;
		}
		
		//get the gradient range for groups/complexes
		var nodeId2gcIdMap = gcJson["nodeId2gcIdMap"];
		var gcIdMap = new Object();
		for (var i in nodeId2gcIdMap) {
			var gcMember = nodeId2gcIdMap[i];
			for (var j in gcMember) {
				var gcRoot = gcMember[j];
				var gcmp = gcIdMap[gcRoot];
				if (gcmp == undefined) {
					gcmp = new Array();
					gcIdMap[gcRoot] = gcmp;
				}
				gcmp.push(hiliteNodes[i]["color1"]);
			}
		}
		
		for (var i in gcIdMap) {
			var colors = getGradientRange(gcIdMap[i]);
			//hiliteNodes[i] = colors;
			var colorObj = new Object();
			colorObj["color1"] = colors[0];
			colorObj["color2"] = colors[1];
			hiliteNodes[i] = colorObj;
		} 

		parent.view.curPwyGCInfo = gcJson;		
		parent.view.$("#canvasLabel").html(pwy.getName());
		
		var lhParams = pathwayUrl + '|';
		var nc = 0;
		for (var nid in hiliteNodes) {
			lhParams += nid;
			lhParams += '-' + hiliteNodes[nid]["color1"];
			lhParams += '-' + hiliteNodes[nid]["color2"];
			lhParams += ';';
			
			nc++;
		}
		 if (nc > 0) {
			 lhParams = lhParams.substring(0, lhParams.length - 1);
		 }
		
		
		var graphExp = parent.view.$("#GraphExplorer").get(0);
		if (graphExp.loadAndHighlight) graphExp.loadAndHighlight(lhParams);
		parent.view.pathwayPanel.setPathway(pwy);

		// hide the no pathway message
		parent.view.$("#pathwayMsg").hide();
	};

	this.getGeneList = function() {
		return this.genes;
	};
	
	this.getRankQuartile = function() {
		var q =  3 - quartile(this.rank, pathways.rankRange);	// min -> 0,  max -> 3  --- based on rank 
		return q;
	};
	
	this.getHierarchyObject = function() {
		var hier;
		var curNode = null;
		for (var i=0; i<hierarchies.length; i++) {  // shouldn't have to do this now.. should be done at initialization
			if(hierarchies[i].topic.indexOf("pathwa") >=0) hier = hierarchies[i];
		}
		var hierObj = null;
		for (var i=0; i < hier.nodes.length; i++) {
			if(hier.nodes[i].id == this.id) {
				hierObj = hier.nodes[i];
			};
		}
		return hierObj;
	}
	
	this.getRimObject = function() {
		var hierObj = this.getHierarchyObject();
		var curNode = null;
		if(hierObj) {
			curNode = hierObj;
			while(!curNode.rimChip) {
				curNode = curNode.parentObj;
			}
		}
		return curNode;
	}
	
	this.getTopic 		= function() { return this.topic;};
	this.getTopicLabel 	= function() { return this.topicLabel;};
	this.getTopicArray  = function() {return this.topicArray;};
	this.getName 		= function() { return this.name;};
	this.getIndex 		= function() {return this.index;};
	this.getDesc 		= function() {return this.desc;};
	this.getId  		= function() {return this.id;};
	
	this.getGenesInContext = function() {
		var lst = [];
		for(var i=0; i<this.genes.length; i++) {
			if(genes.list[this.genes[i]].inContext) lst.push(this.genes[i]);
		}
		return lst;
	};
	
	
	this.isInContext = function() {
		var gl = this.getGenesInContext();
		this.inContext = (gl.length > 0)? true : false;
		return this.inContext;
	};
}

function getGroupComplexInfo(geneIds, handleResult, pwy) {
  console.log("XHR CALLED in Pathways")
	$.getJSON('/bda/data/genes/gcparents/' + geneIds.join(","), function (gcJson) {
		handleResult(gcJson, pwy);
	});
}

function getPathwayDesc(did) {
  console.log("XHR CALLED in Pathways")
	$.getJSON('/bda/data/pathways/desc/' + did, function showDesc(descJson) {
		parent.view.$("#dpDesc").html(descJson.desc);
	});
}

function selectPathwayNodes() {
}

function initPathways(updatePathways, pathwayList, callback) {
	updatePathways(pathwayData[reportId].pathways, pathwayList, callback);
}


function updatePathwaysList(p, pList, callback) {
  var len = (gDataSize == 0) ? p.length : gDataSize;
	var tempgenes = " ITGB1, TLN2, CAPNS1, PIK3R1, TNS1, GIT2";
  var pValueCutoff = 99999;
  
	for (var i=0; i< len; i++) {
		if(p[i].pvalue <= pValueCutoff) {	  
			var pwy = new Pathway(p[i].name, "dummy descrtiption", p[i].pvalue, p[i].ratio,
					0, p[i].did, i, p[i].molIds, p[i].molecularRank, p[i].adjacencyRank);
			pList.list.push(pwy);
		}
	}

	pList.updateValues();
	callback();
}

function PathwaysList() {
	this.name = 'pathways';
	this.list = new Array();
	this.maxNumMembers = 0;
	this.rankRange = {min:0, max:0, inv:1};  // provisional ... calculated below
	this.rankMiRange = {min:0, max:1, inv:1};
	this.rankApRange = {min:0, max:1, inv:1};
	this.ratioRange = {min:0, max:1, inv:1};  // what is this?

	this.getName = function(){
		return this.name;
	};
	
	this.updateValues = function() {
		var pValueMin = 99999999;
		var pValueMax = -rankMin;
		
		var rankMin = 99999999;
		var rankMax = -rankMin;
		
		var rankApMin = 99999999;
		var rankApMax = -rankApMin;
		
		var rankMiMin = 99999999;
		var rankMiMax = -rankMiMin;
		
		var ratioMin = 99999999;
		var ratioMax = -ratioMin;
		
		var mxmem = 0
		for (var i=0; i<this.list.length; i++) {
			pValueMin = Math.min(pValueMin, this.list[i].pvalue);
			pValueMax = Math.max(pValueMax, this.list[i].pvalue);
			rankApMin = Math.min(rankApMin, this.list[i].rankAp);
			rankApMax = Math.max(rankApMax, this.list[i].rankAp);
			rankMiMin = Math.min(rankMiMin, this.list[i].rankMi);
			rankMiMax = Math.max(rankMiMax, this.list[i].rankMi);
			ratioMin = Math.min(ratioMin, this.list[i].ratio);
			ratioMax = Math.max(ratioMax, this.list[i].ratio);
			mxmem = Math.max(this.list[i].genes.length, mxmem);
		}
		this.maxNumMembers = mxmem;
		this.rankRange = {min:0, max:0.1, inv:1};  // not updated here...
		this.rankMiRange = {min:rankMiMin, max:rankMiMax, inv:(rankMiMax==rankMiMin)? 1: 1.0/(rankMiMax-rankMiMin)};
		this.rankApRange = {min:rankApMin, max:rankApMax, inv:(rankApMax==rankApMin)? 1: 1.0/(rankApMax-rankApMin)};
		this.pValueRange = {min:pValueMin, max:pValueMax, inv:(pValueMax==pValueMin)? 1: 1.0/(pValueMax-pValueMin)};
		this.ratioRange = {min:ratioMin, max:ratioMax, inv:(ratioMax==ratioMin)? 1: 1.0/(ratioMax-ratioMin)};  
	};

	this.numberInContext = function() {
		var num=0;
		for (var i=0; i<this.list.length; i++) {
			if(this.list[i].inContext) num++;
		}
		return num;
	};

	this.listInContext = function() {
		var l = new Array();
		for (var i=0;i<this.list.length; i++) {
			if(this.list[i].inContext) l.push(i);
		}
		return l;
	};
	
	this.byId = function(pid) {
		var pwy = null;
		for (var i=0;i<this.list.length; i++) {
			if(this.list[i].id == pid) {
				pwy = this.list[i];
			}
		} 
		
		return pwy;
	};
	
	this.getByID = function(pid) {
		return this.byId(pid);      // compatibility...
	};
	
	this.byIndex = function(i) {
		return this.list[i];
	};

	this.reRank = function(considerMi, considerAp) {
		var rmin=999999999;
		var rmax = -rmin;
		var r=0;
		for(var i=0;i<this.list.length; i++) {
				r = 0;
				if(considerMi) {
					r+= (this.list[i].rankMi-this.rankMiRange.min)*this.rankMiRange.inv;  // between 0,1
				}
				if(considerAp) {
					r+= (this.list[i].rankAp-this.rankApRange.min)*this.rankApRange.inv;  // between 0,1
				}
				if(considerAp && considerMi) r = r/2;  // keep it between 0,1
				this.list[i].rank = r;
				rmin = Math.min(rmin,r);
				rmax = Math.max(rmax,r);
		}
		this.rankRange.min = rmin;
		this.rankRange.max = rmax;
		if(this.rankRange.min == this.rankRange.max) {
			this.rankRange.inv = 1;
		} else {
			this.rankRange.inv = 1.0/(rmax-rmin);
		}
	};
	
	this.sortBy = function(opt, inContext) {
		var l = [];
		if(inContext) {
			l = this.listInContext();
		} else {
			for (var i=0; i<this.list.length; i++) {
				l[i] = i;
			}
		}
		l.sort(function(a,b) {
			return pathways.list[a].pValue - pathways.list[b].pValue;
		});
		
		return l;
	};
	
	this.getByID = function(id) {
		for (var i=0; i<this.list.length; i++) {
			if(this.list[i].id == id) return this.list[i];
		}
		return null;
	}
}
