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

/**
 * Singleton class helper for extraction components managing solr clauses edition.
 * @private
 */
 Ext.define('Ametys.plugins.extraction.edition.EditSolrExtractionComponentDialog', {
    extend: "Ametys.plugins.extraction.edition.EditExtractionComponentDialog",

    /**
     * @protected
     * @property {Object} _codeWidgetParams common params for all used code widget
     */
    
    _init: function ()
    {
        this.callParent(arguments);
        
        // Initialize SolrHint to load all needed data
        SolrHint.init();
        
        // Update content types used for autocompletion
        if (this._data)
        {
            if (this._data.useQueryRef)
            {
                this._updateContentTypesFromSavedQuery(this._data.queryReferenceId);
            }
            else
            {
                this._updateContentTypes(this._data.contentTypes);
            }
        }
        else
        {
            this._updateContentTypes([]);
        }
        
    },
    
    /**
     * Set the content types used for autocompletion in the solr-code widget
     * Set the _codeWidgetParams value to use when creating new solr-code widget in repeater
     * @param {String[]} ctypes the list of content type id
     */
    _updateContentTypes: function (ctypes) {
        this._codeWidgetParams = {
            singleLine: true,
            ctypes: ctypes
        };
        
        this._form.query("solr-code").forEach(function(component) {
            component.setContentTypes(ctypes);
        });
        
    },
    
    
    /**
     * @protected
     * Retrieves the form configuration elements for clauses
     * @return {Object} the form configuration elements
     */
    _getClausesFormConfiguration: function()
    {
        var configuration = {};
        
        // Repeater for clauses
        var composition = {};
        configuration.clauses = {
            name: 'clauses',
            type: 'repeater',
            label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CLAUSE_REPEATER_LABEL}}",
            description: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CLAUSE_REPEATER_DESCRIPTION}}",
            'add-label': "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CLAUSE_REPEATER_ADD_LABEL}}",
            'del-label': "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CLAUSE_REPEATER_DELETE_LABEL}}",
            'min-size': 1,
            elements: composition
        };
        
        // single clause field
        var clauseWidgetParams = {};
        Ext.apply(clauseWidgetParams, this._codeWidgetParams);
        Ext.apply(clauseWidgetParams, {height: 66, mode: 'text/x-solr-ametys'});
        composition.clause = {
            type: 'string',
            label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CLAUSE_INPUT_LABEL}}",
            description: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CLAUSE_INPUT_DESCRIPTION}}",
            widget: 'edition.solr-code',
            'widget-params': clauseWidgetParams
        };
        
        return configuration;
    },
    
    /**
     * @protected
     * Retrieves the form configuration elements for query type
     * @return {Object} the form configuration elements
     */
    _getQueryTypeFormConfiguration: function()
    {
        var configuration = {};
        
        // Query type field
        configuration.queryType  = {
            type: 'string',
            label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_QUERY_TYPE_LABEL}}",
            description: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_QUERY_TYPE_DESCRIPTION}}",
            enumeration: [{
                value: 'empty',
                label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_QUERY_TYPE_EMPTY_LABEL}}"
            },
            {
                value: 'ref',
                label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_QUERY_TYPE_REF_LABEL}}"
            }],
            validation: {
                mandatory: true
            }
        };
        
        // Content types field
        configuration.contentTypes = {
            type: 'string',
            label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CONTENT_TYPES_LABEL}}",
            description: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_CONTENT_TYPES_DESCRIPTION}}",
            multiple: true,
            widget: 'edition.select-content-types',
            enumeration: null, // necessary because 'edition.select-content-types' is a widget for enumerated only
            enumerationConfig: {
                excludeReferenceTable: false
            },
            disableCondition: {
                condition: [{
                    id: 'queryType',
                    operator: 'neq',
                    value: 'empty'
                }]
            },
            validation: {
                mandatory: true
            }
        };
        
        // referenced query field
        configuration.queryReferenceId = {
            type: 'string',
            label: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_REFERENCED_QUERY_LABEL}}",
            description: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_REFERENCED_QUERY_DESCRIPTION}}",
            widget: 'edition.select-query',
            'widget-params': {
                acceptedQueryTypes: ['simple', 'advanced', 'solr']
            },
            disableCondition: {
                condition: [{
                    id: 'queryType',
                    operator: 'neq',
                    value: 'ref'
                }]
            },
            validation: {
                mandatory: true
            }
        };
        
        return configuration;
    },
    
    _onFieldChanged: function(field)
    {
        this.callParent(arguments);
        
        if (field.getInitialConfig('name') == 'contentTypes')
        {
            this._updateContentTypes(field.getValue());
        }
        else if (field.getInitialConfig('name') == 'queryReferenceId')
        {
            this._updateContentTypesFromSavedQuery(field.getValue());
        }
    },
    
    /**
     * @private
     * Send the saved query content types to SolrHint for autocompletion
     * @param {String} queryId The identifier of the query
     */
    _updateContentTypesFromSavedQuery: function(queryId)
    {
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.extraction.edition.EditExtractionNodeManager",
            methodName: "getSavedQueryContentTypes",
            parameters: [queryId],
            callback: {
                handler: this._updateContentTypes,
                scope: this
            },
            errorMessage: {
                category: this.self.getName(),
                msg: "{{i18n PLUGINS_EXTRACTION_EDIT_NODE_ERROR_MSG}}"
            }
        });
    },
    
    _getInitFormCreationValues: function()
    {
        var fromParent = this.callParent(arguments);
        var values = fromParent.values || {};
        var repeaters = fromParent.repeaters || [];
    
        return {
            values: values,
            repeaters: repeaters
        };
    },
    
    _getInitFormEditionValues: function()
    {
        var fromParent = this.callParent(arguments);
        var values = fromParent.values;
        var repeaters = fromParent.repeaters;
        
        values.queryType = this._data.useQueryRef ? 'ref' : 'empty';
        
        Ext.Array.forEach(this._data.clauses, function(clause, index) {
            var realIndex = index + 1; // indexes for repeater begin at 1
            values["clauses["  + realIndex + "]" + this._separator + "clause"] = clause;
        }, this);
        
        repeaters.push({
            name: "clauses",
            prefix: "",
            count: Ext.Array.max([this._data.clauses.length, 1])
        });
    
        return {
            values: values,
            repeaters: repeaters
        };
    },
    
    /**
     * @protected
     * Gets the values of the form
     * @return {Object} The form values
     */
    _getFormValues: function()
    {
        var values = this.callParent(arguments);
        
        // get keys without clauses repeaters keys
        var keys = Ext.Object.getKeys(values);
        var resultKeys = Ext.Array.filter(keys, function(key) {
            return !Ext.String.startsWith(key, "clauses" + this._separator) && !Ext.String.startsWith(key, "_clauses");
        }, this);
        
        // copy values except clauses repeaters keys and add clauses and clauses variables
        var result = Ext.copy({}, values, resultKeys);
        
        // get clauses from values
        var clauses = [];
        var countClauses = values['_clauses' + this._separator + 'size'];
        for (var index = 1; index <= countClauses; index++) { //the repeater begins its counter at 1
            var clause = values["clauses["  + index + "]" + this._separator + "clause"];
            if (!Ext.isEmpty(clause))
            {
                clauses.push(clause);
            }
        }
        result.clauses = clauses;
                
        return result;
    }
 });