/*
 *  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 edit a simple string or multilingual string.<br>
 * The form displays a checkbox have a simple string or text field for each configured languages.<br>
 * See #open method
 */
Ext.define("Ametys.plugins.contenttypeseditor.form.field.EnhancedEditMultilingualString", {
    singleton: true,
    
    /**
     * @property _cbFn {Function} The callback function to call after editing enhanced multilingual string
     * @private
     */
    
    /**
     * @property _allowBlank {Boolean} If 'false' check at least one value is not empty before validating
     * @private
     */
    
    /**
     * @property _box {Ametys.window.DialogBox} The dialog box
     * @private
     */
    
    /**
     * @property _blankErrorActive {Boolean} True when the allowBlank validation fails
     * @private
     */
    
    /**
     * @property _isMultilingual {Boolean} True if user edit multilingual string
     * @private
     */
    
    /**
     * @property _multilingualStringForm {Ext.form.Panel} Multilingual string form
     * @private
     */
    
    /**
     * @property _simpleStringField {Ext.form.field.Text} Simple string textfield
     * @private
     */

    /**
     * Open dialog to edit a simple string or each language's values of a multilingual string
     * @param {Object} config The configuraiton options:
     * @param {Object[]} config.languages (required) Array of the available languages. Excepted properties for each language are:
     * @param {Object[]} config.languages.name The language code such as 'fr', 'en'
     * @param {Object[]} config.languages.label The language label
     * @param {String} config.title (required) The title of the dialog box.
     * @param {String} [config.iconCls="ametysicon-edit45"] One or more space separated CSS classes to be applied to the dialog icon
     * @param {String} [config.icon] The full path to icon (16x16 pixels) for the dialog box
     * @param {Object} [config.values] The values to display at startup
     * @param {Boolean} [config.allowBlank=true] Set to 'false' to validate that at least one value is not empty
     * @param {Function} config.callback The method that will be called when the dialog box is closed.
     * @param {Object} config.callback.isMultilingual True if values are multilingual
     * @param {Object} config.callback.values The edited values for each languages o just a simple string
     */
    open: function(config)
    {
        this._cbFn = config.callback;
        this._allowBlank  = !(config.allowBlank === false);
        this._blankErrorActive = false;
        
        var languages = config.languages || [];
        if (languages.length == 0)
        {
            // No available languages
            Ametys.Msg.alert("{{i18n PLUGINS_CONTENTTYPESEDITOR_HELPER_EDIT_ENHANCED_MULTILINGUAL_NO_LANGUAGE_ERROR}}");
            return;    
        }
        
        this._initialize(config);  
        
        this._box.show();
        
        // set focus on first text field
        this._getForm().getFields().get(0).focus();
    },
    
    /**
     * Initialize the dialog box
     * @param {Object} config The configuraiton options:
     * @param {Object[]} config.languages (required) Array of the available languages. Excepted properties for each language are:
     * @param {Object[]} config.languages.name The language code such as 'fr', 'en'
     * @param {Object[]} config.languages.label The language label
     * @param {String} config.title (required) The title of the dialog box.
     * @param {String} [config.iconCls="ametysicon-edit45"] One or more space separated CSS classes to be applied to the dialog icon
     * @param {String} [config.icon] The full path to icon (16x16 pixels) for the dialog box
     * @param {Object} [config.values] The values to display at startup
     * @private
     */
    _initialize:  function(config)
    {
        var values = config.values || {};
        var languages = config.languages;
        
        var items = [];
        
        var me = this;
        Ext.Array.each(languages, function(language) {
            items.push(Ext.apply({
                fieldLabel: language.label,
                name: language.name,
                id: language.name,
                value: values.isMultilingual ? values.values[language.name] || '' : '',
                listeners: {
                    change: Ext.bind(me._onChange, me)
                }
            }, config.itemConfig || {}));
        });
        
        this._isMultilingual = values.isMultilingual;
        
        this._multilingualStringForm = Ext.create('Ext.form.Panel', {
            defaults: {
                xtype: 'textfield',
                cls: 'ametys',
                labelSeparator: '',
                labelWidth: 80,
                width: '100%',
                msgTarget: 'side'
            },
            hidden: !this._isMultilingual,
            border: false,
            items: items
        });
        
        this._simpleStringField = Ext.create('Ext.form.field.Text', {
            fieldLabel: config.title,
            hidden: this._isMultilingual,
            value: !this._isMultilingual ? values.values : ''
        });

        this._createDialogBox(config.title, config.icon, config.iconCls);
    },
    
    /**
     * @private
     * Creates the dialog box
     * @param {String} title the title of the box
     * @param {String} icon The icon of the dialog as an image
     * @param {String} iconCls The css class for the icon (for glyph purposes)
     */
    _createDialogBox: function(title, icon, iconCls)
    {
        this._form = this._createFormPanel();
        
        this._box = Ext.create('Ametys.window.DialogBox', {
            title: title,
            icon: icon,
            iconCls: icon ? null : iconCls || 'ametysicon-edit45',
            
            width: 500,
            scrollable: true,
            layout: 'fit',
            
            items: [this._form],

            closeAction: 'destroy',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            listeners: {
                close: Ext.bind(this._onClose, this)
            }
        });
    },
    
    /**
     * @private
     * Creates the form
     * @return {Ext.form.Panel} the panel
     */
    _createFormPanel: function()
    {
        var formPanel = Ext.create('Ext.form.Panel', {
            defaults: {
                cls: 'ametys',
                labelSeparator: '',
                labelWidth: 80,
                width: '100%',
                msgTarget: 'side'
            },
            items: [
                {
                    xtype: 'checkbox',
                    boxLabel: "{{i18n PLUGINS_CONTENTTYPESEDITOR_HELPER_EDIT_ENHANCED_MULTILINGUAL_CHECKBOX_MULTILINGUAL_LABEL}}",
                    checked: this._isMultilingual,
                    listeners: {
				        change: Ext.bind(this._onCheckedChange, this)
                     }
                },
                this._simpleStringField,
                this._multilingualStringForm
            ],
            
            buttons : [{
                reference: 'validate',
                text :"{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_CONTENT_TYPE_DIALOG_OK}}",
                handler : Ext.bind(this._ok, this)
            }, {
                text :"{{i18n PLUGINS_CONTENTTYPESEDITOR_EDIT_CONTENT_TYPE_DIALOG_CANCEL}}",
                handler: Ext.bind(function() {this._box.close();}, this) 
            }]
            
        });
        
        return formPanel;
    },
    
    /**
     * @private
     * Listener when the checkbox to select i18n or not has changed its value
     * @param {Ext.form.field.ComboBox} field The combobox
     * @param {Boolean} newValue The new value
     * @param {Boolean} oldValue The old value
     */
    _onCheckedChange: function(field, newValue, oldValue)
    {
        this._isMultilingual = newValue;
        var language = Ametys.cms.language.LanguageDAO.getCurrentLanguage();
        if (newValue)
        {
            this._multilingualStringForm.setHidden(false);
            this._simpleStringField.setHidden(true);
        }
        else
        {
            this._multilingualStringForm.setHidden(true);
            this._simpleStringField.setHidden(false);
        }
    },
    
    /**
     * @private
     * Listener when the value of a field is changed
     * @param {Ext.form.field.Field} fd The field
     * @param {Object} newValue The new value
     * @param {Object} oldValue The original value
     */
    _onChange: function (fd, newValue, oldValue)
    {
        if (this._blankErrorActive && newValue)
        {
            fd.clearInvalid();
            
            this._getForm().getFields().each(function(fd) {
                if (Ext.isEmpty(fd.getValue()))
                {
                    fd.clearInvalid();
                }
            });
            
            this._blankErrorActive = false;
        }
    },
    
    /**
     * Returns the current form
     * @return {Ext.form.Basic} The form
     */
    _getForm: function()
    {
        return this._box.down('form').getForm();  
    },
    
    /**
     * @private
     * Validate the dialog box's form
     */
    _ok: function()
    {
        var form = this._getForm();
        if (!form.isValid())
        {
            return;
        }

        var values = {};
        if (this._isMultilingual)
        {
            var multilingualString = {}
            this._multilingualStringForm.getForm().getFields().each(function(fd) {
	            var value = fd.getValue();
	            if (!Ext.isEmpty(value))
	            {
	                multilingualString[fd.getName()] = value;
	            }
	        });

            values.isMultilingual = true;
            values.values = multilingualString;
        }
        else
        {
            var value =  this._simpleStringField.getValue();
            
            values.isMultilingual = false;
            values.values = value;
        }
        
        if (!this._allowBlank && Ext.Object.isEmpty(values.values))
        {
            this._blankErrorActive = true;
            
            if (values.isMultilingual)
            {
                this._multilingualStringForm.getForm().getFields().each(function(fd) {
	                fd.markInvalid("{{i18n PLUGINS_CONTENTTYPESEDITOR_HELPER_EDIT_ENHANCED_MULTILINGUAL_EDIT_MULTILINGUAL_MANDATORY_ERROR}}");
	            });
            }
            else
            {
                this._simpleStringField.markInvalid("{{i18n PLUGINS_CONTENTTYPESEDITOR_HELPER_EDIT_ENHANCED_MULTILINGUAL_EDIT_SIMPLE_MANDATORY_ERROR}}");
            }
            return;
        }
        
        if (this._cbFn)
        {
            Ext.Function.defer (this._cbFn, 0, null, [values]);
        }
        
        this._validated = true;
        this._box.close();
    },
    
    /**
     * @private
     * Listener when closing the dialog box
     * @param {Boolean} validate true the dialog box was closing after cliking on 'Ok' button
     */
    _onClose: function(validate)
    {
        if (!this._validated && this._cbFn)
        {
            Ext.Function.defer (this._cbFn, 0, null, [null]);
        }
    }
	
});