/**
 * Class for generating a basic grid to show SUBA results.
 * - result paging (server-side)
 * - result sorting (server-side)
 * - single selection model
 * - all the usual grid functionality such as column hiding and repositioning
 * - not resizable, not framed, designed to be rendered in the specified element (at construction)
 * - provides hooks for external application to control data content
 * - created once on page load
 */
var suba_grid = function(params) {

    Ext.QuickTips.init();
	
	//Enable to allow state memory of table settings (hidden columns etc) via a cookie
    //Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

	var self = this;
	var grid = null;
	var pkey = null;
	var model = null;
	var store = null;
	
	//Initialize with user parameters
	Ext.apply(this, params, {
		url   : '',
		db    : '',
		table : '',
		pagesize : 5,
		where : '',
		applyTo : '',
		height:600,
		width:800,
		where:'',
		callback:null
	});
	
	//Render pubmed links correctly
	function render_pubmed(value) {
		if (!value) return;

		var calls = value.split(';');
		var html = '';
		
		for (var i=0; i<calls.length; i++) {
			var parts = calls[i].split(':');
			html += parts[0] + ": <a target='new' href='http://www.ncbi.nlm.nih.gov/sites/entrez?cmd=search&db=pubmed&term=" + parts[1] + "'>" + parts[1] + "</a><br />";				
		}
		return html;
	}
	
	//Render the agi
	function render_agi(value) {
		if (!value) return;
		//return "<a target='new' href='http://suba.plantenergy.uwa.edu.au/flatfile.php?id=" + value + "'>" + value + "</a>";
		return "<a target='new' href='/flatfile.php?id=" + value + "'>" + value + "</a>";
	}
	
	//Render locations
	function render_location(value) {
		if (!value) return;

		var locs = value.split(',');
		var html = '';
		
		for (var i=0; i<locs.length; i++) {
			html += locs[i] + '<br />';
		}
		return html;
	}
	
	//Render blocks of text
	function render_text(value) {
		if (!value) return;
		return "<div style='width:100%; position:relative; white-space:normal!important;'>"+value+"</div>"
	}
	
	//Build components
	function initialize(schema) {

		//Determine the primary key
		pkey = schema.PKEY;
		
		//Build the column model
		model = MySQL.get_column_model(schema);
		
		//Add custom renderers to the column model
		model.setRenderer(model.getIndexById('locus'), render_agi);
		model.setRenderer(model.getIndexById('description'), render_text);		
		model.setRenderer(model.getIndexById('location_targetp'), render_location);
		model.setRenderer(model.getIndexById('location_mitoprot2'), render_location);
		model.setRenderer(model.getIndexById('location_subloc'), render_location);
		model.setRenderer(model.getIndexById('location_ipsort'), render_location);
		model.setRenderer(model.getIndexById('location_predotar'), render_location);
		model.setRenderer(model.getIndexById('location_mitopred'), render_location);
		model.setRenderer(model.getIndexById('location_peroxp'), render_location);
		model.setRenderer(model.getIndexById('location_wolfpsort'), render_location);
		model.setRenderer(model.getIndexById('location_multiloc'), render_location);
		model.setRenderer(model.getIndexById('location_loctree'), render_location);
		model.setRenderer(model.getIndexById('location_all_predictors'), render_location);

		model.setRenderer(model.getIndexById('location_ms'), render_pubmed);
		model.setRenderer(model.getIndexById('location_gfp'), render_pubmed);
		model.setRenderer(model.getIndexById('location_name'), render_pubmed);
		model.setRenderer(model.getIndexById('location_amigo'), render_pubmed);
		model.setRenderer(model.getIndexById('location_swissprot'), render_pubmed);
		
		//Define the default hidden state for columns
		for (var i=0, length=model.getColumnCount(); i<length; i++) {
			model.setHidden(i, true);
		}
		model.setHidden(model.getIndexById('locus'), false);
		model.setHidden(model.getIndexById('description'), false);
		model.setHidden(model.getIndexById('location_ms'), false);
		model.setHidden(model.getIndexById('location_gfp'), false);
		model.setHidden(model.getIndexById('location_swissprot'), false);
		model.setHidden(model.getIndexById('location_amigo'), false);
		model.setHidden(model.getIndexById('location_name'), false);
		model.setHidden(model.getIndexById('location_all_predictors'), false);
		
		//Set improved headers
		model.setColumnHeader(model.getIndexById('locus'), 'AGI');
		model.setColumnHeader(model.getIndexById('chr'), 'Chromosome');
		model.setColumnHeader(model.getIndexById('names'), 'Gene Names');
		model.setColumnHeader(model.getIndexById('description'), 'TAIR Description');
		model.setColumnHeader(model.getIndexById('comment'), 'Lab Comment');
		model.setColumnHeader(model.getIndexById('ests'), 'Num ESTs');
		model.setColumnHeader(model.getIndexById('flcdnas'), 'Num fl-cDNAs');
		model.setColumnHeader(model.getIndexById('residues'), 'Length');
		model.setColumnHeader(model.getIndexById('mwt'), 'MWt');
		model.setColumnHeader(model.getIndexById('pi'), 'IEP');
		model.setColumnHeader(model.getIndexById('gravy'), 'GRAVY');
		model.setColumnHeader(model.getIndexById('location_targetp'), 'TargetP');
		model.setColumnHeader(model.getIndexById('location_mitoprot2'), 'Mitoprot2');
		model.setColumnHeader(model.getIndexById('location_subloc'), 'SubLoc');
		model.setColumnHeader(model.getIndexById('location_ipsort'), 'iPSORT');
		model.setColumnHeader(model.getIndexById('location_predotar'), 'Predotar');
		model.setColumnHeader(model.getIndexById('location_mitopred'), 'MitoPred');
		model.setColumnHeader(model.getIndexById('location_peroxp'), 'PeroxP');
		model.setColumnHeader(model.getIndexById('location_wolfpsort'), 'WoLFPSORT');
		model.setColumnHeader(model.getIndexById('location_multiloc'), 'MultiLoc');
		model.setColumnHeader(model.getIndexById('location_loctree'), 'LOCtree');
		model.setColumnHeader(model.getIndexById('location_all_predictors'), 'All Predictors');
		model.setColumnHeader(model.getIndexById('location_ms'), 'Mass Spec');
		model.setColumnHeader(model.getIndexById('location_gfp'), 'GFP');
		model.setColumnHeader(model.getIndexById('location_name'), 'TAIR');
		model.setColumnHeader(model.getIndexById('location_amigo'), 'AmiGO');
		model.setColumnHeader(model.getIndexById('location_swissprot'), 'UniProt');

		//Set tooltips
		model.setColumnTooltip(model.getIndexById('locus'), '<i>Arabidopsis</i> Gene Identifier');
		model.setColumnTooltip(model.getIndexById('chr'), 'Chromosome');
		model.setColumnTooltip(model.getIndexById('names'), 'Gene Names');
		model.setColumnTooltip(model.getIndexById('description'), 'TAIR Description');
		model.setColumnTooltip(model.getIndexById('comment'), 'Lab Comment');
		model.setColumnTooltip(model.getIndexById('ests'), 'Number of supporting ESTs (TAIR)');
		model.setColumnTooltip(model.getIndexById('flcdnas'), 'Number of supporting fl-cDNAs (TAIR)');
		model.setColumnTooltip(model.getIndexById('residues'), 'Number of amino acids');
		model.setColumnTooltip(model.getIndexById('mwt'), 'Molecular weight');
		model.setColumnTooltip(model.getIndexById('pi'), 'Isoelectric point (computed)');
		model.setColumnTooltip(model.getIndexById('gravy'), 'GRAVY');
		model.setColumnTooltip(model.getIndexById('location_targetp'), 'Localisation prediction(s) by TargetP');
		model.setColumnTooltip(model.getIndexById('location_mitoprot2'), 'Localisation prediction(s) by Mitoprot2');
		model.setColumnTooltip(model.getIndexById('location_subloc'), 'Localisation prediction(s) by SubLoc');
		model.setColumnTooltip(model.getIndexById('location_ipsort'), 'Localisation prediction(s) by iPSORT');
		model.setColumnTooltip(model.getIndexById('location_predotar'), 'Localisation prediction(s) by Predotar');
		model.setColumnTooltip(model.getIndexById('location_mitopred'), 'Localisation prediction(s) by MitoPred');
		model.setColumnTooltip(model.getIndexById('location_peroxp'), 'Localisation prediction(s) by PeroxP');
		model.setColumnTooltip(model.getIndexById('location_wolfpsort'), 'Localisation prediction(s) by WoLFPSORT');
		model.setColumnTooltip(model.getIndexById('location_multiloc'), 'Localisation prediction(s) by MultiLoc');
		model.setColumnTooltip(model.getIndexById('location_loctree'), 'Localisation prediction(s) by LOCtree');
		model.setColumnTooltip(model.getIndexById('location_all_predictors'), 'Localisation prediction(s) by all Predictors');
		model.setColumnTooltip(model.getIndexById('location_ms'), 'Localisation determined by mass spectrometric assay');
		model.setColumnTooltip(model.getIndexById('location_gfp'), 'Localisation determined by green fluorescent protein assay');
		model.setColumnTooltip(model.getIndexById('location_name'), 'Localisation according to TAIR annotation');
		model.setColumnTooltip(model.getIndexById('location_amigo'), 'Localisation according to AmiGO annotation');
		model.setColumnTooltip(model.getIndexById('location_swissprot'), 'Localisation according to UniProt annotation');
		
		//Set default column widths
		model.setColumnWidth(model.getIndexById('locus'), 80);
		model.setColumnWidth(model.getIndexById('chr'), 10);
		model.setColumnWidth(model.getIndexById('names'), 100);
		model.setColumnWidth(model.getIndexById('description'), 170);
		model.setColumnWidth(model.getIndexById('comment'), 80);
		model.setColumnWidth(model.getIndexById('ests'), 20);
		model.setColumnWidth(model.getIndexById('flcdnas'), 20);
		model.setColumnWidth(model.getIndexById('residues'), 30);
		model.setColumnWidth(model.getIndexById('mwt'), 60);
		model.setColumnWidth(model.getIndexById('pi'), 60);
		model.setColumnWidth(model.getIndexById('gravy'), 60);
		model.setColumnWidth(model.getIndexById('location_targetp'), 120);
		model.setColumnWidth(model.getIndexById('location_mitoprot2'), 120);
		model.setColumnWidth(model.getIndexById('location_subloc'), 120);
		model.setColumnWidth(model.getIndexById('location_ipsort'), 120);
		model.setColumnWidth(model.getIndexById('location_predotar'), 120);
		model.setColumnWidth(model.getIndexById('location_mitopred'), 120);
		model.setColumnWidth(model.getIndexById('location_peroxp'), 120);
		model.setColumnWidth(model.getIndexById('location_wolfpsort'), 120);
		model.setColumnWidth(model.getIndexById('location_multiloc'), 120);
		model.setColumnWidth(model.getIndexById('location_loctree'), 120);
		model.setColumnWidth(model.getIndexById('location_all_predictors'), 120);
		model.setColumnWidth(model.getIndexById('location_ms'), 120);
		model.setColumnWidth(model.getIndexById('location_gfp'), 120);
		model.setColumnWidth(model.getIndexById('location_name'), 120);
		model.setColumnWidth(model.getIndexById('location_amigo'), 120);
		model.setColumnWidth(model.getIndexById('location_swissprot'), 120);
				
		//Build data store
		store = MySQL.get_store(schema, self.url);
										
		//Render the grid when it has been parameterised
		store.on('load', build_grid);
		
		build_grid();
		//Load table data
		/*store.load({
			params : {
				db : self.db,
				table : self.table,
				action : 'db_multiple_select',
				start : 0,
				limit : self.pagesize
			}
		});*/
	}

	//Create the grid component (renders in the element named during parameterization)
	function build_grid() {		
		
		//If the grid already exists then do nothing
		if (grid) {
			grid.enable();
			if (self.callback) self.callback();
			return;
		}

	    // create the editor grid
	    grid = new Ext.grid.GridPanel({
			ds: store,
			cm: model,
			//title: 'Table: ' + self.db + '.' + self.table,
			frame:false,
			width:self.width,
			height:self.height,
			trackMouseOver : true, //highlights rows as the mouse moves
			loadMask: true, //fades grid when loading
			border : false,
			stripeRows:true,
			renderTo:self.renderTo || document.body,
			tbar:[
				{
					text:'Download All Results',
					tooltip:'Download data in the record set',
					iconCls:'download',
					handler: download
				}
			],
			bbar: new Ext.PagingToolbar({
				pageSize: self.pagesize,
				store: store,
				displayInfo: true,
				displayMsg: 'Displaying {0} - {1} of {2}',
				emptyMsg: "No data to display"
			})			
	    });
	};
	
	//Download a complete data set. Uses only the currently visible columns, in the order in which they are specified
	function download() {
		var form = document.createElement('FORM');
		form.action = self.url;
		form.method = 'POST';
		
		//Build a list of columns
		var cols = new Array();
		
		//Get the column model currently being used by the grid
		var cm = grid.getColumnModel();
		
		//Loop through the columns
		for (var i=0, length=cm.getColumnCount(); i<length; i++) {
			
			//Skip if the column is hidden
			if (cm.isHidden(i)) {
				continue;
			}
			
			//Add the column name (dataIndex to the list
			cols.push(cm.getDataIndex(i));
		}

		var html = '';
		html += "<input type='hidden' name='db' value='"+self.db+"' />";
		html += "<input type='hidden' name='table' value='"+self.table+"' />";
		html += "<input type='hidden' name='action' value='db_filter' />";
		html += "<input type='hidden' name='download' value='1' />";
		
		//Lazy hack
		var input = document.createElement('INPUT');
		input.setAttribute('type','hidden');
		input.setAttribute('name', 'where');
		input.setAttribute('value', store.baseParams.where);
		
		form.innerHTML = html;
		form.appendChild(input);
		
		document.body.appendChild(form);
		form.submit();
		document.body.removeChild(form);
	}

	//Conduct a MySQL query via the grid
	this.select = function(where) {

		//Set the base parameters that will be used for all queries
		store.baseParams = {
			db: self.db,
			table : self.table,
			action : 'db_filter',
			where: where
		};
		//Load table data
		store.load({
			params : {
				start : 0,
				limit : self.pagesize
			}
		});
	}
	
	//Get table schema information
	MySQL.get_schema(self.url, self.db, self.table, initialize);
};
