/*
 *  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.
 */
/**
 * This class is a singleton to set the root page of a organisation chart
 */
Ext.define('Ametys.plugins.userdirectory.SetOrganisationChartRootAction', {
    singleton: true,
    
    /**
     * @private
     * @property {Boolean} _initialized Indicates if the dialog box has been initialized
     */
    
    /**
     * @private
     * @property {Ametys.form.ConfigurableFormPanel} _formPanel The form panel
     */
    
    /**
     * @private
     * @property {Ametys.window.DialogBox} _box The dialog box
     */
    
    /**
     * Opens the dialog box to set/reset the selected page as a root of a organisation chart.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    act: function(controller)
    {
        var pageId = controller.getMatchingTargets()[0].getParameters().id;
        controller.serverCall('getSupportedContentTypes', [pageId], Ext.bind(this._createDialogBox, this), {arguments: {controller: controller}});
    },
    
    /**
     * @private
     * Creates and shows the dialog box
     * @param {Object[]} contentTypes The available content types for this page
     * @param {Object} arguments The callback arguments
     */
    _createDialogBox: function(contentTypes, arguments)
    {
        if (contentTypes.length < 1)
        {
            Ext.Msg.show({
                title: "{{i18n PLUGINS_USER_DIRECTORY_SET_ORGANISATION_CHART_ROOT_NO_CONTENTTYPE_TITLE}}",
                msg: "{{i18n PLUGINS_USER_DIRECTORY_SET_ORGANISATION_CHART_ROOT_NO_CONTENTTYPE}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.INFO
            });
            return;
        }
        
        var controller = arguments.controller,
            editMode = controller.isPressed(),
            pageId = controller.getMatchingTargets()[0].getParameters().id;
        
        if (!this._initialized)
        {
            this._formPanel = Ext.create('Ametys.form.ConfigurableFormPanel', {
                scrollable: true,
                flex: 1
            });
            
            this._box = Ext.create('Ametys.window.DialogBox', {
                title: "{{i18n PLUGINS_USER_DIRECTORY_SET_ORGANISATION_CHART_ROOT_PAGE_LABEL}}",
                iconCls: 'ametysicon-organization1',
                
                width: 560,
                scrollable: false,
                
                items: [
                    {
                        xtype: 'component',
                        html: "{{i18n PLUGINS_USER_DIRECTORY_ORGANISATION_CHART_ROOT_PAGE_DIALOG_HINT}}",
                        style: {
                            marginBottom: '10px'
                        }
                    }, 
                    this._formPanel
                ],
                
                selectDefaultFocus: true,
                defaultFocus: 'contentType',
                
                referenceHolder: true,
                defaultButton: 'validate',

                closeAction: 'hide',
                
                buttons: [{
                    reference: 'validate',
                    text: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_OK}}",
                    handler: Ext.bind(this._validate, this, [controller], 1)
                }, {
                    itemId: 'removeButton',
                    text: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_REMOVE}}",
                    handler: Ext.bind(this._remove, this, [controller], 1)
                }, {
                    text: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_CANCEL}}",
                    handler: Ext.bind(this._cancel, this)
                }]    
            });
        }
        this._configureFormPanel(contentTypes, controller);
        
        this._box.down('#removeButton').setDisabled(!editMode);
        this._box.show();
    },
    
    /**
     * @private
     * Configure the form panel.
     * @param {Object[]} contentTypes The available content types for this page
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the {@link #act} function
     */
    _configureFormPanel: function(contentTypes, controller)
    {
        if (!this._initialized)
        {
            this._formPanel.configure({
                contentType: {
                    label: "{{i18n PLUGINS_USER_DIRECTORY_ORGANISATION_CHART_ROOT_PAGE_DIALOG_CONTENTTYPE_LABEL}}",
                    description: "{{i18n PLUGINS_USER_DIRECTORY_ORGANISATION_CHART_ROOT_PAGE_DIALOG_CONTENTTYPE_DESCRIPTION}}",
                    type: 'string',
                    enumeration: [], // the displayed content types depend on the current page
                    validation: {
                        mandatory: true
                    }
                },
                'pageVisible' : {
                    label: "{{i18n PLUGINS_USER_DIRECTORY_ORGANISATION_CHART_ROOT_PAGE_DIALOG_PAGE_VISIBLE_LABEL}}",
                    description: "{{i18n PLUGINS_USER_DIRECTORY_ORGANISATION_CHART_ROOT_PAGE_DIALOG_PAGE_VISIBLE_DESCRIPTION}}",
                    type: 'boolean',
                    'default-value': false
                }
            });
            
            this._initialized = true;
        }
        this._initForm(contentTypes, controller.isPressed(), controller.getMatchingTargets()[0].getParameters().id, controller);
    },
    
    /**
     * @private
     * Initialize the form with values
     * @param {Object[]} contentTypes The available content types for this page
     * @param {Boolean} editMode True if in edit mode
     * @param {String} pageId The id of the selected page
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the {@link #act} function
     */
    _initForm: function(contentTypes, editMode, pageId, controller)
    {
        this._formPanel.getField('contentType').getStore().loadData(contentTypes);
        this._formPanel.reset();
        if (editMode)
        {
            controller.serverCall('getRootPageInfo', [pageId], Ext.bind(this._setValues, this));
        }
        else
        {
            this._formPanel.setValues({});
            this._formPanel.getForm().clearInvalid();
        }
    },
    
    /**
     * @private
     * Sets the retrieve values for editing an existing organisation chart root page
     * @param {Object} info The retrieved information
     */
    _setValues: function(info)
    {
        if (info && info.isRoot)
        {
            delete info.isRoot;
            this._formPanel.setValues({values: info});
        }
        else
        {
            this._formPanel.setValues({});
        }
        this._formPanel.getForm().clearInvalid();
    },
    
    /**
    * @private
    * Handler for the 'ok' button of the dialog box
    * @param {Ext.button.Button} button The clicked button
    * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
    */
    _validate: function(button, controller)
    {
        var form = this._formPanel.getForm();
        if (!form.isValid())
        {
            return;
        }
        
        var values = form.getValues();
        var pageId = controller.getMatchingTargets()[0].getParameters().id;
        let pageVisible = values['pageVisible'] == true || values['pageVisible'] == 'true';
        controller.serverCall(
            'setOrganisationChartRoot', 
            [pageId, values.contentType, pageVisible], 
            Ext.bind(this._setOrganisationChartRootCb, this), 
            {waitMessage: this._box, errorMessage: true, arguments: {pageId: pageId}}
        );
    },
    
    /**
     * @private
     * Callback function for the server call of the set of a organisation chart root page
     * @param {Object} response The server response
     * @param {Object} arguments The arguments
     */
    _setOrganisationChartRootCb: function(response, arguments)
    {
        if (!response.error)
        {
            this._box.close();
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.MODIFIED,
                parameters: {major: true},
                targets: {
                    id: Ametys.message.MessageTarget.PAGE,
                    parameters: {
                        ids: [arguments.pageId]
                    }
                }
            });
        }
        else if (response.error && response.error == "invalid-content-type")
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_ERROR_TITLE}}",
                msg: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_ERROR_DESCRIPTION}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
    },
    
    /**
    * @private
    * Handler for the 'remove' button of the dialog box
    * @param {Ext.button.Button} button The clicked button
    * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
    */
    _remove: function(button, controller)
    {
        var pageId = controller.getMatchingTargets()[0].getParameters().id;
        if (!pageId)
        {
            button.disable();
        }
        else
        {
            Ametys.Msg.confirm("{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DELETE_TITLE}}",
                    "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DELETE_CONFIRM}}",
                    Ext.bind(function(btn)
                    {
                        if (btn == 'yes')
                        {
                            controller.serverCall(
                                'removeOrganisationChartRoot', 
                                [pageId], 
                                Ext.bind(this._removeOrganisationChartRootCb, this), 
                                {waitMessage: this._box, errorMessage: true, arguments: {pageId: pageId}}
                            );
                        }
                    }, this),
                    this
            );
        }
    },
    
    /**
     * @private
     * Callback function for the server call of the removing of a organisation chart root page
     */
    _removeOrganisationChartRootCb: function(response, arguments)
    {
        if (response && !response.error)
        {
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.MODIFIED,
                parameters: {major: true},
                targets: {
                    id: Ametys.message.MessageTarget.PAGE,
                    parameters: {
                        ids: [arguments.pageId]
                    }
                }
            });
            this._box.close();
        }
        else if (response.error && response.error == "no-root")
        {
            this._box.down('#removeButton').setDisabled(true);
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_ERROR_TITLE}}",
                msg: "{{i18n PLUGINS_USER_DIRECTORY_ROOT_PAGE_DIALOG_NO_ROOT_DESCRIPTION}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
    },
    
    /**
     * @private
     * Callback for the "cancel" button of the dialog. Close the dialog.
     */
    _cancel: function()
    {
        this._box.close();
    }
});