/* term.js
 * Handles the term viewer section of the site
 * 
 * John Paulett
 */

var parentMapping = new Array();
parentMapping['partof'] = 'Part of';
parentMapping['isa'] = 'Is a';
parentMapping['branchof'] = 'Branch of';
parentMapping['segmentof'] = 'Segment of';
parentMapping['tributaryof'] = 'Tributary of';
parentMapping['continuouswith'] = 'Continuous with';
parentMapping['containedin'] = 'Contained in';
parentMapping['memberof'] = 'Member of';
parentMapping['bloodsupplyof'] = 'Blood Supply of';
parentMapping['innervates'] = 'Innervates';
parentMapping['hasentrapmentsite'] = 'Has Entrapment Site';
parentMapping['synonymof'] = 'Synonym of';

var childMapping = new Array();
childMapping['partof'] = 'Part';
childMapping['isa'] = 'Subtypes';
childMapping['branchof'] = 'Branch';
childMapping['segmentof'] = 'Segment';
childMapping['tributaryof'] = 'Tributary';
childMapping['continuouswith'] = 'Continuous with';
childMapping['containedin'] = 'Contains';
childMapping['memberof'] = 'Member';
childMapping['bloodsupplyof'] = 'Has Blood Supply';
childMapping['innervates'] = 'Has Innervation Source';
childMapping['hasentrapmentsite'] = 'Entrapment Site';
childMapping['synonymof'] = 'Synonym';	

function getTerm(radlexID,storeHistory) {
	if (storeHistory == null){
		storeHistory = true;
	}
	highlightTerm(radlexID);
	var url = 'getTermByID?radlexID=' + radlexID;
	runAjax(url,parseTerm,false);
	if (storeHistory){
		addHistory(radlexID,getBaseID(),getRelationType());
	}
}	

function getTermNoTreeUpdate(radlexID){
	var url = 'getTermByID?radlexID=' + radlexID;
	runAjax(url,parseSynonym,false);
}

function getAtt(radlexID){
	var url = 'getTermByID?radlexID=' + radlexID;
	runAjax(url,parseSynonym,false);
}


function parseSynonym(response){
	var radlexID = response.getAttribute('id')
	var radlexName = response.getElementsByTagName('name')[0].firstChild.data;
	var uri = response.getElementsByTagName('uri')[0].firstChild.data;
	
	var hash = getHash();
	var baseID = (hash['baseID'] != null)? hash['baseID']:"";
	updateHash(radlexID,baseID,document.forms['radRelation'].radRelationSelect.value)
	
	//set up the viewer
	var buffer = '<table>';
	
	buffer += '<tr valign="top"><td class="slotLabel">Name</td><td>'+radlexName+'</td></tr>';
	buffer += '<tr valign="top"><td class="slotLabel" nowrap="true">RadLex ID</td><td>'+radlexID+'</td></tr>';
	buffer += '<tr valign="top"><td class="slotLabel">URI</td><td><a href="'+uri+'">'+uri+'</a></td></tr>';


	var definition = createSlotValue('definition',response,false);
	if (definition != '')buffer += '<tr valign="top"><td class="slotLabel">Definition</td><td>'+definition+'</td></tr>';
	var comment = createSlotValue('comment',response,false);
	if (comment != '') buffer += '<tr valign="top"><td class="slotLabel">Comment</td><td>'+comment+'</td></tr>';
	
	
	var source = createSlotValue('source',response,false);
	if (source != '') buffer += '<tr valign="top"><td class="slotLabel">Source</td><td>'+source+'</td></tr>';
	
	
	var dateCreated = createSlotValue('dateCreated',response,false);
	if (dateCreated != '') buffer += '<tr valign="top"><td class="slotLabel">Date Created</td><td>'+dateCreated+'</td></tr>';
	var termStatus = createSlotValue('termStatus',response,false);
	if (termStatus != '') buffer += '<tr valign="top"><td class="slotLabel">Term Status</td><td>'+termStatus+'</td></tr>';
	var versionNumber = createSlotValue('versionNumber',response,false);
	if (versionNumber != '') buffer += '<tr valign="top"><td class="slotLabel">Version Number</td><td>'+versionNumber+'</td></tr>';
	var acr = createSlotValue('acr',response,true);
	if (acr != '') buffer += '<tr valign="top"><td class="slotLabel">ACR</td><td>'+acr+'</td></tr>';
	var snomed= createSlotValue('snomed',response,true);
	if (snomed != '') buffer += '<tr valign="top"><td class="slotLabel">SNOMED</td><td>'+snomed+'</td></tr>';
	var umls = createSlotValue('umls',response,true);
	if (umls != '') buffer += '<tr valign="top"><td class="slotLabel">UMLS</td><td>'+umls+'</td></tr>';
		
	//make the html for the children and parent relationships
	var parentSlots = makeRelationHTML(response.getElementsByTagName('parent'), false, false)
	var childrenSlots = makeRelationHTML(response.getElementsByTagName('child'), false, true);

	buffer += '<tr><td colspan="2">&nbsp;</td></tr>';
	buffer += combineRelationships(parentSlots, childrenSlots);
	buffer += '</table>';
	document.getElementById('termViewer').innerHTML = buffer;
}


function parseTerm(response) {
	var radlexID = response.getAttribute('id')
	var radlexName = response.getElementsByTagName('name')[0].firstChild.data;
	var uri = response.getElementsByTagName('uri')[0].firstChild.data;
	
	var hash = getHash();
	var baseID = (hash['baseID'] != null)? hash['baseID']:"";
	updateHash(radlexID,baseID,document.forms['radRelation'].radRelationSelect.value)
	
	//set up the viewer
	var buffer = '<table>';
	
	buffer += '<tr valign="top"><td class="slotLabel">Name</td><td>'+radlexName+'</td></tr>';
	buffer += '<tr valign="top"><td class="slotLabel" nowrap="true">RadLex ID</td><td>'+radlexID+'</td></tr>';
	buffer += '<tr valign="top"><td class="slotLabel">URI</td><td><a href="'+uri+'">'+uri+'</a></td></tr>';

	var definition = createSlotValue('definition',response,false);
	if (definition != '')buffer += '<tr valign="top"><td class="slotLabel">Definition</td><td>'+definition+'</td></tr>';
	var comment = createSlotValue('comment',response,false);
	if (comment != '') buffer += '<tr valign="top"><td class="slotLabel">Comment</td><td>'+comment+'</td></tr>';
	
	
	var source = createSlotValue('source',response,false);
	if (source != '') buffer += '<tr valign="top"><td class="slotLabel">Source</td><td>'+source+'</td></tr>';
	
	
	var dateCreated = createSlotValue('dateCreated',response,false);
	if (dateCreated != '') buffer += '<tr valign="top"><td class="slotLabel">Date Created</td><td>'+dateCreated+'</td></tr>';
	var termStatus = createSlotValue('termStatus',response,false);
	if (termStatus != '') buffer += '<tr valign="top"><td class="slotLabel">Term Status</td><td>'+termStatus+'</td></tr>';
	var versionNumber = createSlotValue('versionNumber',response,false);
	if (versionNumber != '') buffer += '<tr valign="top"><td class="slotLabel">Version Number</td><td>'+versionNumber+'</td></tr>';
	var acr = createSlotValue('acr',response,true);
	if (acr != '') buffer += '<tr valign="top"><td class="slotLabel">ACR</td><td>'+acr+'</td></tr>';
	var snomed= createSlotValue('snomed',response,true);
	if (snomed != '') buffer += '<tr valign="top"><td class="slotLabel">SNOMED</td><td>'+snomed+'</td></tr>';
	var umls = createSlotValue('umls',response,true);
	if (umls != '') buffer += '<tr valign="top"><td class="slotLabel">UMLS</td><td>'+umls+'</td></tr>';
		
	//make the html for the children and parent relationships
	var parentSlots = makeRelationHTML(response.getElementsByTagName('parent'), false, false)
	var childrenXML = response.getElementsByTagName('child');
	var childrenSlots = makeRelationHTML(childrenXML, true, true);
	
	buffer += '<tr><td colspan="2">&nbsp;</td></tr>';
	buffer += combineRelationships(parentSlots, childrenSlots);
	buffer += makeAttributeHTML(response.getElementsByTagName('attribute'))
	buffer += '</table>';
	document.getElementById('termViewer').innerHTML = buffer;
	
	// limit which relations to display
	var childRelationshipTypes = listChildrenRelationshipTypes(childrenXML);
	limitRelationPullDown(childRelationshipTypes); 
	
	// expand the tree under this term
	if(childRelationshipTypes.length > 0) {
		insertChildren(radlexID);
	}
}

function makeAttributeHTML(attXML){
	var retVal = "";
	if (attXML.length == 0){
		return retVal;
	}
	retVal += '<tr valign="bottom"><td colspan="2" class="slotLabel"><br />RadLex Attributes</td></tr>'
	
	for (i = 0; i < attXML.length; i++){
		retVal += '<tr valign="top"><td nowrap="true"><b><a onclick="getTermNoTreeUpdate(\''+attXML[i].getAttribute('id')+'\')" style="cursor:pointer">'+attXML[i].getAttribute('name')+'</a></b>';
		attValues = attXML[i].getElementsByTagName('attValue');
		if (attValues.length > 0){
			var tempBuf = "";
			for (j = 0; j < attValues.length; j++){
				if (attValues[j].getAttribute('primarytree') == 0) {
					tempBuf += '<a onclick="getTermNoTreeUpdate(\''+attValues[j].getAttribute('id')+'\')" style="cursor:pointer">'+attValues[j].firstChild.data+'</a>,&nbsp;';
				} else if (attValues[j].getAttribute('primarytree') == 1) {
					tempBuf += 'any <a onclick="getTerm(\''+attValues[j].getAttribute('id')+'\')" style="cursor:pointer">'+attValues[j].firstChild.data+'</a>,&nbsp;';
				} 
			}
			retVal += ':&nbsp;</td><td>'+trimComma(tempBuf)+'</td></tr>';
		} else {
			retVal += '</td><td>&nbsp;</td></tr>';
		}
	}	
	return retVal;
}

function listChildrenRelationshipTypes(relXML) {
	var retVal = new Array();
	for(i=0; i < relXML.length; i++){
		if (relXML[i].firstChild != null) {
			retVal[relXML[i].getAttribute('relationType').toLowerCase()] = true;
		}
	}
	return retVal;
}

/** Returns an array.  The 0 element is the buffer of html for the children / parents
 * Element 1 is an associative array of all the relationship type (true/false for 
 * if they exist).  Element 2 is a boolean indicating if any relations besides synonyms exist 
 * (true if only synonyms or no relationships).
 */
function makeRelationHTML(relXML, noTreeUpdateForSynonyms, isChildren){
	var slots = new Array();
	for(var i=0; i < relXML.length; i++){
		if (relXML[i].firstChild != null){
			var relationType = relXML[i].getAttribute('relationType').toLowerCase();
			if (!(relationType in slots)) {
				slots[relationType] = '';
			}
			
			if (slots[relationType] == 'synonymof' && noTreeUpdateForSynonyms) {
				slots[relationType] += '<a onclick="getTermNoTreeUpdate(\''+relXML[i].getAttribute('id')+'\')" style="cursor:pointer">'+relXML[i].firstChild.data+'</a>,&nbsp;';
			} else {
				slots[relationType] += '<a onclick="setRadlexID(\''+relXML[i].getAttribute('id')+'\')" style="cursor:pointer">'+relXML[i].firstChild.data+'</a>,&nbsp;';
			}	
		}
	}

	// post-process slots to wrap in outer <tr> tags and give it a label
	var labelArray;
	if (isChildren) {
		labelArray = childMapping;
	} else {
		labelArray = parentMapping;
	}

	var retVal = new Array();
	for(var i in slots) {
		retVal[i] = '<tr valign="top"><td nowrap="true">'+labelArray[i]+':</td><td>'+trimComma(slots[i])+'</td></tr>';
	}
	return retVal;
}

function combineRelationships(parents, children){
	var retVal = '';
	for (var i in parentMapping) {
		if (i in parents) {
			retVal += parents[i];
		}
		if (i in children) {
			retVal += children[i];
		}
	}
	return retVal;
}

/* Takes off ",&nbsp;" from the trailing end of a string */
function trimComma(str){
	return str.substr(0,str.length - 7);
}

/*
 * Function: createSlotValue
 * Params:
 *		slot : string of the slot value ID
 *		xmlElem : the xml tag name
 *		rsp : the xml response
 *		createLink : boolean - true makes a hyperlink, needs id attribute in xml
 */
function createSlotValue(xmlElem,rsp,createLink){
	var html = '';
	if (rsp.getElementsByTagName(xmlElem)[0].hasChildNodes()){
		html = rsp.getElementsByTagName(xmlElem)[0].firstChild.data;
		if (createLink){
			var id = rsp.getElementsByTagName(xmlElem)[0].getAttribute('id');
			html = '<a href="'+id+'" style="cursor:pointer">'+html+'</a> ('+id+')';
		}
	}
	return html; 
}