/*
 *  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 for creating/editing a collection of synchronizable contents
 */
Ext.define('Ametys.plugins.contentio.EditCollectionTool', {
    extend: "Ametys.tool.Tool",
    
    statics: {
        /**
         * @readonly
         * @static
         * @property {Number} DEFAULT_INITIAL_ACTION_ID The default id of the initial action of the workflow
         */
        DEFAULT_INITIAL_ACTION_ID: 11,
        /**
         * @readonly
         * @static
         * @property {Number} DEFAULT_SYNCHRONIZE_ACTION_ID The default id of the synchronize action of the workflow
         */
        DEFAULT_SYNCHRONIZE_ACTION_ID: 800,
        /**
         * @readonly
         * @static
         * @property {Number} DEFAULT_VALIDATE_ACTION_ID The default id of the validate action of the workflow
         */
        DEFAULT_VALIDATE_ACTION_ID: 41
    },
    
    /**
     * @private
     * @property {String} _separator The separator for the {@link Ametys.form.ConfigurableFormPanel}s of the dialog box
     */
    _separator: '/',
    
    /**
     * @private
     * @property {String} _mode The mode of the tool. Can be 'add' or 'edit'
     */
    
    /**
     * @private
     * @property {Ametys.form.ConfigurableFormPanel} _formPanel The wrapped form panel in the widget
     */
    
    createPanel: function()
    {
        this._formPanel = Ext.create('Ametys.form.ConfigurableFormPanel', {
            defaultPathSeparator: this._separator,
            defaultFieldConfig: {
            	labelWidth: 250
            },
            hideDisabledFields: true,
            scrollable: true,
            flex: 1,
            listeners: {
                'inputfocus': Ext.bind(this.sendCurrentSelection, this),
                'fieldchange': Ext.bind(this.setDirty, this, [true], false)
            }
        });
        
        return this._formPanel;
    },
    
    getMBSelectionInteraction: function() 
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
    
    /**
     * @inheritdoc
     * @param {Object} params The params to set
     * @param {String} [params.mode] The mode of the tool. Can be 'add' or 'edit'
     * @param {String} [params.collectionLabel] If mode='edit', this is the label of the collection to edit
     */
    setParams: function(params)
    {
        this.callParent(arguments);
        this._mode = params.mode;
        if (this._mode == 'edit')
        {
            this.setTitle(params.collectionLabel);
        }
        else
        {
            this.setTitle("{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_LABEL_ADD}}");
        }
        
        if (this._formPanel.isFormReady())
        {
            // tool seems to be already opened as the ConfigurableFormPanel is ready
            this._focusAsap();
        }
        else
        {
            Ametys.cms.contentio.SynchronizableContentsCollectionDAO.getEditionConfiguration([], this._getFieldsCb, {scope: this, waitMessage: false});
        }
    },
    
    /**
     * Gets the mode of he tool. Can be 'add' or 'edit' 
     * @return {String} the mode of he tool. Can be 'add' or 'edit'
     */
    getMode: function()
    {
        return this._mode;
    },
    
    /**
     * @private
     * After retrieving from server the fields needed for the creation of a collection, configure the configurable form panel
     * @param {Object} response The server response
     * @param {Object[]} arguments The callback arguments
     */
    _getFieldsCb: function(response, arguments)
    {
        // Remove current collection from existing collections list if we are in edition mode
        let existingSCC = this._mode == 'add'
            ? response.existingSCC
            : response.existingSCC.filter(elt => elt.value != this.getParams().id);
        
        var data = {
            label: {
                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_NAME_LABEL}}",
                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_NAME_DESCRIPTION}}",
                type: 'STRING',
                validation: {
                    mandatory: true
                }
            },
            modelId: {
                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNC_TYPE_LABEL}}",
                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNC_TYPE_DESCRIPTION}}",
                multiple: false,
                type: 'STRING',
                enumeration: [],
                validation: {
                    mandatory: true
                }
            },
            'synchro-contents': {
            	role: 'fieldset',
            	label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENT_FIELDSET_LABEL}}",
            	elements: {
            		contentType: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENTTYPE_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENTTYPE_DESCRIPTION}}",
                        type: 'STRING',
                        enumeration: response.contentTypes,
                        validation: {
                            mandatory: true
                        }
                    },
                    languages: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_LANGUAGES_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_LANGUAGES_DESCRIPTION}}",
                        multiple: true,
                        type: 'STRING',
                        enumeration: response.languages,
                        validation: {
                            mandatory: true
                        }
                    },
		            contentPrefix: {
		                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENT_PREFIX_LABEL}}",
		                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENT_PREFIX_DESCRIPTION}}",
		                type: 'STRING',
		                validation: {
		                    mandatory: true
		                }
		            },
		            restrictedField: {
		                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_RESTRICTED_FIELD_LABEL}}",
		                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_RESTRICTED_FIELD_DESCRIPTION}}",
		                type: 'STRING',
		                widget: 'edition.select-metadata',
		                'widget-params': {
		                	contentTypesField: 'contentType',
		                	acceptedTypes: 'BOOLEAN',
		                	stacked: true,
		                	multiple: false,
		                	includeSubRepeaters: false
		                }
		            },
                    checkCollection: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CHECK_COLLECTION_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CHECK_COLLECTION_DESCRIPTION}}",
                        type: 'BOOLEAN',
                        'default-value': true
                    },
                    compatibleSCC: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_COMPATIBLE_COLLECTIONS_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_COMPATIBLE_COLLECTIONS_DESCRIPTION}}",
                        multiple: true,
                        type: 'STRING',
                        enumeration: existingSCC,
                        disableCondition: {
                            condition: [{
                                id: 'checkCollection',
                                operator: 'neq',
                                value: 'true'
                            }]
                        }
                    },
		            synchronizeExistingContentsOnly: {
		                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNCHRONIZE_EXISTING_CONTENTS_ONLY_LABEL}}",
		                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNCHRONIZE_EXISTING_CONTENTS_ONLY_DESCRIPTION}}",
		                type: 'BOOLEAN'
		            },
		            removalSync: {
		                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_REMOVAL_SYNC_LABEL}}",
		                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_REMOVAL_SYNC_DESCRIPTION}}",
		                type: 'BOOLEAN'
		            },
                    ignoreRestrictions: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_IGNORE_RESTRICTIONS_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_IGNORE_RESTRICTIONS_DESCRIPTION}}",
                        type: 'BOOLEAN',
                        'default-value': true
                    },
		            validateAfterImport: {
		                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_VALIDATE_AFTER_IMPORT_LABEL}}",
		                description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_VALIDATE_AFTER_IMPORT_DESCRIPTION}}",
		                type: 'BOOLEAN'
		            }
            	}
            },
            'workflow': {
                role: 'fieldset',
                label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_WORKFLOW_FIELDSET_LABEL}}",
                elements: {
                	workflowName: {
    				    label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_WORKFLOW_LABEL}}",
    				    description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_WORKFLOW_DESCRIPTION}}",
    				    multiple: false,
    				    type: 'STRING',
    				    enumeration: response.workflows,
    				    'default-value': null,
    				    validation: {
    				        mandatory: true
    				    }
    				},
    				initialActionId: {
    				    label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_INITIAL_ACTION_LABEL}}",
    				    description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_INITIAL_ACTION_DESCRIPTION}}",
    				    type: 'LONG',
    				    'default-value': this.statics().DEFAULT_INITIAL_ACTION_ID,
    				    validation: {
    				        mandatory: true
    				    }
    				},
    				synchronizeActionId: {
    				    label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNCHRONIZE_ACTION_LABEL}}",
    				    description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNCHRONIZE_ACTION_DESCRIPTION}}",
    				    type: 'LONG',
    				    'default-value': this.statics().DEFAULT_SYNCHRONIZE_ACTION_ID,
    				    validation: {
    				        mandatory: true
    				    }
    				},
    				validateActionId: {
    				    label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_VALIDATE_ACTION_LABEL}}",
    				    description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_VALIDATE_ACTION_DESCRIPTION}}",
    				    type: 'LONG',
    				    'default-value': this.statics().DEFAULT_VALIDATE_ACTION_ID,
    				    validation: {
    				        mandatory: true
    				    }
    				}
                }
            },
            'additional-operations' : {
            	role: 'fieldset',
            	label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SYNC_PARAMETERS_FIELDSET_LABEL}}",
            	elements: {
                    contentOperator: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENT_OPERATOR_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_CONTENT_OPERATOR_DESCRIPTION}}",
                        multiple: false,
                        type: 'STRING',
                        enumeration: response.contentOperators,
                        'default-value': response.defaultContentOperator,
                        validation: {
                            mandatory: true
                        }
                    },
            		reportMails: {
                        label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_REPORT_MAILS_LABEL}}",
                        description: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_REPORT_MAILS_DESCRIPTION}}",
                        type: 'STRING',
                        validation: {
                            regexp: /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z0-9][A-Za-z0-9]+)(\n(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z0-9][A-Za-z0-9]+))*$/,
                            invalidText: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_REPORT_MAILS_INVALID}}"
                        },
                        widget: 'edition.textarea',
                        'widget-params': {
                        	charCounter: false
                        }
                    }
            	}
           	}
        };
        
        var sourceConfigFieldset = {
            	role: 'fieldset',
            	label: "{{i18n PLUGINS_CONTENTIO_EDIT_COLLECTION_TOOL_SOURCE_PARAMETERS_FIELDSET_LABEL}}",
            	elements: {}
        }
        
        Ext.Array.forEach(response.models, function(model) {
            // Add an entry into the combobox for selecting the model
            data.modelId.enumeration.push({
                label: model.label,
                value: model.id
            });
            
            // Add the fields for each parameter
            Ext.Object.each(model.parameters, function(parameterId, parameter) {
                // Add a disable condition
                parameter['disableCondition'] = {
                    condition: [{
                        id: "modelId",
                        operator: "neq",
                        value: model.id
                    }]
                };
                
                // The field is ready
                sourceConfigFieldset.elements[parameterId] = parameter;
            }, this);
        }, this);
        
        data["source-configuration"] = sourceConfigFieldset;
        
        this._formPanel.configure(data);
        
        if (this._mode == 'add')
        {
            this._formPanel.setValues({});
            this._focusAsap();
        }
        else
        {
            Ametys.cms.contentio.SynchronizableContentsCollectionDAO.getCollectionParameterValues([this.getParams().id], this._fillFields, {scope: this});
        }
    },
    
    /**
     * @private
     * Fills the form with values.
     * @param {Object} values The data to fill
     */
    _fillFields: function(values)
    {
        this._formPanel.setValues({values: values});
        this._focusAsap();
        
    },
    
    /**
     * @private
     * Try to focus the first field of the form panel as soon as possible
     */
    _focusAsap: function()
    {
        this._formPanel.on({
            'afterlayout': {
                fn: function(formPanel) {
                    formPanel.focus(true);
                },
                single: true
            }
        });
    },
    
    sendCurrentSelection: function()
    {
        Ext.create("Ametys.message.Message", {
            type: Ametys.message.Message.SELECTION_CHANGED,
            targets: {
                id: Ametys.message.MessageTarget.SYNCHRONIZABLE_CONTENTS_COLLECTION,
                parameters: {
                    id: this.getParams().id
                },
                
                subtargets: this._formPanel.getMessageTargetConf()
            }
        });
    },
    
    close: function (manual)
    {
        if (manual && this.getMode() == 'edit' && this.isDirty())
        {
            Ametys.Msg.confirm("{{i18n PLUGINS_CONTENTIO_COLLECTION_UNSAVE_LABEL}}", 
                    "{{i18n PLUGINS_CONTENTIO_COLLECTION_UNSAVE_CONFIRM}}", 
                    function (answer) {
                        if (answer =='yes')
                        {
                            this.setDirty(false);
                            Ametys.plugins.contentio.EditCollectionTool.superclass.close.call(this, [manual]);
                        }
                    },
                    this
            );
            return;
        }
        
        this.callParent(arguments);
    }
});