/**
 * Document Terms is a table view of term frequencies for each document.
 *
 * @example
 *
 *   let config = {
 *     "bins": null,
 *     "columns": null,
 *     "dir": null,
 *     "docId": null,
 *     "docIndex": null,
 *     "query": null,
 *     "sort": null,
 *     "stopList": null,
 *     "termColors": null,
 *   };
 *
 *   loadCorpus("austen").tool("documentterms", config);
 *
 * @class DocumentTerms
 * @tutorial documentterms
 * @memberof Tools
 */
Ext.define('Voyant.panel.DocumentTerms', {
	extend: 'Ext.grid.Panel',
	mixins: ['Voyant.panel.Panel'],
	requires: ['Voyant.data.store.DocumentTerms'],
	alias: 'widget.documentterms',
	config: {
		options: [{
    		xtype: 'stoplistoption'
    	},{
			xtype: 'categoriesoption'
		},{
			xtype: 'termcolorsoption'
		}]
    },
    statics: {
    	i18n: {
    	},
    	api: {
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {stopList}
			 * @default
			 */
    		stopList: 'auto',
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {query}
			 */
    		query: undefined,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {docId}
			 */
    		docId: undefined,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {docIndex}
			 */
    		docIndex: undefined,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {bins}
			 * @default
			 */
    		bins: 10,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {columns} columns 'docIndex', 'term', 'rawFreq', 'relativeFreq', 'tfidf', 'zscore', 'distributions'
			 */
			columns: undefined,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {sort}
			 */
			sort: undefined,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {dir}
			 */
			dir: undefined,
			/**
			 * @memberof Tools.DocumentTerms
			 * @instance
			 * @property {termColors}
			 * @default
			 */
			termColors: 'categories'
    	},
		glyph: 'xf0ce@FontAwesome'
    },
    constructor: function(config) {
    	
        this.callParent(arguments);
    	this.mixins['Voyant.panel.Panel'].constructor.apply(this, arguments);
    	
        // create a listener for corpus loading (defined here, in case we need to load it next)
    	this.on('loadedCorpus', function(src, corpus) {
    		var store = this.getStore();
    		store.setCorpus(corpus);
    		if (this.isVisible()) {
        		store.load();
    		}
    	});
    	
    	if (config.embedded) {
    		if (window.console) {
    			console.warn(config.embedded.then);
    		}
    		var cls = Ext.getClass(config.embedded).getName();
    		if (cls=="Voyant.data.store.DocumentTerms" || cls=="Voyant.data.model.Document") {
    			this.fireEvent('loadedCorpus', this, config.embedded.getCorpus());
    		}
    	}
    	else if (config.corpus) {
    		this.fireEvent('loadedCorpus', this, config.corpus);
    	}
    	
    	this.on("query", function(src, query) {
    		this.fireEvent("corpusTermsClicked", src, query);
    	}, this);
    	
    	this.on("corpusTermsClicked", function(src, terms) {
    		if (this.getStore().getCorpus()) { // make sure we have a corpus
        		var query = [];
        		terms.forEach(function(term) {
        			query.push(Ext.isString(term) ? term : term.get("term"));
        		});
        		this.setApiParams({
        			query: query,
        			docId: undefined,
        			docIndex: undefined
        		});
        		if (this.isVisible()) {
            		this.getStore().load({params: this.getApiParams()});
        		}
    		}
    	});
    	
    	this.on("documentsClicked", function(src, documents) {
    		var docIds = [];
    		documents.forEach(function(doc) {docIds.push(doc.get('id'));});
    		this.setApiParams({
    			docId: docIds,
    			query: undefined
    		});
    		if (this.isVisible()) {
        		this.getStore().load({params: this.getApiParams()});
    		}
    	});

		this.on("documentsSelected", function(src, docIds) {
    		this.setApiParams({
    			docId: docIds,
    			query: undefined
    		});
    		if (this.isVisible()) {
        		this.getStore().load({params: this.getApiParams()});
    		}
		});

		this.on("corpusSelected", function(src, corpus) {
			this.setApiParams({
				docId: undefined,
				docIndex: undefined
			});
			if (this.isVisible()) {
				this.getStore().load({params: this.getApiParams()});
			}
		});
    	
    	this.on("activate", function() { // load after tab activate (if we're in a tab panel)
    		if (this.getStore().getCorpus()) {
    			this.getStore().load({params: this.getApiParams()});
    		}
    	}, this);
    },
    
    initComponent: function() {
        var me = this;

        var store = Ext.create("Voyant.data.store.DocumentTermsBuffered", {parentPanel: this});
        
        Ext.apply(me, {
    		title: this.localize('title'),
    		emptyText: this.localize("emptyText"),
            store : store,
    		selModel: Ext.create('Ext.selection.CheckboxModel', {
                listeners: {
                    selectionchange: {
                    	fn: function(sm, selections) {
                    		this.getApplication().dispatchEvent('documentTermsClicked', this, selections);
                    	},
                    	scope: this
                    }
                },
                pruneRemoved: false,
    			mode: 'SIMPLE'
            }),
            dockedItems: [{
                dock: 'bottom',
                xtype: 'toolbar',
                overflowHandler: 'scroller',
                items: [{
                    xtype: 'querysearchfield'
                }, {
                    xtype: 'totalpropertystatus'
                },{
        			xtype: 'corpusdocumentselector'
        		}]
            }],
    		columns: [{
    			text: '#',
    			width: 30,
        		dataIndex: 'docIndex',
                sortable: true,
                renderer: function(v) {return v+1;} // 0-based to 1-based
            },{
    			text: this.localize("term"),
        		dataIndex: 'term',
            	tooltip: this.localize("termTip"),
                sortable: true,
                flex: 1,
				xtype: 'coloredtermfield',
				useCategoriesMenu: true
            },{
            	text: this.localize("rawFreq"),
            	dataIndex: 'rawFreq',
            	tooltip: this.localize("rawFreqTip"),
            	width: 'autoSize',
            	sortable: true
            },{
            	text: this.localize("relativeFreq"),
            	tooltip: this.localize("relativeFreqTip"),
            	dataIndex: 'relativeFreq',
            	width: 'autoSize',
            	sortable: true,
            	renderer: function(val) {
            		return Ext.util.Format.number(val*1000000, "0,000")
            	}
            },{
            	text: this.localize("tfidf"),
            	tooltip: this.localize("tfidfTip"),
            	dataIndex: 'tfidf',
            	width: 'autoSize',
            	sortable: true,
            	hidden: true,
            	renderer: Ext.util.Format.numberRenderer('0,000.000')
            },{
            	text: this.localize("zscore"),
            	tooltip: this.localize("zscoreTip"),
            	dataIndex: 'zscore',
            	width: 'autoSize',
            	sortable: true,
            	hidden: true,
            	renderer: Ext.util.Format.numberRenderer('0,000.000')
            },{
                xtype: 'widgetcolumn',
                text: this.localize("trend"),
                tooltip: this.localize('trendTip'),
                flex: 1,
                dataIndex: 'distributions',
                widget: {
                    xtype: 'sparklineline'
                }
            }],
            
            listeners: {
            	termsClicked: {
            		fn: function(src, terms) {
                		if (this.getStore().getCorpus()) { // make sure we have a corpus
                    		var queryTerms = [];
                    		terms.forEach(function(term) {
                    			if (Ext.isString(term)) {queryTerms.push(term);}
                    			else if (term.term) {queryTerms.push(term.term);}
                    			else if (term.getTerm) {queryTerms.push(term.getTerm());}
                    		});
                    		if (queryTerms.length > 0) {
                    			this.setApiParams({
                    				docIndex: undefined,
                    				docId: undefined,
                    				query: queryTerms
                    			});
                        		if (this.isVisible()) {
                            		if (this.isVisible()) {
                                		this.getStore().load({params: this.getApiParams()});
                            		}
                        		}
                    		}
                		}
                	},
                	scope: this
            	}
            }
        });

        me.callParent(arguments);
        
        me.getStore().getProxy().setExtraParam("withDistributions", true);
        
    }
    
});