// Author: ckchen@ebi.ac.uk

Ext.namespace('Ontology');

Ontology.Loader = "../images/loading_small.gif";

Ontology.msgs = {'grayout' :  "<div id='termErr'>Sorry, no EMMA strain has this phenotype.<br>" +
                          "Strains are only mapped to non-grayout terms.</div>",
             'notes'   :  "<ul id='ontoNote'><li>Click the tree panel on the left to" + 
	     	              "        dispaly strain(s) having that phenotype</li>" +
                          "    <li>Grayout terms do not have mapping to EMMA strains</li>" +
	                      "    <li>Parent terms also contain strains from offspring(s)</li></ul>",
	         'loader'  : "<div class='onto_loader'><img src=\""+Loader+"\" /><span>loading ...</span></div>",	        
	         'mgiurl'  : "<a target='_blank' href='http://www.informatics.jax.org/searches/accession_report.cgi?id=MGI:",  
	         'mpurl'   : "http://www.informatics.jax.org/searches/Phat.cgi?id=" 
};

Ontology.currTree = [];
Ontology.termSum = [];

function initTree(){
	/*an image to define how an Ext component is drawn. 
	  This is a part of how Ext maintains its
	  cross-browser compatibility.*/
	
	Ext.BLANK_IMAGE_URL = 'http://www.emmanet.org/emmatest/js/extjs/resources/images/default/s.gif';	

    var treeLoader = new Ext.tree.TreeLoader({
                dataUrl:'http://www.emmanet.org/emmatest/ontology/scripts/oboExtJsTreeLoader.php',
                baseParams: {'obo' : 'mp'}
    });     

    var root = new Ext.tree.AsyncTreeNode({
                id:'src',
                expanded: true,
                text: 'mammalian phenotype ontology (MP)',
                draggable: false                
    });

    var p = new Ext.Panel({
    	renderTo: 'tree_strains',
		height: 600,	
		autoWidth: true,
 		layout: 'border',
		hideBorders: false,
		defaults: {
	 	    collapsible: true
		    //bodyStyle: 'padding:5px 5px 0 0'
	 	},
		id: 'ontopanel',	     
    		items: [
			//{title : 'North', region : 'north', height: 0, minSize : 0, maxSize : 50},
			{
			xtype: 'treepanel',
			layout: 'fit',
            useArrows: false,
            autoScroll: true,
			containerScroll: true,
			split: true,
            animate: false,                        
            border: false,
            loader: treeLoader,
            root: root,
            title: 'Mammalian Phenotype Ontology',
        	region: 'west',
        	//margins: '0 0 0 0',
        	width: 350,
        	cmargins: '0 4 0 -1', // adjust top margin when collapsed
        	id: 'west',
 	        listeners: {				
				click: function(node){
					Ext.getDom('strainInfo').innerHTML = Ontology.msgs.loader;

					var idstrs = node.attributes.str_ids.join(",");
				
					var re = /MP:\d+/;
					if ( ! re.exec(node.attributes.text) ){
						Ext.getDom('strainInfo').innerHTML = Ontology.msgs.grayout;
						return;	
					}
				
					Ext.Ajax.request({
					
   						url: fetch_url(),
						method: 'post',
   						success: function(response){
							if (response){
								//console.log(response.responseText);
								Ext.getDom('strainInfo').innerHTML = response.responseText;
								add_cluetip();
							}	
						},
   						failure: function(){alert('AJAX call failed')},
 						disableCachig: true,
   						params: {
   								id_strs: idstrs,
   								mpid: node.attributes.term_id,
   								leaf: node.leaf,
   								nodeId : node.id
							  }
						});
					}				
				}
			},
			{
			xtype: 'panel', 
			layout: 'fit',
			region: 'center',
			title: '',
			collapsible: false,
			items: {
				autoScroll: true,
				autoWidth: true,
				id: 'strainInfo'
				}
			}
		]
    
	});
    
	Ext.getDom('strainInfo').innerHTML = Ontology.msgs.notes;

	//p.render('browse_by_ontology');
}

function fetch_url(){	
	// make sure url is correct for production/test env
	var re = /emmatest/;
	var path = re.exec(window.location) ? "/emmatest/" : "/";
	return "http://www.emmanet.org" + path + "search_browse_emmastr_db.php";	
}

function add_cluetip(){
 // just so that popups for strain desc and table sorting will work
 // after Ext Js ajax response is loaded

 $('.sticky').cluetip({
    activation: 'click',
    sticky: true,
    closePosition: 'title',
    arrows: true,
    width: '750px',   
    onShow: function(ct,c){
	 
	 var sLink = $(this).attr('rel');	
	 var index = sLink.indexOf('=');
	 var idstr = sLink.substr(index+1);

	 // use this height to determine the height of the phenotype panel
	 var ontoHeight = $('#desc_general').height();
	 
	 var t= $('#strainDescTabs').tabs();//{
         //  selected: 1,
         //  cache   : true
         // });
	
	 initOntologyDesc(ontoHeight, idstr);
   	 t.tabs('select', 0);   
    } 	
  });
     
  $('#cluetip-inner').css('background-color', 'white');
  
  // so that the table rows of the newly added tab
  // will be striped on load
  $('table.searchDb tbody tr:odd').addClass('odd');
 
  $('table.tablesorter').tablesorter({
    sortList: [[1,0]],
    widgets: ['zebra']
  });
}

function initAutocomplete(){

	// src: http://docs.jquery.com/Plugins/Autocomplete/autocomplete

	var url = fetch_url();
	
	// test 
	//var data = "Something here for testing autocompleter".split(" ");
	$("#auto_term").autocomplete(url, 
			{minChars: 3,
        	 scroll: true,
        	 lineSeparator: "\n",
		 highlight: function(match, keywords) {
        		keywords = keywords.split(' ').join('|');
        		return match.replace(new RegExp("("+keywords+")", "gi"),'<b class="srchHighlight">$1</b>');
    		}

			});

	$('#auto_term').result(function(event, data, formatted) {		
		//console.log("Got input: " + formatted);
		var q_url = url + "?term_name=" + formatted;
		//console.log( !data ? "No match!" : "Selected: " + formatted);

 		$.get(q_url, function(data){
 			var re = /^Sorry/;
 			if ( re.exec(data) ){
 				$('#strainInfo').html("<div id='termErr'>" + data + "</div>");	
 			}
 			else {
 				$('#strainInfo').html(data);
 			}
		});	
	});

}

function initOntologyDesc(oht, idstr){

	Ontology.panelHeight = oht;
		
	Ext.Ajax.request({		
		url: fetch_url(),
		method: 'GET',
		success: function(response){
			if (response){
				// expecting a json of alleles (keys: id, symbol)	
				//console.info("RES: " + response.responseText);
				var aAllele_infos = Ext.util.JSON.decode(response.responseText);				

				if ( aAllele_infos.length < 1 ){
					return;
				}	
				
				// note: tabs are created only when there is > 1 alleles				
				if ( aAllele_infos.length > 1 ){
					make_ajax_tabs(aAllele_infos, oht, idstr);								
				}
				else {					
					display_in_panel(oht, idstr, aAllele_infos); 	
				}	
			}			
		},
		failure: function(){alert('AJAX call failed')},
		disableCachig: true,
		params: { 'idstrAllele': idstr }	
	});	
}
function display_in_panel(oht, idstr, aAllele_infos){
	$.get(fetch_url(), {mp_idstr: idstr, mp_id_allele: aAllele_infos[0].id}, function(data){

		$('#desc_ontology').html(data);		
		tabid = 0; // default
		var id = 'div#mpterms' + tabid + " div[id^=group]";

		Ontology.panelHeight = oht;
		Ontology.tabid = 0;
		Ontology.termListWidth = '44%';
		Ontology.infoHeight = oht - 45;

		adding_gui_effects(id, 'panel'); // ie, show/hide when onclick
	});
}

function adding_gui_effects(id, mode){

	$(id).each(function(){
		$(this).click(function(){	
			if ( $(this).attr('class') == 'termGroupIconPlus'){
				$(this).removeClass();				
				$(this).addClass('termGroupIconMinus');								
 			}
			else {
				$(this).removeClass();
				$(this).addClass('termGroupIconPlus');
			}
			$(this).next().toggle();
		});	
	});

	var oht = Ontology.panelHeight;	
	var tabid = Ontology.tabid;
	var termListWidth = Ontology.termListWidth;
	var infoHeight = Ontology.infoHeight;

	if ( mode == 'panel' ){
		var termListHeight = oht-3;
		$('#desc_ontology').css({'height': parseInt(oht)  +'px'});
		$('div.mpterms').css({'height': parseInt(termListHeight)  +'px', 
				      'width': Ontology.termListWidth, 
				      'overflow':'auto'});
	}
	else {
		// ie, mode == 'tabs'
		var termListHeight = oht-46; 
		$('#phenoTabs').css({'height': oht-7 +'px'});
		$('div#mpterms'+tabid).css({'height': termListHeight +'px', 'width': '44%', 'overflow':'auto'});
	}	
	$('div#onto_term_info'+tabid).css('height', parseInt(infoHeight) + 'px'); 

	$('.listBox li a').click(function(){
			
			$('#partialTree'+tabid).addClass('partialTreePlus');
			
			$('.listBox li a').each(function(){
				$(this).css({'font-weight':'normal'});
			});
			$(this).css({'font-weight':'bold', 'text-decoration':'none'});
			
			var oAllele_infos = Ext.util.JSON.decode($(this).attr('data'));	
			fetch_term_info_and_hierarchy(oAllele_infos);
			
			return false; // don't want to follow the link
	});
	resize_onto_desc();		
}

function resize_onto_desc(){
        var tabid = Ontology.tabid;

        $('div#term_info_header' + tabid).click(function(){
                if ( $('div#mpterms' + tabid).css('display') == 'block'){
                        $('div#mpterms' + tabid).css({'display': 'none'});
                        $('div#infoTreeWrapper' + tabid).css({'width': '100%'}); 
                        $(this).removeClass();
                        $(this).addClass('header_expand');
                }
                else {
                        $('div#infoTreeWrapper' + tabid).css({'width': '55%'});
                        $('div#mpterms' + tabid).css({'display': 'block'});
                        $(this).removeClass();
                        $(this).addClass('header_collapse');
                }
        });
}

function make_ajax_tabs(aAllele_infos, oht, idstr){	

	var html = "<div id='phenoTabs'><ul>";
	var url = fetch_url();
	//var target = "<div id='phenoContent'></div>";
	for(var i=0; i<aAllele_infos.length; i++){	
		
		var title = aAllele_infos[i].symbol;
		
		html += "<li><a href='" + url + '?mp_idstr=' + idstr 
		                       + '&mp_id_allele=' + aAllele_infos[i].id
		                       + '&tab=' + i
	                           + "'>" + title + "</a></li>";
	}  
	html += "</ul>" +  "</div>";	
	
	$('#desc_ontology').html(html);	
	
	// all tabs content goes to #phenoTabs
	$('#phenoTabs').tabs({
        selected: 0,
        cache   : true,
        spinner : 'Loading ...',
        load: function(event, ui) { 
			add_js_css_for_phenoTabs(oht);
		},
		select: function(event, ui){
			//console.log('index: '+ ui.index);
			Ontology.selTab = ui.index;
		}
	});		
}

function add_js_css_for_phenoTabs(oht){
	
	var tabid = Ontology.selTab || 0;	
	var id = 'div#mpterms' + tabid + " div[id^=group]";

	Ontology.panelHeight = oht;
	Ontology.tabid = tabid;
	Ontology.termListWidth = '44%';
	Ontology.infoHeight = oht - 85;

	adding_gui_effects(id, 'tabs'); // ie, show/hide when onclick
}

function fetch_term_info_and_hierarchy(oAllele_infos){
	
	Ext.Ajax.request({		
		url: fetch_url(),
		method: 'GET',
		success: function(response){
			if (response){
				//console.log(response.responseText);
				oRes = Ext.util.JSON.decode(response.responseText);
				
				var mpurl = Ontology.msgs.mpurl + oAllele_infos.mpid;
				var mpurl = "<a target='_blank' href='" + mpurl + "'>" + 'MP ontology: ' + oAllele_infos.mpid + "</a>";
				var infos = '';
				infos += format_term_data('Definition', oRes.terminfo.def);				
				infos += format_term_data('Hierarchy', mpurl);
				
				var composition_bg = parse_allele_genotype(oAllele_infos);				
							
				var allele_info = '<table class="alleleList">' +								
									composition_bg + 							  	 
									format_allele_info('MGI ID', oAllele_infos.mgi_id, Ontology.msgs.mgiurl ) +
								  '</table>';
				
				infos += format_term_data('Genotype', allele_info);  
					
				if ( oRes.terminfo.alt_id ){
					infos += format_term_data('Alternative Terms', oRes.terminfo.alt_id.join(', ')); 
				}
				if ( sComment = oRes.terminfo.comment ){
					infos += format_term_data('Comments', sComment); 
				}
				if ( sIs_obsolete = oRes.terminfo.is_obsolete ){
					infos += format_term_data('Is obsolete', sIs_obsolete); 
				}
				if ( aSyn = oRes.terminfo.synonym ){					
					var syn = '<table class="alleleList">' +
								parse_synonym(aSyn) + 
							  '</table>';
					infos += format_term_data('Synonyms', syn);					
				}
				
				var tabid = oAllele_infos.tab;
			
				$('#onto_term_info' + tabid).html(infos);											
			}	
		},
		failure: function(){alert('AJAX call failed')},
		disableCachig: true,
		params: { 'node_id': oAllele_infos.node_id, 
				  'twoUps_id': oAllele_infos.two_ups_node_id				 
		}		
	});	
}

function parse_synonym(aSyn){

	var caption = "<tr><td class='field'>Name</td><td class='field col2'>Type</td></tr>";
	var data = caption;	
	for (var i=0; i<aSyn.length; i++){
		data += "<tr><td>" + aSyn[i].syn_name + '</td>'  
		      + '<td class="col2">' + aSyn[i].syn_type + '</td></tr>';		
	}
	return data;	
}

function parse_allele_genotype(aInfoList){
	
	var comp = aInfoList.composition;
	var bg = aInfoList.background;
	
	var caption = "<tr><td class='field'>Composition</td><td class='field col2'>Background</td></tr>";
	var data = caption;		
	for(var i=0; i<comp.length;  i++){
		data += "<tr><td>" + comp[i] + '</td><td class="col2">' + bg[i] + '</td></tr>';
	}		
	return data;		
}

function format_allele_info(field, data, link){
	if ( link && typeof data == 'string') {
		data = link + data + "'>" + data + "</a>";
	}
	return "<tr><td class='field'>" + field + "</td><td class='col2'>" + data + "</td></tr>";	
}

function format_term_data(header, info){
	return "<fieldset class='termfset'><legend>"+ header + "</legend>" + info + "</fieldset>";
}

