/*
 *  Copyright 2018 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * This class provides a Tree for surveys, their pages and their questions.
 * @private
 */
Ext.define('Ametys.plugins.linkdirectory.link.LinkDirectoryGrid', {
 	extend: 'Ext.grid.Panel',
 	
	/**
	 * @private
	 * @property {Ext.data.Store} _store The data store for this grid.
	 */
 	
 	statics: {
        
        convertThemes: function(val, record, dataIndex)
        {
            var properties = {};
	        record.data[dataIndex + '_map'] = properties;
	        
	        if (Ext.isArray(val) && val.length > 0 && Ext.isObject(val[0]))
	        {
	            for (var i = 0; i < val.length; i++)
	            {
	                properties[val[i].id] = val[i];
	                val[i] = val[i].id;
	            }
	        }
	        else if (Ext.isObject(val))
	        {
	            properties[val.id] = val;
	            val = val.id;
	        }
	        return val;
        },
        
 		/**
 	     * Renderer for the themes
 	     * @param {Object[]} themes themes value.
 	     * @param {Object} metadata A collection of metadata about the current cell
 	     * @param {Ext.data.Model} record The record for the current row
         * @param {Number} rowIndex The index of the current row
	     * @param {Number} colIndex The index of the current column
	     * @param {Ext.data.Store} store The data store
	     * @param {Ext.view.View} view The current view
         * @param {String} dataIndex The data index  of the column
 	     * @return {String} the labels of the themes as a coma-separated string
 	     */
 	    renderThemes: function(value, metadata, record, rowIndex, colIndex, store, view, dataIndex)
 	    {
            value = Ext.Array.from(value);
            
 	    	var labels = [];
            
            dataIndex = dataIndex || rowIndex; // When used by grouping feature, data index is the 4th arguments
            
            var properties = record.get(dataIndex + "_map");
        
            Ext.Array.forEach(value, function(v) {
                var property = properties[v]
	            labels.push(Ext.String.escapeHtml(property ? property.label : value));
	        });
        
 	        return labels.join(', ')
 	    },
 	    
 	   /**
 	     * Renderer for the limitedAccess
 	     * @param {String|Boolean} value the restricted value
 	     * @param {Object} metadata A collection of metadata about the current cell
 	     * @param {Ext.data.Model} record The record for the current row
 	     * @return {String} the representation of restricted value as an icon.
 	     */
 	    renderLimitedAccess: function(value, metadata, record)
 	    {
 	        if (value == 'true' || (Ext.isBoolean(value) && value))
 	        {
 	            return '<span class="a-grid-glyph ametysicon-check34"></span>';
 	        }
 	        else
 	        {
 	            return "";
 	        }
 	    },
 	    
 	   /**
 	     * Renderer for the url
 	     * @param {String} url the url value
 	     * @param {Object} metadata A collection of metadata about the current cell
 	     * @param {Ext.data.Model} record The record for the current row
 	     * @return {String} the html string used for the rendering of the url
 	     */
 	    renderUrl: function(url, metadata, record)
 	    {
 	        if (record.get('urlType') == 'PAGE')
 	        {
 	            if (record.get('unknownPage'))
 	            {
 	                return '<span class="a-grid-glyph ametysicon-link23 decorator-ametysicon-caution9 link-warning"></span>' + '{{i18n PLUGINS_LINKDIRECTORY_UITOOL_UNKNOWN_PAGE}}';
 	            }
 	            else
 	            {
 	            	return '<span class="a-grid-glyph ametysicon-link23"></span><a class="link-page" href="javascript:(function(){Ametys.tool.ToolsManager.openTool(\'uitool-page\', {id:\'' + url + '\'});})()">' + Ext.String.escapeHtml(record.get('pageTitle')) + '</a>';
 	            }
 	        }
 	        else
 	        {
 	        	return '<span class="a-grid-glyph ametysicon-link23"></span>' + (url || record.get('internalUrl'));
 	        }
 	    },
 	    
 	   /**
 	     * Renderer for the status
 	     * @param {String|Boolean} value the status value
 	     * @param {Object} metadata A collection of metadata about the current cell
 	     * @param {Ext.data.Model} record The record for the current row
 	     * @return {String} the status label
 	     */
 	    renderStatus: function(value, metadata, record)
 	    {
 	        if (value == 'BROKEN')
 	        {
 	            return "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_BROKEN_LABEL}}";
 	        }
 	        else if (value == 'NEW')
 	        {
 	            return "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_NEW_LABEL}}";
 	        }
 	        else if (value == 'NORMAL')
 	        {
 	        	return "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_NORMAL_LABEL}}";
 	        }
 	    }
 	},
 	
 	
 	constructor: function(config)
 	{
 		this._store = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.linkdirectory.link.LinkDirectoryTool.Link',
            
            proxy: {
                type: 'ametys',
                plugin: 'link-directory',
                url: 'links.json',
                reader: {
                    type: 'json',
                    rootProperty: 'links'
                },
                
                extraParams: {
    				siteName: Ametys.getAppParameter('siteName')
    			}
            },
            
            listeners: {
                'beforeload' : Ext.bind(this._onBeforeLoad, this)
            }
        });     
		
 		var langCombo = Ametys.cms.language.LanguageDAO.createComboBox({
			itemId: 'languages-combo',
			fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_LANGUAGE}}",
			listeners: {
	        	'change': Ext.bind(this._onChangeLang, this)
	        }
		});
 		
		config = Ext.applyIf(config, {
			forceFit: true,
            cls: 'linkdirectory-tool',
            
            stateful: true,
            stateId: this.self.getName() + "$linkgrid",
            
            features: [{ftype:'grouping'}],

            store : this._store,
            
            selModel : {
                mode: 'MULTI'
            },
 			
 			// Languages combo box
 			dockedItems: [{
				dock: 'top',
				xtype: 'toolbar',
				layout: {
			        type: 'hbox',
			        align: 'stretch'
			    },
				
			    border: false,
				defaults : {
					cls: 'ametys',
					labelWidth: 55,
					labelSeparator: ''
				},
				
				items: [langCombo,
                    {
                    // Filter input
                    xtype: 'textfield',
                    itemId: 'search-filter-input',
                    cls: 'ametys',
                    flex: 1,
                    maxWidth: 300,
                    emptyText: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_FILTER_EMPTY_TEXT}}",
                    enableKeyEvents: true,
                    minLength: 3,
                    minLengthText: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_FILTER_MIN_LENGTH_INVALID}}",
                    msgTarget: 'qtip',
                    listeners: {change: Ext.Function.createBuffered(this._filterByTitleOrUrl, 300, this)}
                }, {
                    // Clear filter
                    tooltip: "{{i18n PLUGINS_LINKDIRECTORY_UITOOL_FILTER_CLEAR}}",
                    handler: Ext.bind (this._clearFilter, this),
                    iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
                    cls: 'a-btn-light'
                }]
                
			}]
 		});
 		
 		this.callParent(arguments);
 	}, 	
 	
	/**
	 * @private
	 * Listener on selection of the language in top combo box
	 */
	_onChangeLang: function ()
	{
		this._store.load();
	},
	
	/**
     * @private
     * Function called when the 'beforeload' event is fired
     * @param {Ext.data.Store} store the store
     * @param {Ext.data.operation.Operation} operation the object that will be passed to the proxy to load the store
     */
    _onBeforeLoad: function(store, operation)
    {
    	// Let the load occur only if we know the language.
		var lang = this.down("combobox[itemId='languages-combo']").getValue();
		
		operation.setParams( Ext.apply(operation.getParams() || {}, {
			lang: lang
		}));
    },
    
    /**
     * @private
     * Filters links by input field value.
     * @param {Ext.form.Field} field The field
     */
    _filterByTitleOrUrl: function (field)
    {
        var value = Ext.String.trim(field.getValue());
        if (this._filterValue == value)
        {
            // Do nothing
            return;
        }
        
        this._filterValue = value;
        var regexFilter = new RegExp(value, 'i');
        
        if (value.length > 2)
        {
            var currentSelection = this.getSelection();
           
            this._store.clearFilter();
            this._store.filterBy(function(record){
                return regexFilter.test(record.data.title) || regexFilter.test(record.data.url);
            });
            
            if (currentSelection.length > 0)
            {
                var me = this;
                Ext.Array.each(currentSelection, function (sel) {
                    if (me._store.findExact(me._store.getModel().idProperty, sel.getId()) == -1)
                    {
                        // The current selection is not visible, clear the selection
                        me.getSelectionModel().deselect([sel]);
                    }
                })
                
            }
        }
        else
        {
            // We do not call _clearFilter that will also empty the filter and prevent from typing
            this._filterValue = null;
            this._store.clearFilter(); 
        }
    },
    
    /**
     * @private
     * Clear the current filter
     */
    _clearFilter: function()
    {
        this.down("#search-filter-input").reset();
        this._filterValue = null;
        
        this._store.clearFilter();
    }
 });