/**
 * @class Voyeur.Tool.DocumentTypeKwicsGrid A panel that provides per-document KWIC 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.DocumentTypeKwicsGrid = Ext.extend(Ext.grid.GridPanel, {
	
	constructor : function(config) {
		Ext.apply(this, new Voyeur.Tool(config, this));
		
		var store = new Ext.data.GroupingStore({
			reader: Voyeur.data.TypeKwics.reader
			,groupField:'docIndex'
			,proxy: new Ext.data.HttpProxy({url:this.getTromboneUrl()})
			,listeners : {
				'beforeload' : {
					fn : function(store, options) {
						Ext.applyIf(options.params, this.getApiParams());
						if (!options.params.corpus) {return false;}
						Ext.apply(options.params, {tool: 'TypeKwics'});
					},
					scope : this
				}
				,'loadexception' : {
					fn: function(conn, proxy, response, error){
						this.alertError(response.responseText);
					}
					,scope : this
				}
			}
			,remoteSort: true
			// TODO: restore sorting of KWICS
			,sortInfo : {field : 'RAWFREQ', direction : this.getApiParamValue('sortDirection')}
		});
		
		var size = this.getApiParamValue('limit');
		
		var xtypePrefix = this.getXType()+'.';

		this.expander = new Ext.ux.grid.RowExpander({context: this.getApiParamValue('preview')});
		this.expander.tromboneUrl = this.getTromboneUrl();
		
		var forTool = this; /* create a reference that can be used for direct access (instead of relying on scope) */
		
		this.expander.getBodyContent = function(record,index) {
			
	        var body = '<div id="tmp' + record.id + '">Loading…</div>';
	        var params = forTool.getApiParams();
	        params.start = this.grid.getBottomToolbar().cursor+index;
	        params.limit = 1;
	        params.context = params.preview;
	        params.tool = 'TypeKwics';
	        Ext.Ajax.request({
	           url: forTool.getTromboneUrl()
			   ,params : params
	           ,disableCaching: true
	           ,success: function(response, options) {
	        		var data = Ext.util.JSON.decode(response.responseText);
	        		var recordsObject = Voyeur.data.TypeKwics.reader.readRecords(data);
	        		var record = recordsObject.records[0];
	        		var text = record.get('left')+" <span class='keyword'>"+record.get('middle')+' </span>'+record.get('right');
	        		text = text.replace(/\n\s*/g,'<br />');
	 	            Ext.getDom('tmp' + options.objId).innerHTML = '<div class="x-selectable">'+text+'</div>';
	           }
	           ,failure: function(response, options) {
	           }
			   ,objId: record.id
			   ,type : record.get('type')
	        });

	        return body;
		}
		
		// override class to allow cell selection
		this.expander.getRowClass = function(record, rowIndex, p, ds){
	        p.cols = p.cols-1;
	        var content = this.bodyContent[record.id];
	        if(!content && !this.lazyRender){
	            content = this.getBodyContent(record, rowIndex);
	        }
	        if(content){
	            p.body = content;
	        }
	        return 'x-selectable ' + (this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed');
	    }
		
		this.expander.beforeExpand = function(record, body, rowIndex,a,b,c,d,e){
	        if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
	            body.innerHTML = this.getBodyContent(record, rowIndex);
	            return true;
	        } else{
	            return false;
	        }
	    }
					
		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(this.expander, new Ext.ux.grid.Favs())

		var currentContext = this.getApiParamValue('context');
		var currentPreview = this.getApiParamValue('preview');

		var pagingToolBar = new Ext.PagingToolbar({
			store : store
            ,enableOverflow: true
	        ,pageSize: size
			,displayInfo: true
			,displayMsg : "{0}-{1} of {2}"
			,items : [
				'-',
				{
					text : Voyeur.localization.get(this.xtype+'.context')
					,tooltip : Voyeur.localization.get(this.xtype+'.contextTip')
					,menu : new Ext.menu.Menu({
						items : [
							new Ext.menu.CheckItem({text : '5',checked:currentContext==5,group:'context'})
							,new Ext.menu.CheckItem({text : '10',checked:currentContext==10,group:'context'})
							,new Ext.menu.CheckItem({text : '15',checked:currentContext==15,group:'context'})
							,new Ext.menu.CheckItem({text : '20',checked:currentContext==20,group:'context'})
							,new Ext.menu.CheckItem({text : '25',checked:currentContext==25,group:'context'})
						]
						,listeners : {
							'itemclick' : {
								fn : function(item) {
									this.setApiParams({context: item.text})
									this.getStore().load();
								}
								,scope : this
							}
						}
					})
				}
				,{
					text : Voyeur.localization.get(this.xtype+'.preview')
					,tooltip : Voyeur.localization.get(this.xtype+'.previewTip')
					,menu : new Ext.menu.Menu({
						items : [
							new Ext.menu.CheckItem({text : '10',checked:currentPreview==10,group:'preview'})
							,new Ext.menu.CheckItem({text : '20',checked:currentPreview==20,group:'preview'})
							,new Ext.menu.CheckItem({text : '30',checked:currentPreview==30,group:'preview'})
							,new Ext.menu.CheckItem({text : '40',checked:currentPreview==40,group:'preview'})
							,new Ext.menu.CheckItem({text : '50',checked:currentPreview==50,group:'preview'})
							,new Ext.menu.CheckItem({text : '75',checked:currentPreview==75,group:'preview'})
							,new Ext.menu.CheckItem({text : '100',checked:currentPreview==100,group:'preview'})
							,new Ext.menu.CheckItem({text : '200',checked:currentPreview==200,group:'preview'})
							,new Ext.menu.CheckItem({text : '300',checked:currentPreview==300,group:'preview'})
							,new Ext.menu.CheckItem({text : '400',checked:currentPreview==400,group:'preview'})
							,new Ext.menu.CheckItem({text : '500',checked:currentPreview==500,group:'preview'})
						]
						,listeners : {
							'itemclick' : {
								fn : function(item) {
									this.setApiParams({preview: item.text});
									// look through rows and re-fetch needed previews
									this.getStore().each(function(record, ind) {
										if (this.expander.state[record.id]) {
											this.expander.getBodyContent(record, ind);
										}
									}, this);
								}
								,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.CheckboxSelectionModel({
				listeners: {
					rowselect: {
						fn: function(sm, index, record) {
							/**
							 * @event tokenSelected
							 * @param {Voyeur.Tool.DocumentTypeKwicsGrid} tool
							 * @param {Object} params <ul>
							 * <li><b>docIdType</b> : String</li>
							 * <li><b>tokenId</b> : Integer</li>
							 * </ul>
							 * @type dispatcher
							 */
							this.getApplication().dispatchEvent('tokenSelected', this, {
								docIdType: record.get('docId')+':'+record.get('type'),
								tokenId: record.get('tokenId')
							});
						}
						,scope: this
					}
				}
			}),
			stripeRows : true,
			colModel : new Ext.grid.ColumnModel([
				this.expander		
				,{header : 'Left', css : 'direction: rtl;', dataIndex : 'left', toolTip : Voyeur.localization.get('tool.frequencies_document.term'), renderer : function(val) {val=Ext.util.Format.htmlEncode(val); return val; return "…"+val.substring(val.length-30)}, align : 'right'},
				{header : 'Keyword', dataIndex : 'middle', toolTip : Voyeur.localization.get('tool.frequencies_document.document_index'), renderer : function(val) {return "<span class='keyword'>" +Ext.util.Format.htmlEncode(val) + '</span>';}, align : 'center', width : 50},
				{header : 'Right', dataIndex : 'right', toolTip : Voyeur.localization.get('tool.frequencies_document.document_name'), renderer : function(val) {val = Ext.util.Format.htmlEncode(val); return val; return val.substring(0,30)+"…"}},
				{header : 'Document', dataIndex : 'docIndex', toolTip : Voyeur.localization.get('tool.frequencies_document.document_name'), renderer : function(value, b,c,d ,e, store) {return forTool.getCorpus().getDocument(value).getLabel()}, scope: this, width: 75},
				{header : 'Position', dataIndex : 'tokenId', toolTip : Voyeur.localization.get('tool.frequencies_document.document_name'), renderer : function(val) {return val}, width : 75, hidden : true}
			]),
			store : store,
			bbar : pagingToolBar
		});
		Voyeur.Tool.DocumentTypeKwicsGrid.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,  type: null})
			if (data.tokenIdStart) {this.setApiParams({tokenIdStart: data.tokenIdStart})}
			this.getStore().load();
		}, this);

		/**
		 * @event documentTypesSelected
		 * @type listener
		 */
		this.addListener('documentTypesSelected', function(src, data) {
			this.setApiParams({docIdType: data.docIdType,  type: null})
			this.getStore().load();
		}, this);
		
		/**
		 * @event corpusTypeSelected
		 * @type listener
		 */
		this.addListener('corpusTypeSelected', function(src, data) {
			if (this.getCorpus().getSize() == 1) {
				var docIdType = this.getCorpus().getDocument(0).getId()+':'+data.type;
				this.setApiParams({docIdType: docIdType,  type: null})
				if (data.tokenIdStart) {this.setApiParams({tokenIdStart: data.tokenIdStart})}
				this.getStore().load();
			}
		}, this);
		
		/**
		 * @event corpusTypesSelected
		 * @type listener
		 */
		this.addListener('corpusTypesSelected', function(src, data) {
			if (this.getCorpus().getSize() == 1) {
				var docId = this.getCorpus().getDocument(0).getId();
				var docIdType = [];
				for (var i = 0; i < data.type.length; i++) {
					docIdType.push(docId+':'+data.type[i]);
				}
				this.setApiParams({docIdType: docIdType,  type: null})
				if (data.tokenIdStart) {this.setApiParams({tokenIdStart: data.tokenIdStart})}
				this.getStore().load();
			}
		}, this);
		
//		this.addListener('tokenSelected', function(src, data) {
//			this.setApiParams({docIdType: data.docIdType,  type: null})
//			this.getStore().load();
//		}, this);

	}

	,api: {
		/**
		 * @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 display in the collapsed view.
		 * @type Integer
		 * @default 5
		 */
		,context: {'default': 5}
		/**
		 * @property preview The number of surround words to display in the expanded view.
		 * @type Integer
		 * @default 50
		 */
		,preview: {'default': 50}
		//,sortBy: {'default': 'tokenId'}
		//,sortDirection: {'default': 'desc'}
		/**
		 * @property type The corpus type(s) to restrict results to.
		 * @type String|Array
		 * @default null
		 */
		,type: {'default': null}
		/**
		 * @property docIdType The document type(s) to restrict results to.
		 * @type String|Array
		 * @default null
		 */
		,docIdType: {'default': null}
		/**
		 * @property tokenIdStart The token id to start at.
		 * @type Integer
		 * @default null
		 */
		,tokenIdStart: {'default': null}
		,toolType: ['Table']
//		,visibleColumn: {'default': ['type','rawFreq','relativeFreqs']}
		,listeners: ['CorpusSummaryResultLoaded', 'documentTypeSelected', 'documentTypesSelected', 'corpusTypeSelected', 'corpusTypesSelected']
		,dispatchers: ['tokenSelected']
	}
	
	,thumb: {
		large: 'DocumentTypeKwicsGrid.png'
	}

	// private localization variables
	,i18n : {
		title : {en: "Keywords in Context"}
		,help : {en: "This tool shows each occurrence of a selected term with some context (words to the left and right of the keyword)."}
		,context : {en: "Context"}
		,contextTip : {en: "This value determines how many words to display on the left and the right of each keyword."}
		,preview : {en: "Preview"}
		,previewTip : {en: "This value determines how many words to display on the left and the right of each keyword in the preview section (the preview is available by expanding the keyword row)."}
		,selectRowsForResults : {en: "Generate results by selecting rows from the <i>Keyword in Context</i> tool."}
	}
});

Ext.reg('voyeurDocumentTypeKwicsGrid', Voyeur.Tool.DocumentTypeKwicsGrid);

