/**
 * @class Voyeur.Tool.DocumentTypeFrequenciesGrid 
 * @description A panel for displaying type frequencies for individual documents in a tabular format.
 * @extends Ext.grid.Panel
 * @extends Voyeur.Tool
 * @author Stéfan Sinclair
 * @since 0.1.1
 */
Voyeur.Tool.DocumentTypeFrequenciesGrid = Ext.extend(Ext.grid.GridPanel, {
	constructor : function(config) {
		Ext.apply(this, new Voyeur.Tool(config, this))

		var xtypePrefix = config.xtype+'.';

		var store = new Ext.data.GroupingStore({
			reader: new Ext.data.JsonReader(
				{
					root : 'documentTypes.types'
					,totalProperty : 'documentTypes["@totalTypes"]'
				},
				Ext.data.Record.create(Voyeur.data.DocumentTypes.fields))
			,proxy: new Ext.data.HttpProxy({url:this.getTromboneUrl()})
			,listeners : {
			'beforeload' : {
				fn : function(store, options) {
						if (this.hidden || this.getCorpus().isEmpty() || (!this.getApiParamValue('docIdType') && !this.getApiParamValue('docIndex') && !this.getApiParamValue('type') && !this.getApiParamValue('docId'))) {return false;}
						Ext.applyIf(options.params, this.getApiParams());
						var clean = ['docId', 'docIdType','type','query'];
						for (var i=0; i<clean.length;i++) {if (!options.params[clean[i]]) {delete options.params[clean[i]]}}
						Ext.apply(options.params, {tool: 'DocumentTypeFrequencies'});
					},
					scope : this
				},
				'loadexception' : {
					fn: function(conn, proxy, response, error){
						var alert = Ext.MessageBox.alert("Error", "An error occurred while loading data:<pre style='overflow: auto; clear: both'>\n" + response.responseText+"</pre>");
						alert.setIcon(Ext.MessageBox.ERROR);
					}
					,scope : this
				}
			}
			,remoteSort: true
//			,baseParams : {
//				tool : 'DocumentTypeFrequencies'
//				,bins : 10
//				,extendedSortZscoreMinimum : 1
//			}
			,sortInfo : {field : this.getApiParamValue('sortBy'), direction: this.getApiParamValue('sortDirection')}
			,groupField: this.getApiParamValue('groupBy')
			,groupOnSort : false
		});
		store.paramNames.sort='sortBy';
		store.paramNames.dir='sortDirection'

		this.pagingToolBar = new Ext.PagingToolbar({
				store : store
		        ,pageSize: 30
				,displayInfo: false
				,displayMsg : "{0} - {1} of {2}"
				,listeners : {
					'render' : function(tb) {
						tb.first.hide();
						tb.last.hide();
						tb.refresh.hide();
						seps = tb.findByType('tbseparator');
						for (var i=0;i<seps.length;i++) {seps[i].hide();}
					}
				}
			});

		config.viewConfig = config.viewConfig ? config.viewConfig : {};
		Ext.applyIf(config.viewConfig, {
//			forceFit:true,
			emptyText : this.localize('noResults','tool'),
			deferEmptyText: false
			,hideGroupedColumn : true			
		})

		if (!config.plugins) {config.plugins=[]}
		config.plugins.push(new Ext.ux.grid.Favs({
			exporter: function(records) {
				var vals = [];
				for (var i=0;i<records.length;i++) {
					vals.push(records[i].get('docId')+':'+records[i].get('type'))
				}
				return {docIdType: vals}
			}
		}))
		
		var sm = new Ext.grid.CheckboxSelectionModel()

		var panel = this;
		Ext.applyIf(config, {
			view :  new Ext.grid.GroupingView(config.viewConfig)
			,iconCls : 'table'
//			viewConfig :  config.viewConfig
			,store : store
			,stripeRows : true
			,loadMask : true
			,bbar : [this.pagingToolBar]
			,autoExpandColumn : this.getId()+'-column-docLabel'
			,sm : new Ext.grid.CheckboxSelectionModel()
			,colModel : new Ext.grid.ColumnModel([sm
				,{header : this.localize('docLabel'), dataIndex : 'docIndex', id : this.getId()+'-column-docLabel', toolTip : Voyeur.localization.get('tool.frequencies_document.term'), renderer : function(val) {return panel.getCorpus().getDocument(val).getShortLabel()}}
  				,{header : this.localize('docTitle'), dataIndex : 'docIndex', id : this.getId()+'-column-docTitle', hidden: true, toolTip : Voyeur.localization.get('tool.frequencies_document.term'), renderer : function(val) {return panel.getCorpus().getDocument(val).get('title')}}
  				,{header : this.localize('docAuthor'), dataIndex : 'docIndex', id : this.getId()+'-column-Author', hidden: true, toolTip : Voyeur.localization.get('tool.frequencies_document.term'), renderer : function(val) {return panel.getCorpus().getDocument(val).get('author')}}
  				,{header : this.localize('docTime'), dataIndex : 'docIndex', id : this.getId()+'-column-Time', hidden: true, toolTip : Voyeur.localization.get('tool.frequencies_document.term'), renderer : function(val) {return panel.getCorpus().getDocument(val).getDate()}}
				,{header : 'Type', dataIndex : 'type', sortable : true, toolTip : Voyeur.localization.get('tool.frequencies_document.term'), renderer : function(val,cell,record) {return "<span class='keyword'>"+val+"</span>"}}
				,{header : Voyeur.localization.get(xtypePrefix+'rawFreq'), dataIndex : 'rawFreq', sortable : true, tooltip : Voyeur.localization.get(xtypePrefix+'rawFreqTip'), renderer : Ext.util.Format.numberRenderer('0,000'), width: 60}
				,{header : this.localize('rawZscore'), dataIndex : 'rawZscore', sortable : true, hidden: true, tooltip : this.localize('rawZscoreTip'), renderer : function(val) {return isNaN(val) ? '–' : "<span class='"+ (val < 0 ? 'negative' : 'positive') + "'>"+ Ext.util.Format.number(val,'0,000.00') + '</span>'}}
				,{header : this.localize('rawZscoreCorpusDelta'), dataIndex : 'rawZscoreCorpusDelta', sortable : true, hidden: false, tooltip : this.localize('rawZscoreCorpusDeltaTip'), renderer : function(val) {return isNaN(val) ? '–' : "<span class='"+ (val < 0 ? 'negative' : 'positive') + "'>"+ Ext.util.Format.number(val,'0,000.00') + '</span>'}}
				,{header : Voyeur.localization.get(xtypePrefix+'relativeFreq'), dataIndex : 'relativeFreq', sortable: true, tooltip : Voyeur.localization.get(xtypePrefix+'relativeFreqTip'), renderer : function(val) {return Ext.util.Format.number(val * 10000, '0,000.00')}, width: 60}
				
				// TODO: fix distribution mean in document frequencies ,{header : Voyeur.localization.get(xtypePrefix+'distributionMean'), dataIndex : 'distributionMean', hidden : true, tooltip : Voyeur.localization.get(xtypePrefix+'distributionMeanTip'), renderer : function(val) {return Ext.util.Format.number(val,'0,000.0')}, width: 60}
				,{header : Voyeur.localization.get(xtypePrefix+'distributionStdDev'), dataIndex : 'distributionStdDev', sortable: true, hidden : true, tooltip : Voyeur.localization.get(xtypePrefix+'distributionStdDevTip'), renderer : function(val) {return isNaN(val) ? '–' : Ext.util.Format.number(val,'0,000.000')}, width: 60}
				,{header : Voyeur.localization.get(xtypePrefix+'distributionKurtosis'), dataIndex : 'distributionKurtosis', sortable: true, hidden : true, tooltip : Voyeur.localization.get(xtypePrefix+'distributionKurtosisTip'), renderer : function(val) {return isNaN(val) ? '–' : "<span class='"+ (val < 0 ? 'negative' : 'positive') + "'>"+ Ext.util.Format.number(val,'0,000.00') + '</span>'}, width: 60}
				,{header : Voyeur.localization.get(xtypePrefix+'distributionSkewness'), dataIndex : 'distributionSkewness', sortable: true, hidden: true, tooltip : Voyeur.localization.get(xtypePrefix+'distributionSkewnessTip'), renderer : function(val) {return isNaN(val) ? '–' : "<span class='"+ (val < 0 ? 'negative' : 'positive') + "'>"+ Ext.util.Format.number(val,'0,000.00') + '</span>'}, width: 60}
				,{header : Voyeur.localization.get(xtypePrefix+'distributionFreqs'), dataIndex : 'distributionFreqs', tooltip : Voyeur.localization.get(xtypePrefix+'distributionFreqsTip'), renderer: function(val,cell,record,rowIndex,colIndex) {
						return panel.getSparkLine(val, panel.getColumnModel().getColumnWidth(colIndex))
					}, width : 100}
			])
		});
		
		Voyeur.Tool.DocumentTypeFrequenciesGrid.superclass.constructor.apply(this, arguments);

		
		this.addListener('CorpusSummaryResultLoaded', function(src, data) {
			this.getStore().load();
		}, this);

		this.addListener('documentTypeSelected', function(src, data) {
			this.adjustForDocumentsSize(1);
			this.resetFilteringApiParams();
			this.setApiParams({docIdType: data.docIdType});
			this.getStore().load();
		}, this);

		this.addListener('documentTypesSelected', function(src, data) {
			var docIdTypes = data.docIdType;
			var docs = {};
			var counter = 0;
			for (var i=0;i<docIdType.length;i++) {
				parts = docIdType[i].split(":");
				if (!docs[parts[0]]) {
					counter++;
					docs[parts[0]] = true;
				}
			}
			this.adjustForDocumentsSize(counter);
			this.resetFilteringApiParams();
			this.setApiParams({docIdType: data.docIdType});
			this.getStore().load();
		}, this);

		this.addListener('rowclick', function(src, grid, rowIndex, e) {
			this.fireSelectionChange();
		}, this);
		
		this.addListener('corpusTypeSelected', function(src, data, records, panel) {
			this.adjustForDocumentsSize(this.getCorpus().getSize());
			this.resetFilteringApiParams();
			this.setApiParams({type: data.type});
			this.getStore().load();
		}, this)
		this.addListener('corpusTypesSelected', function(src, data, records, panel) {
			this.adjustForDocumentsSize(this.getCorpus().getSize());
			this.resetFilteringApiParams();
			this.setApiParams({type: data.type});
			this.getStore().load();
		}, this);
		
		this.addListener('corpusDocumentSelected', function(src, params) {
			this.adjustForDocumentsSize(1);
			this.resetFilteringApiParams();
			this.setApiParams({docId: params.docId});
			this.getStore().load();
		}, this);
		this.addListener('corpusDocumentsSelected', function(src, ids) {
			this.adjustForDocumentsSize(ids.length);
			this.resetFilteringApiParams();
			this.setApiParams({docId: ids});
			this.getStore().load();
		}, this);
	}

	,resetFilteringApiParams : function(query) {
		this.setApiParams({type: undefined, docId: undefined, docIdType: undefined, query: undefined});
	}
	,adjustForDocumentsSize : function(size) {
		var store = this.getStore();
		var cm = this.getColumnModel();
		var isMultiple = size>1;
		cm.setHidden(cm.findColumnIndex('docIndex'), !isMultiple);
		if (isMultiple) {store.groupBy('type');}
		else {store.clearGrouping();}		
	}
	,fireSelectionChange : function() {
		var time = new Date().getMilliseconds();
		this.lastSelectionTime=time;
		var me = this;
		setTimeout(function() {if (me.lastSelectionTime == time) {
			records = me.getSelectionModel().getSelections();
			docIdType = []
			for (var i=0;i<records.length;i++) {
				docIdType.push(records[i].get('docId')+':'+records[i].get('type'));
			}
			if (docIdType.length==1) {
				Voyeur.application.dispatchEvent('documentTypeSelected', me, {docIdType : docIdType[0]}, records[0], me.getStore(), me);
			}
			else if (docIdType.length>1) {
				Voyeur.application.dispatchEvent('documentTypesSelected', me, {docIdType : docIdType}, records, me.getStore(), me);
			}
		}}, 1000);
	}
	,lastSelectionTime : 0
	,handleCorpusTermRowClick : function(sm) {
	}

	,showOptions : function() {
		this.showOptionsWindow({
			items : [{
				xtype : 'form',
				labelWidth : 150,
				labelAlign : 'right',
				border : false,
				items : [{
					xtype : 'combo',
					id : 'stopList',
					value : this.getStore().baseParams.stopList,
					fieldLabel : '<span ext:qtip="'
							+ this.localize('stopListTip','tool') + '">'
							+ this.localize('stopList','tool') + '</span>',
					loadingText : this.localize('loading', 'tool'),
					width : 300,
					store : this.getApplication().getStopListsStore()
				    ,selectOnFocus : true
				    ,displayField: 'label'
				    ,valueField: 'id'
				    ,mode: 'local'
				    ,emptyText: this.localize('none','tool')
				},{
					xtype : 'numberfield',
					id : 'extendedSortZscoreMinimum',
					value : this.getStore().baseParams.extendedSortZscoreMinimum,
					fieldLabel : '<span ext:qtip="'
							+ this.localize('extendedSortZscoreMinimumTip','tool')
							+ '">'
							+ this.localize('extendedSortZscoreMinimum','tool')
							+ '</span>'
				}],
				buttons : [{
					text : this.localize('ok', 'tool'),
					iconCls : 'icon-accept',
					listeners : {
						click : {
							fn : function(btn) {
								var formPanel = btn.findParentByType('form');
								var form = formPanel.getForm();
								var stopList = form.findField('stopList');

								if (stopList.getValue() && !stopList.getRawValue()) stopList.setValue('');
								else if (stopList.lastQuery && stopList.lastQuery!=stopList.getValue()) {
									stopList.getStore().loadData({stopLists: {lists: [{id: stopList.lastQuery, label: stopList.lastQuery, description: ''}]}}, true);
									stopList.setValue(stopList.lastQuery)
								}
									
								if (form.isDirty()) {
									this.setApiParams({
										extendedSortZscoreMinimum: form.findField('extendedSortZscoreMinimum').getValue()
										,stopList: stopList.getValue()
									})
									this.getStore().load();
								}
								formPanel.findParentByType('window').destroy();
								
							},
							scope : this
						}
					}
				}, {
					text : this.localize('cancel', 'tool'),
					handler : function(btn) {
						btn.findParentByType('window').destroy();
					}
				}, {
					text : this.localize('restore', 'tool'),
					listeners : {
						click : {
							fn : function(btn) {
								var form = btn.findParentByType('form').getForm();
								form.findField('extendedSortZscoreMinimum').setValue(this.getApiParamDefaultValue('extendedSortZscoreMinimum'));
							},
							scope : this
						}
					}
	
				}]
			}]
		})

	}

	,api: {
		stopList: {'default': null ,'choices': ['stop.en.taporware.txt', 'stop.en.glasgow.txt']}
		,start: {'default': 0}
		,limit: {'default': 50}
		,sortBy: {'default': 'rawFreq'}
		,sortDirection: {'default': 'desc'}
		,groupBy: {'default': 'type'}
		,docIdType: {'default': undefined}
		,type: {'default': undefined}
		,docId: {'default': undefined}
		,docIndex: {'default': undefined}
		,extendedSortZscoreMinimum: {'default': 1}
//		,visibleColumn: {'default': ['type', 'rawCollocateFreq', 'relativelCollocateFreq', 'relativeRatio']}
	}
	
	// private localization variables
	,i18n : {
		title : {en: "Words within each Document"}
		,help : {en: "This table shows word frequencies for each document in the corpus. Hover over the column headers or toolbar buttons for more information."}
		,docLabel : {en : 'Document'}
		,docTitle : {en : 'Title'}
		,docAuthor : {en : 'Author'}
		,docTime : {en : 'Time'}
		,type : {en: "Type"}
		,typeTip : {en: "The type from the document for which data is being provided."}
		,rawFreq : {en: "Count"}
		,rawFreqTip : {en: "The raw count of this term in the document."}
		,rawZscore : {en: "Z-Score"}
		,rawZscoreTip : {en: "This is the z-score – or <a href='http://en.wikipedia.org/wiki/Standard_score' target='_blank'>standard score</a> – of the total raw frequencies for the type in the document, compared to other types; it is a normalized version of the raw frequency, showing the number of standard deviations a value is above or below the mean of type frequencies."}
		,rawZscoreCorpusDelta : {en: "Difference"}
		,rawZscoreCorpusDeltaTip : {en: "This is the difference between the z-score of the word in the document and the z-score of the word in the corpus (positive values mean the word is more frequent in the document than in the corpus as a whole). The z-score – <a href='http://en.wikipedia.org/wiki/Standard_score' target='_blank'>standard score</a> is a normalized version of the raw frequency, showing the number of standard deviations a value is above or below the mean of type frequencies."}
		,relativeFreq : {en: "Relative"}
		,relativeFreqTip : {en: "The relative count of this type in the document (per 10,000 words)."}
		,distributionMean : {en: "Mean"}
		,distributionMeanTip : {en: "This is the mean of distribution values for the document."}
		,distributionStdDev : {en: "Std. Dev."}
		,distributionKurtosis : {en: "Peakedness"}
		,distributionSkewness : {en: "Skew"}
		,distributionFreqs : {en: "Trend"}
		,distributionFreqsTip : {en: "This graph represents the values of the mean relative counts across the corpus (every document has a represented value)."}
		,bins : {en: "Distribution"}
		,binsTip : {en: "This graph represents the distribution of the term across the document."}
		,add_terms : {en: "Add terms"}
		,add_termsMsg : {en: "You can add new search terms below, one per line."}
		,selectRowsForResults : {en: "Generate results by selecting rows from the <i>Document Types</i> tool"}
	}
});

Ext.reg('voyeurDocumentTypeFrequenciesGrid', Voyeur.Tool.DocumentTypeFrequenciesGrid);
