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

/**
 *@private
 * Class handling the select values dialog box
 */
Ext.define('Ametys.plugins.contenttypeseditor.form.field.SelectValuesHelper', {

    singleton: true,
    
    /**
     * @private
     * @property {Function} _cbFn the callback function used when the dialog box closes
     */
    
    /**
     * @private
     * @property {Ext.grid.Panel} _grid the grid panel of the dialog box
     */
    
    /**
     * @private
     * @property {Ametys.window.DialogBox} _box the dialog box
     */
    
    /**
     * Create the select values dialog box.
     * @param {Object} config The configuration options :
     * @param {String} config.title the title of a dialog box
     * @param {String} config.iconCls The CSS class for the icon of the dialog box
     * @param {String} config.isMultilingual true if value column is multilingual
     * @param {String} config.columnLabelName the name of label column (first column on left)
     * @param {String} config.columnValueName the name of value column (last column on right)
     * @param {String} config.columnLabelRegexp the name of label column (first column on left)
     * @param {String} config.columnValueRegexp the name of value column (last column on right)
     * @param {String} config.addButtonName the name of the add button
     * @param {String} config.addButtonDescription the description of the add button
     * @param {String} config.removeButtonName the name of the remove button
     * @param {String} config.removeButtonDescription the description of the remove button
     * @param {String} config.defaultLabel the default value if a new entry is created for the label column
     * @param {String} config.defaultValue the defaul value if a new entry is created for the value column
     * @param {String} config.valuesAsString the values of the form under the form of a string
     * @param {Function} config.callback the callback function to invoke when the select values process is over
     * @param {Object[]} config.callback.values An array of object with 'label' and 'value'
     */
    create: function(config)
    {
        this._cbFn = config.callback;
        
        var title = config.title || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_TITLE}}";
        var iconCls = config.iconCls || 'ametysicon-write13';
        var isMultilingual = config.isMultilingual || false;
        var columnLabelName = config.columnLabelName || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_COL_LABEL}}";
        var columnValueName = config.columnValueName || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_COL_VALUE}}";
        var columnLabelRegexp = config.columnLabelRegexp || "";
        var columnValueRegexp = config.columnValueRegexp || "";
        var addButtonName = config.addButtonName || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_ACTION_ADD_LABEL}}";
        var addButtonDescription = config.addButtonDescription || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_ACTION_ADD_DESCRIPTION}}";
        var removeButtonName = config.removeButtonName || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_ACTION_DEL_LABEL}}";
        var removeButtonDescription = config.removeButtonDescription || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_ACTION_DEL_DESCRIPTION}}";
        var defaultLabel = config.defaultLabel || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_ACTION_ADD_DEFAULTLABEL}}";
        var defaultValue = config.defaultValue || "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_GRID_ACTION_ADD_DEFAULTVALUE}}";
        var values = config.values || "";
        
        
        this._initialize(title, iconCls, isMultilingual, columnLabelName, columnValueName, columnLabelRegexp, columnValueRegexp, addButtonName, addButtonDescription, removeButtonName, removeButtonDescription, defaultLabel, defaultValue);
        
        this._box.show();
        
        if (config.values)
        {
            this._load(values);
        }
    },
    
    /**
     * Load the values in the form
     * @param {String} values the form's values under the form of a string
     */
    _load: function(values)
    {
        var data = [];
        
        if (values)
        {
            data = values; 
        }
        
        this._grid.getStore().loadData(data, false);
        
        if (data.length > 0)
        {
            this._grid.getSelectionModel().select(0);
            this._grid.getView().focusRow(0);
        }
    },
    
    /**
     * Initialize the box and its grid panel
     */
    _initialize: function(title, iconCls, isMultilingual, columnLabelName, columnValueName, columnLabelRegexp, columnValueRegexp, addButtonName, addButtonDescription, removeButtonName, removeButtonDescription, defaultLabel, defaultValue)
    {
        var columns = [];
        columns.push({
            header: columnLabelName, 
            width: 180,
            sortable: false,
            dataIndex: 'label',
            editor: Ext.create('Ext.form.field.Text', { 
                allowBlank: false,
                selectOnFocus: true,
                regex: columnLabelRegexp
            })
        });
        
        if (isMultilingual)
        {
           columns.push({
                header: columnValueName,
                flex: 1,
                sortable: false,
                dataIndex: 'value',
                editor: 
                {
                    xtype: "enhancedmultilingualstring",
                    allowBlank: true,
                    name: 'values',
                    id: 'values',
                    regex: columnValueRegexp
                },
                renderer: function(value)
                {
                    // This renderer allow to display the value according to the current language used or the value if it's not a multilingual value
                    if (value)
                    {
		                var language = Ametys.cms.language.LanguageDAO.getCurrentLanguage();
		                var result = "";
		                if (value.isMultilingual)
		                {
		                    result = value.values[language];
		                }
		                else
		                {
		                    result = value.values;
		                }
		                return result;
		            }
                    else
                    {
                        return "";
                    }
                }
            }) 
        }
        else
        {
            columns.push({
                header: columnValueName,
                flex: 1,
                sortable: false,
                dataIndex: 'value',
                editor: Ext.create('Ext.form.field.Text', { 
                    allowBlank: true,
                    selectOnFocus: true,
                    regex: columnValueRegexp
                })
            })    
        }
        
        this._grid = Ext.create('Ext.grid.Panel', 
        {
            border: false,
            scrollable: true,
            
            store: Ext.create('Ext.data.ArrayStore', 
            {
                fields: ['label', 'value']
            }),
            
            selModel: 'cellmodel',
            
            plugins: {
                ptype: 'cellediting',
                clicksToEdit: 2
            },
            columns: columns,
            columnLines: true,
          
            viewConfig: {
                forceFit: true
            },
          
            // inline toolbars
            bbar:
            [
                {
                    xtype: 'button',
                    flex: 0.5,
                    text: addButtonName,
                    tooltip: addButtonDescription,
                    handler: Ext.bind(this._add, this, [defaultLabel, defaultValue, isMultilingual])
                },
                '-',
                {
                    xtype: 'button',
                    itemId: 'removeButton',
                    flex: 0.5,
                    text: removeButtonName,
                    tooltip: removeButtonDescription,
                    disabled: true,
                    handler: this._remove,
                    scope: this
                }
            ],
              
            listeners: {
                'selectionchange': Ext.bind(this._onSelectionChange, this),
                'edit': function(editor, context) {
                    context.record.commit();
                }
            }
        });
        
        this._box = Ext.create('Ametys.window.DialogBox', 
        {
            title: title,
            icon: iconCls,
            
            width: 500,
            height: 295,
            
            cls: 'ametys',
            layout: 'fit',
            
            items: [ this._grid ],
            
            defaultFocus: this._grid,
            closeAction: 'destroy',
            
            referenceHolder: true,
            defaultButton: 'validate', 
            
            buttons: 
            [ 
                {
                    reference: 'validate',
                    text : "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_OK}}",
                    handler: this._validate,
                    scope: this
                },
                {
                    text : "{{i18n PLUGINS_CONTENTTYPESEDITOR_SELECT_VALUES_HELPER_CANCEL}}",
                    handler: this._cancel,
                    scope: this
                }
            ]
        });
    },
    
    
    /**
     * Add a value in the grid's store. Starts the edition of a new value
     */
    _add: function(defaultLabel, defaultValue, isMultilingual)
    {
        var store = this._grid.getStore(),
            sm = this._grid.getSelectionModel(),
            pos;
            
        if (sm.hasSelection())
        {
            pos = {row: sm.getPosition().rowIdx + 1, column: 0};
        }
        else
        {
            pos = {row: store.getCount(), column: 0};
        }
        
        var value = [];
        if (isMultilingual)
        {
            value = {
                isMultilingual: false,
                values: defaultValue
            }
        }
        else
        {
            value = defaultValue
        }
        
        var record = Ext.create('Ext.data.Record', 
        {
            label: defaultLabel,
            value: value
        }); 

        store.insert(pos.row, [record]);
        this._grid.editingPlugin.startEditByPosition(pos);
    },
    
    /**
     * Remove the selected record from the grid's store
     */
    _remove: function()
    {
        var store = this._grid.getStore();
        var sm = this._grid.getSelectionModel();
        
        if (sm.hasSelection())
        {
            store.remove(sm.getSelection());
        }
    },
    
    /**
     * Function invoked when a grid record is selected
     */
    _onSelectionChange: function()
    {
        var sm = this._grid.getSelectionModel();
        this._grid.down('#removeButton').setDisabled(!sm.hasSelection());
    },
    
    /**
     * @private
     * When the 'ok' button is pressed 
     */
    _validate: function()
    {
        if (Ext.isFunction(this._cbFn))
        {
	        var values = [];
	                       
	        var store = this._grid.getStore()
	       
	        for (var i = 0; i < store.getCount(); i++)
	        {
                var label = store.getAt(i).get('label');
                var value = store.getAt(i).get('value');
                
                values.push({
                    label: label,
                    value: value
                });
            }  
            
            this._cbFn(values);
        }
        this._box.close();
    },
    
    /**
     * @private
     * When the cancel button is pressed
     */
    _cancel: function()
    {
        this._box.close();
    }
    
});