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

/**
 * This UI helper provides a dialog box to create and edit a metadataRef
 */
Ext.define('Ametys.plugins.contenttypeseditor.editor.EditMetadataRefHelper',  {
    singleton: true,
    
    /**
     * @property {Function} _cbFn The callback function invoked when a metadataref is created/edited
     * @private
     */
    
    /**
     * @property {Ametys.window.DialogBox} _box The dialog box for creating/editing a metadataref.
     * @private
     */
    
    /**
     * @property {String} _mode The current edition mode ('new' or 'edit')
     * @private
     */
    
    /**
     * @property {Ext.form.Panel} _form The form panel
     * @private
     */
    
    /**
     * Configure and open the dialog box
     * @param {Object} config The configuration options :
     * @param {String} config.contentTypeId The id of content type
     * @param {String} config.title The title of dialog box
     * @param {String} config.iconCls The CSS class for the icon of the dialog box
     * @param {String} config.metadataRefInfo All information about the metadataRef to edit
     * @param {String} config.mode The mode. Can only be 'add' or 'edit.
     * @param {String[]} config.metadataNames Names of metadata used for this content type.
     * @param {Function} config.callback The callback function invoked when a new content type is created. The callback function will received the following parameters:
     * @param {Object} config.callback.contentTypeInfos All information about a content type 
     */
    open: function(config)
    {
        this._mode = config.mode || 'add';
        this._contentTypeId = config.contentTypeId;
        this._metadataNames = config.metadataNames;
        this._metadataRefInfo = config.metadataRefInfo;
        this._cbFn = config.callback;
       
        this._createDialogBox(config.title, config.iconCls);
         
        if (this._mode == 'edit')
        {
            this._fillFields(config.metadataRefInfo);
        }
        else
        {
            this._beforeDialogBoxCreated();
        }
        
        this._box.show();
    },
    
    /**
     * @private
     * When editing an existing metadata ref, fill the dialog box with given informations
     * @param {Object} metadataRefInfo The curretly edited metadata-ref
     */
    _fillFields: function(metadataRefInfo)
    {
        this._form.getForm().findField("metadataref-type").setValue(metadataRefInfo.dataType);
        this._form.getForm().findField("metadataref-type").setDisabled(true);
        if (metadataRefInfo.dataType == "model_item_ref")
        {
            this._displayFieldsetField(false);
            this._displayMetadataRefField(true);
            this._form.getForm().findField("metadataref-metadata-name").setValue(metadataRefInfo.name);
        }
        else if (metadataRefInfo.dataType == "fieldset")
        {
            this._displayMetadataRefField(false);
            this._displayFieldsetField(true);
            this._form.getForm().findField("fieldset-role").setValue(metadataRefInfo.role);
            this._form.getForm().findField("fieldset-label").setValue(metadataRefInfo.label);
        }
    },
    
    /**
     * Create the dialog box
     * @private
     * @param {String} title The dialog box title
     * @param {String} iconCls The css class to use as the dialog box icon
     */
    _createDialogBox: function(title, iconCls)
    {
        var defaultFocus = 'metadataref-type';
        if (this._mode == "edit")
        {
            if (this._metadataRefInfo.dataType == "model_item_ref")
            {
                defaultFocus = 'metadataref-metadata-name';
            }
            else
            {
                defaultFocus = 'fieldset-role';
            }
        }
        
        this._form = this._createFormPanel();
        
        this._box = Ext.create('Ametys.window.DialogBox', {
            title : title || "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATAREF_DIALOG_EDIT_TITLE}}",
            iconCls: iconCls || 'ametysicon-add64',
            width: 600,
            layout: 'fit',
            scrollable: true,
            referenceHolder: true,
            defaultFocus: defaultFocus,

            items: [this._form],
            
            buttons: 
            [
                {
                    text: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATAREF_DIALOG_ACTIONS_FINISH}}",
                    handler: this._validate,
                    scope: this
                }, 
                {
                    text: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATAREF_DIALOG_ACTIONS_CANCEL}}",
                    handler: this._cancel,
                    scope: this
                }
            ],
            
            closeAction: 'destroy'
        })
    },
    
    /**
     * Create the form part of the dialog box
     * @private
     * @return {String} The form
     */
    _createFormPanel: function()
    {
        var formPanel = Ext.create('c', {
            defaults: 
            {
                cls: 'ametys',
                labelSeparator: '',
                labelStyle: 'font-weight: bold',
                labelWidth: 150,
                width: '100%',
                msgTarget: 'side'
            },
            items: 
            [
                {
                    xtype: "combobox",
                    fieldLabel: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_METADATAREF_TYPE_INPUT_LABEL}} *",
                    ametysDescription: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_METADATAREF_TYPE_INPUT_DESCRIPTION}}",
                    name: 'metadataref-type',
                    id: 'metadataref-type',
                    valueField: 'id',
                    displayField: 'label',
                    allowBlank: false,
                    editable: true,
                    forceSelection: true,
                    queryMode: 'local',
                    store: {
                        autoLoad: true,
                        fields: [
                            {name: 'id'},
                            {name: 'label'}
                        ],
                        listeners: 
                        {
                            'beforeload' : this._onBeforeLoadStoreType,
                            scope: this
                        }
                    },
                    listeners: 
                    {
                        'select' : this._onTypeSelected,
                        scope: this
                    
                    }
                },
                {
                    xtype: "combobox",
                    fieldLabel: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_METADATAREF_METADATA_NAME_INPUT_LABEL}} *",
                    ametysDescription: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_METADATAREF_METADATA_NAME_INPUT_DESCRIPTION}}",
                    allowBlank: false,
                    name: 'metadataref-metadata-name',
                    id: 'metadataref-metadata-name',
                    valueField: 'id',
                    displayField: 'name',
                    editable: false,
                    forceSelection: true,
                    queryMode: 'local',
                    store: 
                    {
                        autoLoad: true,
                        sorters: [{property: 'name', direction: 'ASC'}],
                        fields: [
                            {name: 'id'},
                            {name: 'name', type: 'string'},
                            {name: 'path'}
                        ],
                        listeners:
                        {
                            'load' : this._onLoadMetadataName,
                            scope: this
                        }
                    }
                },
                {
                    xtype: "textfield",
                    fieldLabel: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_FIELDSET_ROLE_INPUT_LABEL}} *",
                    ametysDescription: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_FIELDSET_ROLE_INPUT_DESCRIPTION}}",
                    allowBlank: false,
                    name: 'fieldset-role',
                    id: 'fieldset-role',
                    disabled: true,
                    hidden: true
                },
                {
                    xtype: "enhancedmultilingualstring",
                    fieldLabel: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_FIELDSET_LABEL_INPUT_LABEL}} *",
                    ametysDescription: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_METADATASET_DIALOG_FIELDSET_LABEL_INPUT_DESCRIPTION}}",
                    allowBlank: false,
                    name: 'fieldset-label',
                    id: 'fieldset-label',
                    disabled: true,
                    hidden: true
                }
            ]
        });
        
        return formPanel;
    },
    
    /**
     * @private
     * Callback when the contenttype field store is loaded 
     * @param {Ext.data.Store} store The store
     */
    _onBeforeLoadStoreType: function(store)
    {
        store.setData([
            {"label" : "Metadata reference", "id" : "metadata_ref"},
            {"label" : "Fieldset", "id" : "fieldset"}]);
    },
    
    /**
     * Fires when at least one list item is selected.
     * @param {Ext.form.field.ComboBox} combo The combo box
     * @param {Ext.data.Model} record A single record
     */
    _onTypeSelected: function(combo, record)
    {
        this._type = record.id;
        
        if (this._type == "metadata_ref")
        {
            this._displayFieldsetField(false);
            this._displayMetadataRefField(true);
        }
        else if (this._type == "fieldset")
        {
            this._displayMetadataRefField(false);
            this._displayFieldsetField(true);
        }
    },
    
    /**
     * @private
     * When the metadata name field store is loaded
     * @param {Ext.data.Store} store The store
     */
    _onLoadMetadataName: function(store)
    {
        if (this._contentTypeId)
        {
            Ametys.data.ServerComm.callMethod({
                role: "org.ametys.plugins.contenttypeseditor.edition.EditContentTypeInformationHelper",
                methodName: "getAttributeNames",
                parameters: [this._contentTypeId],
                callback: {
                    handler: this._loadMetadataName,
                    arguments: {
                        store: store
                    },
                    scope: this
                }
            }); 
        }
    },
    
    /**
     * @private
     * Callback after #_onLoadMetadataName 
     * @param {Object} metadataNames The metadata names return by the server
     * @param {Object} args Manual args
     * @param {Ext.data.Store} args.store The store with metadata names
     */
    _loadMetadataName: function(metadataNames, args)
    {
        args.store.setData(metadataNames);
        if (this._mode == 'edit')
        {
            if (this._metadataRefInfo.dataType == "model_item_ref")
            {
                this._form.getForm().findField("metadataref-metadata-name").setValue(this._metadataRefInfo.name);
            }
        }
    },
    
    /**
     * Reset and display/hide, enable/disable the metadata name field
     * @private
     * @param {Boolean} display true to display/enable
     */
    _displayMetadataRefField: function(display)
    {
        this._form.getForm().findField("metadataref-metadata-name").setValue("");
        this._form.getForm().findField("metadataref-metadata-name").setDisabled(!display);
        this._form.getForm().findField("metadataref-metadata-name").setHidden(!display);
    },
    
    /**
     * @private
     * Reset and display/hide, enable/disable the fieldsets field
     * @param {Boolean} display true to diaply/enable
     */
    _displayFieldsetField: function(display)
    {
        this._form.getForm().findField("fieldset-role").setValue("");
        this._form.getForm().findField("fieldset-label").setValue("");
        
        this._form.getForm().findField("fieldset-role").setDisabled(!display);
        this._form.getForm().findField("fieldset-label").setDisabled(!display);
        
        this._form.getForm().findField("fieldset-role").setHidden(!display);
        this._form.getForm().findField("fieldset-label").setHidden(!display);
    },
    
    /**
     * @private
     * When adding a reference, called during creation
     */
    _beforeDialogBoxCreated: function()
    {
        this._form.getForm().findField("metadataref-type").setValue("metadata_ref");
        this._displayFieldsetField(false);
        this._displayMetadataRefField(true);
    },
    
    /**
     * @private
     * When validating the dialog box
     */
    _validate: function()
    {
        var isValidForm = this._form.getForm().isValid();
        if (!isValidForm)
        {
            return;
        }
        if (Ext.isFunction(this._cbFn))
        {
            var values = this._getFormValues();
            this._cbFn(values);
        }
        this._box.close();
    },
    
    /**
     * @private
     * Get the values in the form
     * @return {Object} The values (dataType or dataType, role, label, leaf or dataType, name, path, isRepeaterOrComposite, leaf)
     */
    _getFormValues: function()
    {
        var type = this._form.getForm().findField("metadataref-type").getValue();

        var values = {};
        values.dataType = type;
        if (type == "model_item_ref")
        {
            values.name = this._form.getForm().findField("metadataref-metadata-name").getValue();
            values.path = this._form.getForm().findField("metadataref-metadata-name").getStore().getById(values.name).data.path;
            var isRepeaterOrComposite = this._form.getForm().findField("metadataref-metadata-name").getStore().getById(values.name).data.isRepeaterOrComposite;
            values.isRepeaterOrComposite = isRepeaterOrComposite;
            values.leaf = !isRepeaterOrComposite;
        }
        else if (type == "fieldset")
        {
            values.role = this._form.getForm().findField("fieldset-role").getValue();
            values.label = this._form.getForm().findField("fieldset-label").getValue();
            values.leaf = false;
        }
        return values;
    },
    
    /**
     * @private
     * When clicking on cancel button
     */
    _cancel: function()
    {
        this._box.close();
    }
    
});