/*
 *  Copyright 2016 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.
 */

/**
 * Tool that display the list of projects
 * @private
 */
Ext.define('Ametys.plugins.workspaces.project.tool.ProjectsTool', {
    extend: 'Ametys.tool.Tool',
    
    
    constructor: function(config)
    {
        this.callParent(arguments);
        Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onMessageCreatedOrModified, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.CREATED, this._onMessageCreatedOrModified, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onMessageDeleted, this);
        
        Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onSiteModified, this);
    },
        
    getMBSelectionInteraction: function() 
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
    
    createPanel: function()
    {
        this._store = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.workspaces.project.tool.ProjectsTool.ProjectEntry',
            proxy: {
                type: 'ametys',
                role: 'org.ametys.plugins.workspaces.project.ProjectManager',
                methodName: 'getProjectsForClientSide',
                methodArguments: [],
                reader: {
                    type: 'json'
                }
            },
            sorters: [{property: 'title', direction: 'ASC'}]
        });
        
        this._grid = Ext.create('Ext.grid.Panel', {
            
            stateful: true,
            stateId: this.self.getName() + "$grid",
            
            // Languages combo box
            dockedItems: [{
                dock: 'top',
                xtype: 'toolbar',
                layout: {
                    type: 'hbox',
                    align: 'stretch'
                },
                
                border: false,
                defaults : {
                    cls: 'ametys',
                    labelWidth: 55,
                    labelSeparator: ''
                },
                
                items: [{
                    // Search input
	                xtype: 'textfield',
                    itemId: 'search-filter-input',
	                cls: 'ametys',
	                flex: 1,
	                maxWidth: 300,
	                emptyText: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_FILTER_EMPTY_TEXT}}",
	                enableKeyEvents: true,
	                minLength: 3,
	                minLengthText: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_FILTER_MIN_LENGTH_INVALID}}",
	                msgTarget: 'qtip',
	                listeners: {change: Ext.Function.createBuffered(this._filterByTitle, 300, this)}
                }, {
                    // Clear filter
                    tooltip: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_FILTER_CLEAR}}",
                    handler: Ext.bind (this._clearFilter, this),
                    iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
                    cls: 'a-btn-light'
                }]
            }],
            
            store: this._store,
            
            selModel: {
                mode: 'SINGLE'
            },
            
            columns: [
                {stateId: 'grid-column-title', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_TITLE}}", width: 200, sortable: true, dataIndex: 'title', renderer: Ametys.plugins.workspaces.project.tool.ProjectsGridHelper.renderTitle},
                {stateId: 'grid-column-name', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_NAME}}", flex: 0.1, sortable: true, dataIndex: 'name', hidden: true},
                {stateId: 'grid-column-description', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_DESCRIPTION}}", flex: 0.3, sortable: true, dataIndex: 'description', renderer: function (v) { return Ext.util.Format.nl2br(v.replace(/&/g, '&amp;').replace(/</g, '&lt;')) }},
                {stateId: 'grid-column-categories', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_CATEGORIES}}", flex: 0.2, sortable: true, dataIndex: 'categories', renderer: this._renderTags},
                {stateId: 'grid-column-tags', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_TAGS}}", flex: 0.2, sortable: true, dataIndex: 'tags', renderer: this._renderTags, hidden: true},
                {stateId: 'grid-column-managers', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_MANAGERS}}", flex: 0.3, sortable: false, dataIndex: 'managers', renderer: Ametys.grid.GridColumnHelper.renderUser},
                {stateId: 'grid-column-creationDate', header: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_COLUMN_CREATION}}", flex: 0.1, sortable: true, dataIndex: 'creationDate', xtype: 'datecolumn', format: Ext.Date.patterns.FriendlyDateTime}
            ],
            
            listeners: {
                'selectionchange': Ext.bind(this.sendCurrentSelection, this)
            }
        });
        
        return this._grid;
    },
    
    /**
     * @private
     * Filters queries by input field value.
     * @param {Ext.form.Field} field The field
     */
    _filterByTitle: 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._grid.getSelection();
           
            this._store.clearFilter();
            this._store.filterBy(function(record){
                return regexFilter.test(record.data.title) || regexFilter.test(record.data.name);
            });
            
            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._grid.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(); 
        }
    },
    
    /**
     * Clear the current filter
     */
    _clearFilter: function()
    {
        this._grid.down("#search-filter-input").reset();
        this._filterValue = null;
        
        this._store.clearFilter();
    },
    
    /**
     * @private
     * Renderer for tags
     * @param {String} value the 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 label
     */
    _renderTags: function(value, metadata, record)
    {
        var names = [];
        Ext.Array.each(value, function (item, index) {
            names.push(item.title);
        })
        return names.join(", ");
    },
    
    sendCurrentSelection: function()
    {
        var selection = this._grid.getSelectionModel().getSelection();

        var targets = [];
        for (var i = 0; i < selection.length; i++) 
        {
            targets.push({
                id: Ametys.message.MessageTarget.WORKSPACES_PROJECT,
                parameters: {
                    id: selection[i].id
                }
            });
        }
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.SELECTION_CHANGED,
            targets: targets
        });
    },
    
    setParams: function (params)
    {
        this.callParent(arguments);
        this.refresh();
    },
    
    /**
     * Refreshes the tool
     */
    refresh: function ()
    {
        this.showRefreshing();
        
        this._store.load({callback: this._refreshCb, scope: this});
    },
    
    /**
     * Function invoked after loading the store
     * @private
     */
    _refreshCb: function ()
    {
        this.showRefreshed();
    },
    
    /**
     * Listener on creation or edition message.
     * @param {Ametys.message.Message} message The edition message.
     * @private
     */
    _onMessageCreatedOrModified: function(message)
    {
        var targets = message.getTargets(Ametys.message.MessageTarget.WORKSPACES_PROJECT);
        if (targets.length > 0)
        {
            this.showOutOfDate();
        }
    },
    
    /**
     * Listener on deletion message.
     * @param {Ametys.message.Message} message The deletion message.
     * @private
     */
    _onMessageDeleted: function(message)
    {
        var targets = message.getTargets(Ametys.message.MessageTarget.WORKSPACES_PROJECT);
        for (var i = 0; i < targets.length; i++)
        {
            var record = this._store.getById(targets[i].getParameters().id);
            this._store.remove(record);
        }
    },
    
    /**
     * @private
     * Listener on project modification
     * @param {Ametys.message.Message} message The edition message
     */
    _onSiteModified: function(message)
    {
        var targets = message.getTargets(Ametys.message.MessageTarget.SITE);
        if (targets.length > 0)
        {
            // ideally, we would like to check if the site correspond to a
            // project, and if it is the case, just reload the project
            this.showOutOfDate();
        }
    }
});