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

/**
 * Contains actions for the search tool
 */
Ext.define('Ametys.plugins.cms.search.ContentSearchToolActions', {
    singleton: true,
    
    /**
     * Reset criteria of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    resetCriteria: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        searchTool.form.reset();
        if (searchTool.isAdvancedMode())
        {
            searchTool.initAdvancedFromSimple();
        }
    },
    
    /**
     * Reset formatting (sorts, grouping, column status...) of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    resetFormatting: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        
        if (searchTool.resetFormatting)
        {
            searchTool.resetFormatting();
        }
    },
    
    /**
     * Reinitialize the sorters of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    reinitSort: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool(),
            values = searchTool.form.getValues(),
            sorters = Ametys.plugins.cms.search.SearchGridHelper.getDefaultSorters(values);
            
        if (sorters === undefined)
        {
            Ametys.data.ServerComm.callMethod({
                role: "org.ametys.cms.search.model.SearchModelHelper",
                methodName: "getColumnConfigurations",
                parameters: [searchTool._modelId, searchTool.getContextualParameters()],
                callback: {
                    handler: this._getColumnConfigurationsCb,
                    arguments: [searchTool],
                    scope: this
                },
                errorMessage: {
                    msg: "{{i18n plugin.cms:UITOOL_SEARCH_BUTTON_DEFAULT_SORT_ERROR}}",
                    category: Ext.getClassName(this)
                }
            });
        }
        else
        {
            this._doReinitSort(sorters, searchTool);
        }
    },
    
    /**
     * @private
     * Callback of server call org.ametys.cms.search.model.SearchModelHelper#getColumnConfigurations, 
     * @param {Object[]} columnDefs The column definitions
     * @param {Array} args The callback arguments
     * @param {Ametys.plugins.cms.search.ContentSearchTool} args.searchTool The search tool
     */
    _getColumnConfigurationsCb: function(columnDefs, args)
    {
        var grid = args[0],
            columns = Ametys.plugins.cms.search.SearchGridHelper.getColumnsFromJson(columnDefs, false),
            defaults = Ametys.plugins.cms.search.SearchGridHelper.getSortersFromJson(columns);
        
        this._doReinitSort(defaults, grid);
    },

    /**
     * @private
     * Effectively reinitialize the sorters of the search tool to the given ones
     * @param {Object[]} sorters The sorters to apply
     * @param {Ametys.plugins.cms.search.ContentSearchTool} searchTool The search tool
     */
    _doReinitSort: function(sorters, searchTool)
    {
        var store = searchTool.grid.getStore();
        store.sorters.removeAll(); // clean old sorters (doing store.sorters = null will lead to setSorters calling #sortFn for doing a clientside sort)
        store.setSorters(sorters);
        searchTool._launchSearch();
    },
    
    /**
     * Apply the CSV export of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    exportCSV: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var url = Ametys.getPluginDirectPrefix(searchTool.getExportCSVUrlPlugin()) + '/' + searchTool.getExportCSVUrl();
        
        Ametys.openWindow (url, {parameters: Ext.JSON.encode(params)}, 'POST');
    },
    
    /**
     * Apply the CSV export of the search tool currently selected and execute it asynchronously
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    asyncExportCSV: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var searchParams = searchTool.getSearchParametersForExport();
        var exportUrl = searchTool.getExportCSVUrlPlugin() + '/' + searchTool.getExportCSVUrl();
        
        this._asyncExport("csv", searchParams, exportUrl);
    },
    
    /**
     * Apply the PDF export of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    exportPDF: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var url = Ametys.getPluginDirectPrefix(searchTool.getExportPDFUrlPlugin()) + '/' + searchTool.getExportPDFUrl();
        
        Ametys.openWindow (url, {parameters: Ext.JSON.encode(params)}, 'POST');
    },
    
    /**
     * Apply the PDF export of the search tool currently selected and execute it asynchronously
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    asyncExportPDF: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var searchParams = searchTool.getSearchParametersForExport();
        var exportUrl = searchTool.getExportPDFUrlPlugin() + '/' + searchTool.getExportPDFUrl();
        
        this._asyncExport("pdf", searchParams, exportUrl);
    },
    
    /**
     * @private
     * Calls the async export callable to run it with the current search
     * @param {String} type The type of export to generate (csv, xml or doc)
     * @param {Object} searchParams The search parameters for the current search
     * @param {String} exportUrl The enternal export URL
     */
    _asyncExport: function(type, searchParams, exportUrl)
    {
        Ametys.plugins.cms.search.AsyncExportDialog.open({
            serverCallFn: serverCallFn,
            scope: this
        });
        
        function serverCallFn(params)
        {
            if (params)
            {
                Ametys.plugins.cms.search.AsyncExportScheduler.add(
                    [
                        type,
                        params.recipient,
                        Ext.JSON.encode(searchParams), 
                        Ametys.LANGUAGE_CODE,
                        exportUrl
                    ],
                    Ext.bind(this._executeAsyncExportCb, this),
                    {
                        waitMessage: "{{i18n UITOOL_SEARCH_ASYNC_EXPORT_TASK_WAITING_MESSAGE}}",
                        errorMessage: "{{i18n UITOOL_SEARCH_ASYNC_EXPORT_TASK_EXECUTE_ERROR}}"
                    }
                );
            }
        }
    },
    
    /**
     * Callback fired when the export asynchronous execution has finished: notify a message.
     * @param {Object} result The request result.
     * @private
     */
    _executeAsyncExportCb: function(result)
    {
        Ametys.notify({
            title: "{{i18n UITOOL_SEARCH_ASYNC_EXPORT_NOTIFY_TITLE}}",
            description: "{{i18n UITOOL_SEARCH_ASYNC_EXPORT_NOTIFY_DESC}}"
        });
    },
    
    /**
     * Apply the XML export of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    exportXML: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var url = Ametys.getPluginDirectPrefix(searchTool.getExportXMLUrlPlugin()) + '/' + searchTool.getExportXMLUrl();
        
        Ametys.openWindow (url, {parameters: Ext.JSON.encode(params)}, 'POST');
    },
    
    /**
     * Apply the XML export of the search tool currently selected and execute it asynchronously
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    asyncExportXML: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var searchParams = searchTool.getSearchParametersForExport();
        var exportUrl = searchTool.getExportXMLUrlPlugin() + '/' + searchTool.getExportXMLUrl();
        
        this._asyncExport("xml", searchParams, exportUrl);
    },
    
    /**
     * Apply the doc export of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    exportDoc: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var url = Ametys.getPluginDirectPrefix(searchTool.getExportDOCUrlPlugin()) + '/' + searchTool.getExportDOCUrl();
        
        var callback = Ext.Function.bind(this._exportDocCb, this, [url, params], true);
        this._exportDoc(callback);
    },
    
    /**
     * @private
     * Apply the doc export of the search tool currently selected, will ask for grouping fields
     * @param {Function} callback The callback called after the result of the Ametys.plugins.cms.search.ChooseSearchGroupingFields dialog
     */
    _exportDoc: function(callback)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var url = Ametys.getPluginDirectPrefix(searchTool.getExportDOCUrlPlugin()) + '/' + searchTool.getExportDOCUrl();
        
        if (searchTool instanceof Ametys.plugins.cms.search.solr.SolrContentSearchTool)
        {
            Ametys.plugins.cms.search.ChooseSearchGroupingFields.open({
                selectionMode: 'free',
                codeMode: 'solr-ametys-columns',
                contentTypes: searchTool.getSelectedCTypes(),
                helpmessage: "{{i18n PLUGINS_CMS_UITOOL_SOLR_SEARCH_COLUMNS_GROUPS_DESC}}",
                callback: callback
            });
        }
        else
        {
            // Get available grouping fields from columns
            var availableGroupingFields = searchTool.getAvailableGroupingFields();
            
            // Open the dialog box to choose grouping fields
            Ametys.plugins.cms.search.ChooseSearchGroupingFields.open({
                selectionMode: 'fixed',
                fields: availableGroupingFields,
                callback: callback
            });
        }
    },
    
    /**
     * @private
     * Apply the DOC export of the search tool currently selected
     * @param {String} groupingFields The field used to group the contents
     * @param {String} url Export URL
     * @param {Object} params The search parameters for the current search
     */
    _exportDocCb: function(groupingFields, url, params)
    {
        params.groupingFields = groupingFields;
                    
        Ametys.openWindow (url, {parameters: Ext.JSON.encode(params)}, 'POST');
    },
    
    /**
     * Apply the DOC export of the search tool currently selected and execute it asynchronously
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    asyncExportDoc: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var exportUrl = searchTool.getExportDOCUrlPlugin() + '/' + searchTool.getExportDOCUrl();
        
        var callback = Ext.Function.bind(this._asyncExportDocCb, this, [params, exportUrl], true);
        this._exportDoc(callback);
    },
    
    /**
     * @private
     * Apply the DOC export of the search tool currently selected and execute it asynchronously
     * @param {String} groupingFields The field used to group the contents
     * @param {Object} params The search parameters for the current search
     */
    _asyncExportDocCb: function(groupingFields, params, exportUrl)
    {
        params.groupingFields = groupingFields;
        this._asyncExport("doc", params, exportUrl);
    },
    
    /**
     * Apply the print of the search tool currently selected
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The button pressed to launch the action
     */
    print: function(controller)
    {
        var searchTool = Ametys.tool.ToolsManager.getFocusedTool();
        var params = searchTool.getSearchParametersForExport();
        var url = Ametys.getPluginDirectPrefix(searchTool.getPrintUrlPlugin()) + '/' + searchTool.getPrintUrl();
        
        Ametys.openWindow (url, {parameters: Ext.JSON.encode(params)}, 'POST');
    }
});