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

/**
 * Sitemap and pages context for profile assignments.
 */
Ext.define('Ametys.plugins.odf.right.ODFRightAssignmentContext', {
    extend: 'Ametys.plugins.cms.profiles.ContentRightAssignmentContext',
    
    /**
     * @private
     * @property {Ametys.plugins.contentstree.ContentsTreePanel} _tree The orgunit tree
     */
    
    /**
     * @cfg {String} [contactModelId] The id of the search model for ODF contact
     */
    
    constructor: function(config)
    {
        this.callParent(arguments);
        this._contactModelId = config.contactModelId;
    },
    
    getComponent: function()
    {
        this.callParent(arguments);
        
        // Form for contact search
        this._contactForm = this._createForm();
        
        // The result grid for contact search
        this._contactGrid = this._createContactSearchGrid();
        
        this._container.items.add(Ext.create('Ext.container.Container', {
            itemId: 'contact-search-container',
            flex: 1,
            layout: {
                type: "vbox",
                align: "stretch"
            },
            items: [this._contactForm, this._contactGrid]
        })); 
        
        this._contentTab = Ext.create('Ext.Panel', {
            title: "{{i18n PLUGINS_ODF_RIGHT_ASSIGNMENT_CONTEXT_TAB_CONTENTS}}",
            layout: 'fit',
            items: this._container
        });
        
    	this._tree = this._getOrgUnitTab();
        
        this._tabPanel = Ext.create('Ext.tab.Panel', {
            items: [this._contentTab , this._tree],
            
            listeners: {
                'tabchange': Ext.bind(this._onTabChange, this)
            }
        });
        
        return this._tabPanel;
    },
    
    _getRadioFields: function()
    {
        return [{
                xtype: 'radiofield',
                boxLabel  : this._radioOptionAllLabel,
                name      : 'radio-content',
                itemId: 'radio-content-all',
                checked: true,
                inputValue: 'all',
                handler: this._onSelectAll,
                scope: this,
                style: {
                    marginLeft: '5px'
                }
            }, {
                xtype: 'radiofield',
                boxLabel  : "{{i18n PLUGINS_ODF_RIGHT_ASSIGNMENT_SEARCH_PROGRAM_ITEM}}",
                name      : 'radio-content',
                inputValue: 'search',
                itemId: 'radio-content-search',
                handler: this._onSelectSearch,
                scope: this,
                style: {
                    marginLeft: '5px'
                }
        }, {
                xtype: 'radiofield',
                boxLabel  : "{{i18n PLUGINS_ODF_RIGHT_ASSIGNMENT_SEARCH_CONTACT}}",
                name      : 'radio-content',
                inputValue: 'search-contact',
                itemId: 'radio-contact-search',
                handler: this._onSelectSearch,
                scope: this,
                style: {
                    marginLeft: '5px'
                }
        }];
    },
    
    /**
     * @private
     * Override callback to get search model for contacts
     * @param {Object} result the server result
     */
    _getSearchModelCb: function(result)
    {
        this.callParent(arguments);
        
        // Get search model for contacts
        Ametys.data.ServerComm.callMethod({
                role: "org.ametys.cms.search.model.SearchModelHelper",
                methodName: "getSearchModelConfiguration",
                parameters: [this._contactModelId, this._getContextualParameters()],
                callback: {
                    handler: this._getContactSearchModelCb,
                    scope: this
                },
                errorMessage: {
                    msg: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR}}",
                    category: Ext.getClassName(this)
                },
                waitMessage: {
                    msg: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_LOADMASK_DEFAULT_MESSAGE}}",
                    target: this._container
                }
            });
    },
    
    /**
     * @private
     * Callback function after retrieving the search model for ODF contacts
     * @param {Object} result the server result
     */
    _getContactSearchModelCb: function(result)
    {
        // Configure the search form
        this._contactForm.configure(result['simple-criteria']);
        this._contactForm.setValues(this._getDefaultSearchValues());
        
        // Reconfigure the result grid
        var fields = Ametys.plugins.cms.search.SearchGridHelper.getFieldsFromJson(result.columns);
        Ametys.plugins.cms.search.ContentSearchTool.addDefaultContentFields(fields);
        var columns = Ametys.plugins.cms.search.SearchGridHelper.getColumnsFromJson(result.columns, false);
        var sorters = Ametys.plugins.cms.search.SearchGridHelper.getSortersFromJson(columns, this._grid);
        
        this._contactGridStore.setProxy({
            type: 'ametys',
            plugin: result.searchUrlPlugin,
            url: result.searchUrl,
            reader: {
                type: 'json',
                rootProperty: 'contents'
            }
        });
        
        if (result.pageSize != null && result.pageSize > 0)
        {
            this._contactGridStore.setPageSize(result.pageSize);
        }
        
        // Update model
        this._contactGridStore.model.replaceFields(fields, true);
        this._contactGrid.reconfigure(columns);
        this._contactGridStore.setSorters(sorters); // Will fire a load event
    },
    
      /**
     * @private
     * Create the search result grid for contacts
     * @return The grid
     */
    _createContactSearchGrid: function ()
    {
        // The store of the result grid
        this._contactGridStore = Ext.create('Ext.data.Store', {
            remoteSort: true,
            autoLoad: false,
            sortOnLoad: true,
            listeners: {
                'beforeload': {fn: this._onBeforeLoadContactGrid, scope: this},
                'load': {fn: this._onLoadContactGrid, scope: this}
            }
        });
        
        return Ext.create('Ext.grid.Panel', {
            store: this._contactGridStore,
            scrollable: true,
            width: '100%',
            flex: 1,
            listeners: {
                'selectionchange': Ext.bind(this._onSelectionChanged, this)
            },
            
            selModel : {
                mode: 'MULTI'
            },
            
            dockedItems: [{
                dock: 'top',
                xtype: 'toolbar',
                layout: {
                    type: 'hbox',
                    align: 'stretch'
                },
                border: true,
                items: [{
                    itemId: 'search',
                    text: "{{i18n plugin.cms:UITOOL_SEARCH_BUTTON_SEARCH}}",
                    iconCls: 'ametysicon-magnifier12',
                    handler: this._searchContact,
                    scope: this,
                    tooltip: {
                        title: "{{i18n plugin.cms:UITOOL_SEARCH_BUTTON_SEARCH}}",
                        text: "{{i18n plugin.cms:UITOOL_SEARCH_BUTTON_SEARCH_DESC}}",
                        glyphIcon: 'ametysicon-magnifier12',
                        inribbon: false
                    }
                }]
            }, {
                dock: 'bottom',
                xtype: 'pagingtoolbar',
                store: this._contactGridStore,
                displayInfo: true,
                displayMsg: "{{i18n plugin.cms:UITOOL_CONTENTEDITIONGRID_RESULT_1}}{0}{{i18n plugin.cms:UITOOL_CONTENTEDITIONGRID_RESULT_2}}{1}{{i18n plugin.cms:UITOOL_CONTENTEDITIONGRID_RESULT_3}}{2}",
                emptyMsg: "{{i18n plugin.cms:UITOOL_CONTENTEDITIONGRID_NO_RESULT}}",
                scrollable: true
            }]
        });
    },
    
    /**
     * @private
     * Function called before loading the grid store
     * @param {Ext.data.Store} store The grid store
     * @param {Ext.data.operation.Operation} operation The object that will be passed to the Proxy to load the store
     */
    _onBeforeLoadContactGrid: function(store, operation)
    {
        if (!this._initialized)
        {
            return false;
        }
        
        operation.setParams(Ext.apply(operation.getParams() || {}, {
            values: Ext.clone(this._contactForm.getJsonValues()),
            excludeSubContents: false,
            model: this._contactModelId,
            contextualParameters: this._getContextualParameters()
        }));
    },
    
    
    /**
     * @private
     * Launches the search
     * @param {Ext.button.Button} button The button
     */
    _searchContact: function(button)
    {
        if (!this._contactForm.isValid())
        {
            return;
        }
        
        this._contactGridStore.loadPage(1);
    },
    
    /**
     * @private
     * Function called when loading the grid store
     * @param {Ext.data.Store} store The grid store
     * @param {Ext.data.Model[]} records The loaded records
     * @param {Boolean} successful True if the operation was successful.
     * @param {Ext.data.operation.Operation} operation The object that will be passed to the Proxy to load the store
     */
    _onLoadContactGrid: function(store, records, successful, operation)
    {
        if (successful && !operation.aborted && records.length > 0)
        {
            this._contactGrid.getSelectionModel().select(records[0]);
            this._contactGrid.getView().focusRow(0);
        }
    },
    
    /**
     * @private
     * Create the tab for orgunits tree
     * @return {Ext.tree.Panel} The orgunits tree panel
     */
    _getOrgUnitTab: function()
    {
        return Ext.create('Ametys.plugins.contentstree.ContentsTreePanel', {
            title: "{{i18n PLUGINS_ODF_RIGHT_ASSIGNMENT_CONTEXT_TAB_ORGUNITS}}",
            itemId: 'orgunit-tree',
            treeId: 'odf-orgunit-tree-config',
            
            border: false,
            scrollable: true,
            animate: true,
            multiSelect: false,

            root: null,
            rootVisible: true,
            
            listeners: {
                'selectionchange': Ext.bind(this._onTreeSelectionChanged, this)
            }
        });
    },
    
    /**
     * @private
     * Handler when the radio button is checked or unchecked for "all" option
     */
    _onSelectAll: function (checkbox, checked)
    {
        if (checked)
        {
            // Disable search
            this._switchToAllContentsMode();
        }
    },
    
    /**
     * @private
     * Handler when the radio button is checked or unchecked for a search option
     */
    _onSelectSearch: function (checkbox, checked)
    {
        if (checked)
        {
            // Enable search
            this._switchToSearchMode(checkbox);
        }
    },
    
    _switchToSearchMode: function (checkbox)
    {
        var searchContainer = this._container.down('#search-container');
        var contactSearchContainer = this._container.down('#contact-search-container');
        
        if (checkbox.itemId == 'radio-content-search')
        {
            contactSearchContainer.hide();
            searchContainer.show();
            
            this._initSearchGrid(this._grid);
        }
        else
        {
            searchContainer.hide();
            contactSearchContainer.show();
            
            this._initSearchGrid(this._contactGrid);
        }
    },
    
    /**
     * @private
     * Switch to the "all contents" mode
     */
    _switchToAllContentsMode: function()
    {
        this._container.down('#radio-content-all').setValue(true);
        this._changeObjectContext(this._contentsRootContext, "<b>" + this._hintAllContents + "</b>", false, true);
        
        // Disable search result grids
        this._grid.getSelectionModel().deselectAll();
        this._contactGrid.getSelectionModel().deselectAll();
        
        // Hide search
        this._container.down('#search-container').hide();
        this._container.down('#contact-search-container').hide();
    },
    
    initialize: function(result)
    {
        if (!this._initialized)
        {
            this.callParent(arguments);
            
            Ametys.data.ServerComm.callMethod({
	            role: "org.ametys.odf.orgunit.RootOrgUnitProvider",
	            methodName: "getRootId",
	            callback: {
	                handler: this._setRootNode,
	                scope: this
	            },
	            waitMessage: false
	        });
        }
        else
        {
            this._switchToAllContentsMode();
        }
    },
    
    /**
     * @private
     * Set the id of orgunit tree's root node
     * @param {String} rootId The root id
     */
    _setRootNode: function (rootId)
    {
        this._tree.setContentRootNode(rootId);
    },
    
    /**
     * @private
     * Listener on tab change. Reinit the context.
     * @param {Ext.tab.Panel} tabPanel The tab panel
     * @param {Ext.Component} newCard The newly activated item
     */
    _onTabChange: function(tabPanel, newCard)
    {
        if (newCard.getItemId() == 'orgunit-tree')
        {
            // Expand tree node and select root
            this._tree.getRootNode().expand(false, function () {
                this._tree.getSelectionModel().select(0);
            }, this);
        }
        else
        {
            this._tree.getSelectionModel().clearSelections();
            this._switchToAllContentsMode();
        }
    },
    
    /**
     * @private
     * Listener when the selection in the tree has changed
     * @param {Ext.selection.Model} model The selection model
     * @param {Ext.data.Model[]} selected The selected records
     */
    _onTreeSelectionChanged: function(model, selected)
    {
        // Check it is not too soon to fire the event (if we do not loaded the root node yet for example)
        if (selected.length > 0)
        {
            var orgunit = selected[0],
                object = orgunit.get('contentId'),
                title = orgunit.get('title');
            
            var hintTextContext = "{{i18n PLUGINS_ODF_RIGHT_ASSIGNMENT_CONTEXT_ORGUNIT_HINT}} <b>" + title + "</b>";
            
            this._changeObjectContext(object, hintTextContext);
        }
    }
});