/**
 * @class Voyeur.Tool.DocumentTypeCollocateFrequenciesGrid A panel that provides per-document collocate data in a tabular format.
 * @extends_ext Ext.grid.GridPanel
 * @extends Voyeur.Tool
 * @namespace Voyeur.Tool
 * @author Stéfan Sinclair
 * @since 0.1.1
 */
Voyeur.Tool.DocumentTypeCollocateFrequenciesGrid = Ext.extend(Ext.grid.GridPanel, {
	constructor: function(config){
		Ext.apply(this, new Voyeur.Tool(config, this))
		var reader = new Ext.data.JsonReader({
			root: 'documentTypeCollocateFrequencies.types',
			totalProperty: 'documentTypeCollocateFrequencies["@totalTypes"]'
		}, Voyeur.data.DocumentTypeCollocates.fields);
		var store = new Ext.data.GroupingStore({
			reader: reader
			,fields: Voyeur.data.DocumentTypeCollocates.fields
			,groupField: this.getApiParamValue('groupBy')
			,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('type'))) {return false;}
						Ext.applyIf(options.params, this.getApiParams());
						Ext.apply(options.params, {tool: 'DocumentTypeCollocateFrequencies'});
					},
					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
			,sortInfo : {field : this.getApiParamValue('sortBy'), direction : this.getApiParamValue('sortDirection')}
		});
		store.paramNames.sort='sortBy';
		store.paramNames.dir='sortDirection'
		
		var xtypePrefix = this.getXType() + '.';
		
		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());
		
		var context = this.getApiParamValue('context');
		var visibleColumn = this.getApiParamValue('visibleColumn');
		
		var panel = this;
		
		var pagingToolbar = new Ext.PagingToolbar({
			store: store,
            enableOverflow: true,
			pageSize: this.getApiParamValue('limit'),
			displayInfo: true
			,items : [
				'-',
				{
					text : this.localize('context')
					,tooltip : this.localize('contextTip')
					,menu : new Ext.menu.Menu({
						items : [
							new Ext.menu.CheckItem({text : '1',checked:context==1,group:'context'})
							,new Ext.menu.CheckItem({text : '2',checked:context==2,group:'context'})
							,new Ext.menu.CheckItem({text : '3',checked:context==3,group:'context'})
							,new Ext.menu.CheckItem({text : '4',checked:context==4,group:'context'})
							,new Ext.menu.CheckItem({text : '5',checked:context==5,group:'context'})
							,new Ext.menu.CheckItem({text : '7',checked:context==7,group:'context'})
							,new Ext.menu.CheckItem({text : '10',checked:context==10,group:'context'})
							,new Ext.menu.CheckItem({text : '15',checked:context==15,group:'context'})
							,new Ext.menu.CheckItem({text : '20',checked:context==20,group:'context'})
							,new Ext.menu.CheckItem({text : '25',checked:context==25,group:'context'})
						]
						,listeners : {
							'itemclick' : {
								fn : function(item) {
									this.setApiParams({context: item.text})
									this.getStore().load();
								}
								,scope : this
							}
						}
					})
				}, '-',
				{
	                xtype: 'typeSearch',
	                width: 100,
	                parentTool: this,
	                listeners: {
	            	    typeSelected: function(combo, type, record) {
	                		this.setApiParams({type: type});
	                		var docIdTypes = [];
	                		this.getCorpus().getDocuments().eachKey(function(key, doc) {
	                			var docIdType = key+':'+type;
	                			docIdTypes.push(docIdType);
	                		}, this);
	                		this.setApiParams({docIdType: docIdTypes});
							this.getStore().load();
	            	    },
	            	    scope: this
	                }
	            }
			]
		});
		
		Ext.applyIf(config, {
			view: new Ext.grid.GroupingView(config.viewConfig)
			,iconCls : 'table'
			,loadMask: true,
			sm: new Ext.grid.RowSelectionModel(),
			stripeRows: true,
			colModel: new Ext.grid.ColumnModel({
				columns: [
					{
						header: this.localize('docLabel'), tooltip : this.localize('docLabelTip'), dataIndex: 'docIndex', hidden: visibleColumn.indexOf('docIndex')==-1,
						renderer : function(val) {return panel.getCorpus().getDocument(val).getShortLabel()}
					}
					,{
						header: this.localize('keywordDocument'), tooltip : this.localize('keywordDocumentTip'), dataIndex: 'keyword_docId', sortable: false, hidden: visibleColumn.indexOf('keyword_docId')==-1,
						renderer : function(val, meta, record) {return '<span class="keyword">'+record.get('keyword')+'</span> in '+panel.getCorpus().getDocument(record.get('docIndex')).getShortTitle()}
					},{
						header: this.localize('keyword'), tooltip : this.localize('keywordTip'), dataIndex: 'keyword', sortable: true, hidden: visibleColumn.indexOf('keyword')==-1,
						renderer : function(val) {return '<span class="keyword">'+val+'</span>'}
					},{
						header: this.localize('type'), tooltip : this.localize('typeTip'), dataIndex: 'type', sortable: true, hidden: visibleColumn.indexOf('type')==-1,
						renderer : function(val) {return '<span class="keyword">'+val+'</span>'}
					}
					,{
						header: this.localize('rawCollocateFreq'), tooltip : this.localize('rawCollocateFreqTip'), dataIndex: 'rawCollocateFreq', sortable: true, hidden: visibleColumn.indexOf('rawCollocateFreq')==-1,
						renderer : function (val, meta, record) {return val + ' ('+ record.get('rawFreq') + ')'}
					}
					,{
						header: this.localize('relativeCollocateFreq'), tooltip : this.localize('relativeCollocateFreqTip'), sortable: true, dataIndex: 'relativeCollocateFreq', hidden: visibleColumn.indexOf('relativeCollocateFreq')==-1,
						renderer : function (val, meta, record) {return Ext.util.Format.number(val*10000,'0,000.0') + ' ('+Ext.util.Format.number(record.get('relativeFreq')*10000,'0,000.0')+')'}
					}
					,{
						header: this.localize('rawCollocateFreqRatio'), tooltip : this.localize('rawCollocateFreqRatioTip'), sortable: true,  dataIndex: 'rawCollocateFreqRatio', hidden: visibleColumn.indexOf('rawCollocateFreqRatio')==-1,
						renderer : function(val) {return "<span class='" + (val < 0 ? 'negative' : 'positive') + "'>" + Ext.util.Format.number(val*100,'0,000.0') + '</span>'}
					}
				],
				listeners: {
					hiddenchange: {
						// FIXME this code moved from Voyeur.Tool as being too specific
						// also in CorpusTypeFrequenciesGrid
						fn: function(cm) {
							var columns = [];
							var size = cm.getColumnCount();
							var dataIndex;
							for (var i=0;i<size;i++) {
								if (!cm.isHidden(i)) {
									dataIndex = cm.getDataIndex(i);
									if (dataIndex) {columns.push(cm.getDataIndex(i));}
								}
							}
							this.setApiParams({visibleColumn: columns});
							if (this.store && this.store.groupField) {this.setApiParams({groupBy: this.store.groupField})}
						}
						,scope: this
					}
				}
			}),
			store: store,
			bbar: pagingToolbar
		});
		Voyeur.Tool.DocumentTypeCollocateFrequenciesGrid.superclass.constructor.apply(this, arguments);
		
		/**
		 * @event CorpusSummaryResultLoaded
		 * @type listener
		 */
		this.addListener('CorpusSummaryResultLoaded', function(src, data) {
			this.getStore().load();
		}, this);

		/**
		 * @event documentTypeSelected
		 * @type listener
		 */
		this.addListener('documentTypeSelected', function(src, data) {
			this.setApiParams({docIdType: data.docIdType});
			this.getStore().load();
		}, this);

		/**
		 * @event documentTypesSelected
		 * @type listener
		 */
		this.addListener('documentTypesSelected', function(src, data) {
			this.setApiParams({docIdType: data.docIdType});
			this.getStore().load();
		}, this);
	}
	
	,api: {
		/**
		 * @property stopList The stop list to use to filter results.
		 * Choose from a pre-defined list, or enter a comma separated list of words, or enter an URL to a list of stop words in plain text (one per line).
		 * @type String
		 * @default null
		 * @choices stop.en.taporware.txt, stop.fr.veronis.txt
		 */
		stopList: {
			'default': null,
			'choices': ['stop.en.taporware.txt', 'stop.fr.veronis.txt']
		}
		/**
		 * @property start The index in the results to start at.
		 * @type Integer
		 * @default 0
		 */
		,start: {'default': 0}
		/**
		 * @property limit The number of words to return in each call.
		 * @type Integer
		 * @default 50
		 */
		,limit: {'default': 50}
		/**
		 * @property context The number of surrounding words to examine for collocates.
		 * @type Integer
		 * @default 3
		 */
		,context: {'default': 3}
		/**
		 * @property sortBy The property to sort results by.
		 * @type String
		 * @default rawCollocateFreqRatio
		 * @choices docIndex, keyword, type, rawCollocateFreq, relativeCollocateFreq, rawCollocateFreqRatio
		 */
		,sortBy: {
			'default': 'rawCollocateFreqRatio',
			'choices': ['docIndex', 'keyword', 'type', 'rawCollocateFreq', 'relativeCollocateFreq', 'rawCollocateFreqRatio']
		}
		/**
		 * @property sortDirection The direction to sort results in.
		 * @type String
		 * @default DESC
		 * @choices ASC, DESC
		 */
		,sortDirection: {'default': 'DESC'}
		/**
		 * @property groupBy The property to group results by.
		 * @type String
		 * @default keyword_docId
		 * @choices docIndex, keyword_docId, keyword, type, rawCollocateFreq, relativeCollocateFreq, rawCollocateFreqRatio
		 */
		,groupBy: {
			'default': 'keyword_docId',
			'choices': ['docIndex', 'keyword_docId', 'keyword', 'type', 'rawCollocateFreq', 'relativeCollocateFreq', 'rawCollocateFreqRatio']
		}
		/**
		 * @property query A string to search for in a document.
		 * @type String
		 * @default null
		 */
		,query: {'default': null}
		/**
		 * @property docIdType The document type(s) to restrict results to.
		 * @type String|Array
		 * @default null
		 */
		,docIdType: {'default': null}
		/**
		 * @property visibleColumn The columns to display.
		 * @type Array
		 * @default ['type', 'rawCollocateFreq', 'relativelCollocateFreq', 'rawCollocateFreqRatio']
		 * @choices docIndex, keyword_docId, keyword, type, rawCollocateFreq, relativeCollocateFreq, rawCollocateFreqRatio
		 */
		,visibleColumn: {'default': ['type', 'rawCollocateFreq', 'relativelCollocateFreq', 'rawCollocateFreqRatio']}
		,toolType: ['Table', 'Document']
		,listeners: ['CorpusSummaryResultLoaded', 'documentTypeSelected', 'documentTypesSelected']
	}
	
	,thumb: {
		large: 'DocumentTypeCollocateFrequenciesGrid.png'
	}

	// private localization variables
	,i18n : {
		title : {en: "Collocates"}
		,help : {en: "This table shows the frequencies of words that appear near a specified term in a document."}
		,context : {en: "Context"}
		,contextTip : {en: "This value determines how many words to count on the left and the right of each keyword."}
		,term : {en: "Term"}
		,termTip : {en: "The term from the corpus for which data is being provided."}
		,docLabel: {en: 'Document'}
		,docLabelTip: {en: "The document in which the collocate is found."}
		,keywordDocument: {en: 'Keyword/Document'}
		,keywordDocumentTip: {en: "Indicates the keyword and document for the collocate."}
		,keyword: {en: 'Keyword'}
		,keywordTip: {en: 'This is the keyword for which collocates are shown.'}
		,type : {en : "Frequencies"}
		,typeTip: {en: 'This is the collocate that occurs near the keyword.'}
		,rawCollocateFreq: {en: 'Raw Frequency'}
		,rawCollocateFreqTip: {en: 'This shows the frequency of the collocate near the keyword, and then in parentheses the frequency of the collocate in the entire document.'}
		,relativeCollocateFreq: {en: 'Relative Frequency'}
		,relativeCollocateFreqTip: {en: 'This shows the relative frequency per 10,000 words of the collocate near the keyword, and then in parentheses the relative frequency of the collocate in the entire document.'}
		,rawCollocateFreqRatio: {en: 'Ratio'}
		,rawCollocateFreqRatioTip: {en: "This indicates the difference between the relative frequency of the collocates near the keywords and the relative frequency of the collocates in the entire document. Higher positive values mean that the collocate is more closely associated with the keyword than in the rest of the document."}
	}
});

Ext.reg('voyeurDocumentTypeCollocateFrequenciesGrid', Voyeur.Tool.DocumentTypeCollocateFrequenciesGrid);

