// constructor and methods for the evidence object

function Evidence() {
	this.references = new Object();
	this.findings = new Object();
	this.refIds = new Array();
	this.finIds = new Array();
	
	this.refTypes = new Object();
	this.refTypesList = new Array(); // for sorting by type???? - unimplemented
	this.refTypesCounts = new Object();
	
	this.addReference = function(ref) {
		this.references[ref.did] = ref;
		this.refIds.push(ref.did);
	};
	
	this.addFinding = function(finding) {
		this.findings[finding.did] = finding;
		this.finIds.push(finding.did);
	};
	
	this.clear = function() {
		this.references = new Object();
		this.findings = new Object();
		this.refIds.length = 0;
		this.finIds.length = 0;
		this.refTypes = new Object();
		this.refTypesList.length = 0;
		this.refTypesCounts = new Object();
	};
	
	this.updateValues = function() {
		var refTypesMap = new Object();
		var finTypes = new Object();
		for (var x in this.finIds) {
			var fin = this.findings[this.finIds[x]];
			if (this.refTypes[fin.type] == undefined) {
				this.refTypes[fin.type] = new Array();
			}
			
			if (!refTypesMap.hasOwnProperty(fin.type)) {
				refTypesMap[fin.type] = new Object();
			}
			
			var t = fin.type;
			if (!finTypes.hasOwnProperty(t)) {
				finTypes[t] = 1;
			} else {
				finTypes[t]++;
			}
			
			for (var i = 0; i < fin.refIds.length; i++) {
				var finRefId = fin.refIds[i];
				this.references[finRefId].findingIds.push(fin.did);
				
				//check if the refTypes array already contains this refId. If it does not contain the refId, then add it.
				var idExists = false;
				var refTypeIds = this.refTypes[fin.type];
				if (!refTypesMap[fin.type].hasOwnProperty(finRefId)) { // to enable faster lookup
					refTypesMap[fin.type][finRefId] = finRefId;
					refTypeIds.push(finRefId);
				}
				
				var ft = this.references[finRefId].findingTypes; // add up the finding type counts within each reference.
				if (!ft.hasOwnProperty(t)) {
					ft[t] = 1;
				} else {
					ft[t]++;
				}
			}
			
		}
		
		for (var i in this.refTypes) { // Get total count of different evidence types
			this.refTypesList.push(i);
			this.refTypesCounts[i] = finTypes[i];
		}
		
		this.sortBy("sortByDate");
	};
	
	this.sortBy = function(sortProp) {
		if (sortProp == "evidenceType") {
			this.refTypesList.sort(function(t1, t2) {
				return (t1 > t2 ? 1 : (t1 == t2 ? 0 : -1));
			});
		} else if (sortProp == "sortByJournal") {
			for (var rti in this.refTypes) {
				var refTypeIds = this.refTypes[rti];
			
				refTypeIds.sort(function(id1, id2) {
					var refObj = parent.comm.evidence.references;
					var j1 = refObj[id1].journal != null ? refObj[id1].journal : 'zzzzzzzzzzz';
					var j2 = refObj[id2].journal != null ? refObj[id2].journal : 'zzzzzzzzzzz';
					
					return (j1 > j2 ? 1 : (j1 == j2 ? 0 : -1));
				});
			}
		} else if (sortProp == "sortByCitation") {
			for (var rti in this.refTypes) {
				var refTypeIds = this.refTypes[rti];
			
				refTypeIds.sort(function(id1, id2) {
					var refObj = parent.comm.evidence.references;
					var j1 = refObj[id1].citation;
					var j2 = refObj[id2].citation;
					
					return (j1 > j2 ? 1 : (j1 == j2 ? 0 : -1));
				});
			}
		} else if (sortProp == "sortByDate") {
			for (var rti in this.refTypes) {
				var refTypeIds = this.refTypes[rti];
			
				// Changing to mergeSort since the default sort implementation in Webkit is SelectionSort which is not suitable for large arrays.
				// http://stackoverflow.com/questions/234683/javascript-array-sort-implementation
				// http://en.wikipedia.org/wiki/Selection_Sort
				this.refTypes[rti] = merge_sort(refTypeIds, function(id1, id2) {
					var refObj = evidence.references;
					var j1 = refObj[id1].pubDate;
					var j2 = refObj[id2].pubDate;
					
					return (j1 < j2 ? 1 : (j1 == j2 ? 0 : -1)); // sort dates from newest to oldest
				});
			}
		} else if (sortProp == "sortByTitle") {
			for (var rti in this.refTypes) {
				var refTypeIds = this.refTypes[rti];
			
				refTypeIds.sort(function(id1, id2) {
					var refObj = evidence.references;
					var j1 = refObj[id1].title != null ? refObj[id1].title : (refObj[id1].reference != null ? refObj[id1].reference : 'zzzzzzzzzzz');
					var j2 = refObj[id2].title != null ? refObj[id2].title : (refObj[id2].reference != null ? refObj[id2].reference : 'zzzzzzzzzzz');
					
					return (j1 > j2 ? 1 : (j1 == j2 ? 0 : -1));
				});
			}
		} else if (sortProp == "sortByAuthor") {
			for (var rti in this.refTypes) {
				var refTypeIds = this.refTypes[rti];
			
				refTypeIds.sort(function(id1, id2) {
					var refObj = evidence.references;
					var j1 = refObj[id1].author != null ? refObj[id1].author : 'zzzzzzzzzzz';
					var j2 = refObj[id2].author != null ? refObj[id2].author : 'zzzzzzzzzzz';
					
					return (j1 > j2 ? 1 : (j1 == j2 ? 0 : -1));
				});
			}
		}
 	};
}

function Reference(did, source, url, sourceid, author, title, citation, journal, reference, pubDate, findingCount) {
	this.did = did;
	this.source = source;
	this.url = url;
	this.sourceid = sourceid;
	this.author = author;
	this.title = title;
	this.citation = citation;
	this.journal = journal;
	this.reference = reference;
	this.pubDate = pubDate;
	this.findingCount = findingCount;
	
	this.findingIds = new Array();
	this.findingTypes = new Object();
}

function Finding(did, nlg, referenceIds, type) {
	this.did = did;
	this.nlg = nlg;
	this.type = type;
	this.refIds = referenceIds;
}

function EvidenceTypes() {
	this.types = new Object();
	this.types["Biomarker"] = new EvidenceType('Biomarker', '#E01B94');
	this.types["Drug"] = new EvidenceType('Drug', '#1BAB20');
	this.types["Expression"] = new EvidenceType('Expression', '#635F1D');
	this.types["Mutation"] = new EvidenceType('Mutation', '#FF9100');
	this.types["Unclassified"] = new EvidenceType('Unclassified', '#BDB6AE');
	
	this.getDiseaseEvidenceCategoryColor = function(category) {
		if (this.types[category] != null) {
			return this.types[category].color;
		} else {
			return this.types["Unclassified"].color;
		}
	};
}

function EvidenceType(name, color) {
	this.name = name;
	this.color = color;
}




