//globals =================
var genGridTopicRecord;
var propGridTopicRecord;
var clsGridTopicRecord;
var passed_pid;
//=========================

Ext.onReady(function(){
    var clusters_rendered = false;
    var loader = new Ext.tree.TreeLoader({dataUrl:LEVEL.servletTreeURL});
    var root = new Ext.tree.AsyncTreeNode({
    	expanded: true,
        text: 'root', 
        id:'source'
    });
    
    var clickListener = function(n) {
      	if (  (typeof n.attributes.leaf) == 'undefined'  )
      		return;
    	var col = centerPanel.items;
		col.each(function(item,index,length) {
			if( item.id=='comp_cl_genomes' || item.id=='comp_cl_properties') {
				var level;
				if( item.id == 'comp_cl_genomes' ) {
					level = LEVEL.CLUSTER_GENOMES;
				} else {
				 	level = LEVEL.CLUSTER_PROPERTIES;
				} 
				showGenomes(n.attributes,level);
				item.setVisible(true);
			} else 
				item.setVisible(false);
		})
    };
    
    // tree panel
    var treePanel = new Ext.tree.TreePanel({
    	region: 'west',
        collapsible: true,
        title:'Taxon Explorer',
        width: 300,
        minSize: 260,
        maxSize: 400,
        autoScroll: true,
        split: true,
        loader: loader,
        root: root,
        rootVisible: false,
        id : 'phyloTree',
        listeners: {
            click: clickListener
        }
    });
        
    var updatePanel = function(url){
    	var col = centerPanel.items;
    	col.each(function(item,index,length){
    		if(item.id == 'comp_my_text') {
    			item.setVisible(true);
    			item.getUpdater().update(url);
    		}
    		else 
    			item.setVisible(false);
    	})
    };
    
 	var toolBar = ['->',
    	{
    	text: 'Home',
       	handler: function(){
       			updatePanel('home.html');
       		}
   		}, 
   		{
       	text: 'Cluster List',
       	handler: function(){
       		var col = centerPanel.items;
    		col.each(function(item,index,length){
    		if(item.id == 'comp_cl_list') {
    			if ( !clusters_rendered ) {
    				showClusters();
					clusters_rendered = true;
				} else {
					var grid = Ext.getCmp("clustersGridId");
					grid.getSelectionModel().clearSelections();
				}   			
    			item.setVisible(true);
    		}
    		else 
    			item.setVisible(false);
    		})
	       }
   		},
   		{
   		text: 'Statistics',
       	handler: function(){
       			updatePanel('statistics.html');
	        }
   		},
   		{
   		text: 'Help',
       	handler: function(){
       			updatePanel('help.html');
	        }
   		}
     ];
   
 	  var bodyStyle = "padding:15px;";
 	  var bodyTableStyle = "padding-left:10px;padding-top:10px;";
 	  
 	  var centerPanel = new Ext.Panel({ // raw
        region:'center',
        items: [
    		{
    		id:'comp_my_text',
    		bodyStyle: bodyStyle,
    		contentEl:'my_text'
    		},
    		{
    		id:'comp_cl_list',
    		bodyStyle: bodyTableStyle,
    		baseCls:'x-plain',
    		contentEl:'cl_list'
    		},
    		{
         	id:'comp_cl_genomes',
         	bodyStyle: bodyTableStyle,
         	baseCls:'x-plain',
         	contentEl:'cl_genomes'
      		},
      		{
	        id:'comp_cl_properties',
	        bodyStyle: bodyTableStyle,
	        baseCls:'x-plain',
	        contentEl:'cl_properties'
      		}
    	],
        autoScroll: true, 
        tbar: toolBar
    	});
         	
     var viewport = new Ext.Viewport({
            layout:'border',
            items:[
            	new Ext.BoxComponent({ // raw
                    region:'north',
                    el: 'north'
                }),
             	treePanel,
             	centerPanel
             	
             ]
        });
      	updatePanel('home.html');
    
    	//fetch and display Refseq version
    	Ext.Ajax.request({
   			url: LEVEL.servletTableURL,
   		method: 'GET',
   		success: function(req, options) 
   		{ 
   			var info = eval("(" + req.responseText + ")");
   			var refseqEl = Ext.get("refseq");
   			refseqEl.update("Based on RefSeq " + info['RefSeq.description']);
   			var versionEl = Ext.get("atgc_version");
   			versionEl.update(ATGC.Version);
		},
  		 params: { level: LEVEL.INFO }
	});
});



function createGenomesGrid(cold) {	
	var xg = Ext.grid;
	var cm;
	var ds;
	var cols = [];
	var schema = [];
	var grid;
	var dest;
	var sm;
	
	var getSelectedGenomes = function(){
		var rs = sm.getSelections();
		var ids = [];	
		var sc = sm.getCount();
		for (var i=0; i< sc; i++) {
			var idx = rs[i].get('order')-1; 
			ids.push( idx );
		}
		var  genomes = ids[0];
		for ( var ii=1; ii<ids.length; ii++ ){
			genomes += ','+ids[ii];
		}
		return genomes;
	}
	
	var clickHandler = function(item, e) {
		e.stopEvent();
		var href = item.href + "&genomes="+getSelectedGenomes() + 
			"&phylonode_id=" + passed_pid;
		window.open(href, '_blank');
	}
	
		
	var onSelectionChange = function(selMod) {
		var selCount = selMod.getCount(); 
		if ( selCount==0 ) {
			menuDownload.items.each(function(item,i,l){
				if (i==0) 
					item.setVisible(true);
				else 
					item.disable();
			});
		} else {
			menuDownload.items.each(function(item,i,l){
				if (i==0)
					item.setVisible(false);
				else
					item.enable();
			});
		};
	}
	sm = new xg.CheckboxSelectionModel();
	sm.on({
  		'selectionchange' : {
      		fn: onSelectionChange 
      		}
	});
	cols.push(sm);
	dest = Ext.get('cl_genomes');

	
	create_schema(cold, ATGC.menuDisable, schema, cols);
	//place check box into the second column
	var tmp = cols[0];
	cols[0] = cols[1];
	cols[1] = tmp;

	cm = new Ext.grid.ColumnModel(cols);
	genGridTopicRecord =  Ext.data.Record.create(schema);
	var ar = new Ext.data.ArrayReader({}, genGridTopicRecord);
	var proxy = new Ext.data.MemoryProxy([]); 
	// create the Data Store
	ds = new Ext.data.Store({
		proxy: proxy,
		reader: ar
	});
	
	
	
	var href = LEVEL.servletTableURL + "?";
	var hrefs = ["", 
		href + "&level=" + LEVEL.MULTIPLE_ORFS_GENEIDS,	
		href + "&level=" + LEVEL.MULTIPLE_ORFS, 
		href + "&level=" + LEVEL.ORTHOLOGOUS_PROTEINS,
		href + "&level=" + LEVEL.DNMATRIX,
		href + "&level=" + LEVEL.DSMATRIX
		];

    var menuDownload = new Ext.menu.Menu({
       id: 'mainMenu',
       items: [
           {text: '<html><span  class="warning">Please select genomes for download</span></html>'
           },
           {text: 'Protein GIs for orthologous ORFs'
           },
           {text: 'Multiple alignment of orthologous ORFs'
           },
           {text: 'Multiple alignment of orthologous proteins'
           },
		{text: 'Matrix of pair wise genome distances (median of dN)'
		},
		{text: 'Matrix of pair wise genome distances (median of dS)'
		}
         ]});
    menuDownload.items.each(function(item,i,l){
			if (i!=0) {
				item.disable();
				item.on('click', clickHandler);
				item.href = hrefs[i];
			}
		});
       
    
    var menuColumns = createMenuColumns(cm);

	grid = new xg.GridPanel({
		id: "genomesGridId",
		store: ds,
		frame: false,
		cm: cm,
		sm: sm,
		loadMask: true,
		width:800,
       	height:350,
		// inline toolbars
		tbar:[
			{
        	text:'<html><span style="color:red;">' + ATGC.DownloadTitle + '</span></html>',
            menu: menuDownload ,
            iconCls:'download' 
            },
            {
            text:'<html><span style="color:red;">' + ATGC.ColumnsTitle + '</span></html>',
            iconCls:'columns',
            menu: menuColumns
            },
            '->',
            {
            text:'<html>Link legends: ' +
            	'<span class="VistaLink">V - </span>Vista genome browser' + 
            	'<span class="NCBILink">&nbsp;&nbsp;T - </span>NCBI taxonomy' +
            	'<span class="IMGLink">&nbsp;&nbsp;I - </span>IMG' +
            	'<span class="MOLLink">&nbsp;&nbsp;M - </span>MicrobesOnline' +
            	'</html>'
            }
              ], 
		title:"Cluster Genomes",
		renderTo: dest
		}); 
	
	
	return grid;	
}	

function createPropertiesGrid(cold) {
	var xg = Ext.grid;
	var cm;
	var ds;
	var cols = [];
	var schema = [];
	var grid;
	var dest;
	//var cold = data.columns;
	
	sm = new Ext.grid.RowSelectionModel();
	dest = Ext.get('cl_properties');
	
	create_schema(cold, ATGC.menuDisable, schema, cols);
	cm = new Ext.grid.ColumnModel(cols);
	propGridTopicRecord =  Ext.data.Record.create(schema);
	var ar = new Ext.data.ArrayReader({},
		//schema); 
		propGridTopicRecord);
	var proxy = new Ext.data.MemoryProxy([]); 
	// create the Data Store
	ds = new Ext.data.Store({
		proxy: proxy,
		reader: ar
	});
	
	grid = new xg.GridPanel({
		id: "propertiesGridId",
		title:'Cluster properties',
		hideHeaders: true, 
		store: ds,
		frame:false,
		cm: cm,
		sm: sm,
		loadMask: true,
		width:800,
       	height:150,
		renderTo: dest
		});
	return grid;
}

function showGenomes(attributes, level) {
	var phylonode_id = attributes.id;
	var label = attributes.text.substr(0, attributes.text.indexOf('['));
	this.init = function(data, params) {
		this.passed_pid = params.phylonode_id;
		var level = params.level;
		var grid;
		var TopicRecord;
		var cold = data.columns;
		if (level == LEVEL.CLUSTER_GENOMES) {
			grid = Ext.getCmp("genomesGridId");
			if ( (typeof grid)== 'undefined' )
				grid =createGenomesGrid(cold);
			grid.setTitle( "<html><span style=\"font-size: larger;\">" + label + "</html>" );
			TopicRecord = genGridTopicRecord;
		} else {
			grid = Ext.getCmp("propertiesGridId");
			if ( (typeof grid)== 'undefined' )
				grid = createPropertiesGrid(cold);
			TopicRecord = propGridTopicRecord;
		}
		
		var ds = grid.getStore();
		ds.removeAll();
		ds.load();
		for (var i=0; i < data.rows.length; i++) {
            ds.add(new TopicRecord(data.rows[i]));
        }
	};
	
	
	Ext.Ajax.request({
   		url: LEVEL.servletTableURL,
   		method: 'GET',
   		success: function(req, options) 
   		{ 
   			var data = eval("(" + req.responseText + ")");
			this.init(data, options.params);
		},
  		 params: { level: level, phylonode_id: phylonode_id }
	});
	
}

function createClustersGrid(cold) {
	var onRowSelect = function(selModel, rowIndex, record) {
		var pid = record.data.phylonode_id;
		var tree = Ext.getCmp('phyloTree');
		var node = tree.getNodeById(pid);
		tree.collapseAll();
		tree.selectPath(node.getPath());
		tree.fireEvent('click', node);
	}
	   
	var sm = new Ext.grid.RowSelectionModel();
       sm.on({
 			'rowselect' : {
     			fn: onRowSelect
     		}
	});
	// create the columns
	var cols = [];
	var schema = [];
	create_schema(cold, ATGC.menuEnable, schema, cols);
	var cm = new Ext.grid.ColumnModel(cols);
	cm.defaultSortable = true;
	clsGridTopicRecord =  Ext.data.Record.create(schema);
	var ar = new Ext.data.ArrayReader({},clsGridTopicRecord);
	var proxy = new Ext.data.MemoryProxy([]); 
	Ext.menu.RangeMenu.prototype.icons = {
  		gt: 'Ext/grid-filtering/img/greater_then.png', 
  		lt: 'Ext/grid-filtering/img/less_then.png',
  		eq: 'Ext/grid-filtering/img/equals.png'
	};
	Ext.grid.filter.StringFilter.prototype.icon = 'Ext/grid-filtering/img/find.png';
	// create the Data Store
	var ds = new Ext.data.Store({
		proxy: proxy,
		reader: ar
	});
	
	var fValues = [];
	fValues[0] = {type: 'string',  dataIndex: cols[0].dataIndex};
	for (var i = 1 ; i < cold.length; i++){
		fValues[i] = {type: 'numeric',  dataIndex: cols[i].dataIndex};
	}
	
	var filters = new Ext.grid.GridFilters({
	  filters: fValues });
	
	
	
	var menuColumns = createMenuColumns(cm);
       
	var grid = new Ext.grid.GridPanel({
		id: "clustersGridId",
		store: ds,
		frame: false,
		cm: cm,
		sm: sm,
		loadMask: true,
		width: 800,
		height: 450,
		tbar:[{
        	text:'<html><span style="color:red;">' + ATGC.ColumnsTitle + '</span></html>',
        	iconCls:'columns',
            menu: menuColumns
        }],
		plugins: filters,
		title:'Clusters properties',
		renderTo: Ext.get('cl_list')
	});
	return grid;
}

function showClusters() {
	Ext.Ajax.request({
   		url: LEVEL.servletTableURL,
   		method: 'GET',
   		success: function(req, options) 
   		{ 
   			var data = eval("(" + req.responseText + ")");
			this.init(data);
		},
  		 params: { level: LEVEL.TOP, phylonode_id: -1 }
	});
	this.init = function(data) {
		var grid = createClustersGrid(data.columns);
		var ds = grid.getStore();
		ds.removeAll();	
		ds.load();
		for (var i=0; i < data.rows.length; i++) {
            ds.add(new clsGridTopicRecord(data.rows[i]));
        }
	};
};

function createMenuColumns(cm){
	
	var menuColumns = new Ext.menu.Menu({
        id: 'menuColumns',
        items: []});
    var menuColumnsCheckHandler = function(item, checked) {
		cm.setHidden(item.id ,!checked);
	};
    
	for(var i = 0; i < cm.getColumnCount(); i++) {
			var colHeader = cm.getColumnHeader(i);
			if (colHeader.substr(0,4)=="<div" || colHeader=="Order")
				continue;
			var menuItem = new Ext.menu.CheckItem({ id: i, text: colHeader, checked: !cm.isHidden(i) });
			menuItem.on('checkchange', menuColumnsCheckHandler);
			menuColumns.add(menuItem);
		};
	return menuColumns;
}

function create_schema(cold, isMenuDisable, schema, cols) {
	for (var i = 0 ; i < cold.length; i++){
		var col = {menuDisabled : isMenuDisable};
		// auto set the index if not specfied.
		if (!cold[i].id) 
			col.dataIndex = i + "";
		else 
			col.dataIndex = cold[i].id;
		
		var arg = {name : col.dataIndex};
		
		if (cold[i].type) {
			arg.type =  cold[i].type;
			// default the date format if not specified
			if (arg.type = 'date') {
				if (cold[i].dateFormat)
					arg.dateType = cold[i].dateFormat;
				else 
					arg.dateType = 'n/j h:ia';
			}
		}
		
		schema.push(arg);
		// mix in everything but the renderer and editor
		for (var ii in cold[i]) {
			if (ii == 'label') {    
				col.header = cold[i].label; 
			} else {
				col[ii] = cold[i][ii];
			}
		}
		
		/*if ( (typeof col.sortable) == 'undefined' ) 
			col.sortable = true;*/
		
		cols.push(col);
	} 
}
	

