/*
 *  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 class is a singleton to set the root page of a ugc.
 */
Ext.define('Ametys.plugins.ugc.SetUGCRootAction', {
    singleton: true,
    
    /**
     * @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 ugc.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    act: function(controller)
    {
    	var contentType = controller.getConfig("ugc-content-type");
    	var metadata = controller.getConfig("ugc-metadataPath");
        var isClassificationPageVisible = controller.getConfig("ugc-page-visible");
        
    	var pageId = controller.getMatchingTargets()[0].getParameters().id;
        if (metadata != null && isClassificationPageVisible != null)
        {
		    this._createConfirmBox(controller, contentType, pageId, metadata, isClassificationPageVisible);
        }
        else
        {
            this._createDialogBox(controller, contentType, pageId, metadata, isClassificationPageVisible);
        }
    },
    
    /**
     * @private
     * Creates confirm box to set the root page. This case appends when the classification metadata is fixed or null
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Object} contentType The content types for this page
     * @param {Object} pageId the page id
     * @param {Object} metadata The classification metadata path
     * @param {Boolean} isClassificationPageVisible true if the transitional pages are visible
     */
    _createConfirmBox: function(controller, contentType, pageId, metadata, isClassificationPageVisible)
    {
    	var state = controller.isPressed();
        if (state) // We remove the ugc root
        {
        	Ametys.Msg.confirm("{{i18n PLUGINS_UGC_ROOT_PAGE_DELETE_TITLE}}",
        			controller.getConfig("ugc-dialog-delete-confirm"),
        			Ext.bind(function(btn)
					{
        				if (btn == 'yes')
        				{
        					this._removeUGCRoot(controller, pageId);
        				}
					}, this),
					this
        	);
        }
        else // We set the ugc root
        {
        	Ametys.Msg.confirm("{{i18n PLUGINS_UGC_SET_ROOT_PAGE_BOX_TITLE}}",
        			controller.getConfig("ugc-dialog-confirm"),
        			Ext.bind(function(btn)
					{
        				if (btn == 'yes')
        				{
        					this._setUGCRoot(controller, contentType, pageId, metadata, isClassificationPageVisible);
        				}
					}, this),
					this
        	);
        }
    },
    
    /**
     * @private
     * Creates and shows the dialog box. This case appends when the user need to choose the classification metadata
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Object} contentType The content types for this page
     * @param {Object} pageId the page id
     * @param {Object} [metadata] The classification metadata path. Can be null
     * @param {Boolean} [isClassificationPageVisible] true if the transitional pages are visible. Can be null
     */
    _createDialogBox: function(controller, contentType, pageId, metadata, isClassificationPageVisible)
    {
        var editMode = controller.isPressed();
        
        this._formPanel = Ext.create('Ametys.form.ConfigurableFormPanel', {
            scrollable: true,
            flex: 1
        });
        
        this._box = Ext.create('Ametys.window.DialogBox', {
            title: controller.getConfig("ugc-dialog-title"),
            iconCls: controller.getConfig("ugc-dialog-icon"),
            
            width: 560,
            scrollable: false,
            
            items: [
                {
                    xtype: 'component',
                    html: controller.getConfig("ugc-dialog-hint"),
                    style: {
                        marginBottom: '10px'
                    }
                }, 
                this._formPanel
            ],
            
            selectDefaultFocus: true,
            defaultFocus: 'metadata',
            
            referenceHolder: true,
            defaultButton: 'validate',

            closeAction: 'destroy',
            
            buttons: [{
                reference: 'validate',
                text: "{{i18n PLUGINS_UGC_SET_ROOT_PAGE_BOX_VALIDATE}}",
                handler: Ext.bind(this._validate, this, [controller, contentType, pageId, metadata, isClassificationPageVisible], 1)
            }, {
                itemId: 'removeButton',
                text: "{{i18n PLUGINS_UGC_SET_ROOT_PAGE_BOX_REMOVE}}",
                handler: Ext.bind(this._remove, this, [controller, pageId], 1)
            }, {
                text: "{{i18n PLUGINS_UGC_SET_ROOT_PAGE_BOX_CANCEL}}",
                handler: Ext.bind(this._closeBox, this)
            }]    
        });
        
        this._configureFormPanel(controller, contentType, metadata, isClassificationPageVisible);
        
        this._initForm(controller, pageId, editMode);
        this._box.down('#removeButton').setDisabled(!editMode);
        this._box.show();
    },
    
    /**
     * @private
     * Configure the form panel.
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the {@link #act} function
     * @param {Object} contentType The content types for this page
     * @param {Object} [metadata] The classification metadata path. Can be null
     * @param {Boolean} [isClassificationPageVisible] true if the transitional pages are visible. Can be null.
     */
    _configureFormPanel: function(controller, contentType, metadata, isClassificationPageVisible)
    {
        var configuration = {};
        if (metadata == null)
        {
            configuration['metadata'] = {
                label: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_METADATA_LABEL}}",
                description: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_METADATA_DESCRIPTION}}",
                type: 'string',
                widget: 'edition.select-metadata',
                'widget-params': {
                    contentTypes: contentType,
                    multiple: false,
                    acceptedTypes: 'STRING[ENUMERATED],CONTENT',
                    includeSubRepeaters: false,
                    stacked: true
                },
                validation: {
                    mandatory: true
                }
            };
        }
        
        if (isClassificationPageVisible == null)
        {
            configuration['is-visible'] = {
                label: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_IS_VISIBLE_LABEL}}",
                description: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_IS_VISIBLE_DESCRIPTION}}",
                type: 'boolean',
                'default-value': false
            }
        }
        
        this._formPanel.configure(configuration);
    },
    
    /**
     * @private
     * Initialize the form with values
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the {@link #act} function
     * @param {String} pageId The id of the selected page
     * @param {Boolean} editMode True if in edit mode
     */
    _initForm: function(controller, pageId, editMode)
    {
        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 ugc 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
    * @param {Object} contentType The content type for this page
    * @param {Object} pageId the page id
    * @param {Object} [metadata] The classification metadata path. Can be null
    * @param {Boolean} [isClassificationPageVisible] true if the transitional pages are visible. Can be null
    */
    _validate: function(button, controller, contentType, pageId, metadata, isClassificationPageVisible)
    {
        var form = this._formPanel.getForm();
        if (!form.isValid())
        {
            return;
        }
        
        var values = form.getValues();
        var metadataValue = metadata != null ? metadata : values['metadata'];
        var isVisibleValue = isClassificationPageVisible != null ? isClassificationPageVisible : values['is-visible'];
        
    	this._setUGCRoot(controller, contentType, pageId, metadataValue, isVisibleValue);
	},
    
    /**
     * @private
     * Set UGC root
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Object} contentType The content type for this page
     * @param {Object} pageId the page id
     * @param {Object} metadata The classification metadata
     * @param {Boolean} isClassificationPageVisible true if the transitional pages are visible
     */
    _setUGCRoot: function(controller, contentType, pageId, metadata, isClassificationPageVisible)
    {
        var isVisible = isClassificationPageVisible == true || isClassificationPageVisible == 'true';
    	controller.serverCall(
                'setUGCRoot', 
                [pageId, contentType, metadata, isVisible], 
                Ext.bind(this._setUGCRootCb, this), 
                {waitMessage: this._box, errorMessage: true, arguments: {pageId: pageId}}
        );
    },
    
    /**
     * @private
     * Callback function for the server call of the set of a ugc root page
     * @param {Object} response The server response
     * @param {Object} arguments The arguments
     */
    _setUGCRootCb: function(response, arguments)
    {
        if (!response.error)
        {
            this._closeBox();
            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 == "wrong-content-type")
    	{
        	Ametys.Msg.show({
                title: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_ERROR_TITLE}}",
                msg: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_ERROR_WRONG_CONTENT_TYPE}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
    	}
        else if (response.error == "wrong-metadata")
    	{
        	Ametys.Msg.show({
                title: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_ERROR_TITLE}}",
                msg: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_ERROR_WRONG_METADATA}}",
                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
    * @param {String} pageId The id of the page that will no longer be the UGC root page
    */
    _remove: function(button, controller, pageId)
    {
        if (!pageId)
        {
            button.disable();
        }
        else
        {
            Ametys.Msg.confirm("{{i18n PLUGINS_UGC_ROOT_PAGE_DELETE_TITLE}}",
                    controller.getConfig("ugc-dialog-delete-confirm"),
                    Ext.bind(function(btn)
                    {
                        if (btn == 'yes')
                        {
                            this._removeUGCRoot(controller, pageId);
                        }
                    }, this),
                    this
            );
        }
    },
    
    /**
     * @private
     * Remove UGC root
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Object} pageId the page id
     */
    _removeUGCRoot: function(controller, pageId)
    {
    	controller.serverCall(
                'removeUGCRoot', 
                [pageId], 
                Ext.bind(this._removeUGCRootCb, this), 
                {waitMessage: this._box, errorMessage: true, arguments: {pageId: pageId}}
            );
    },
    
    /**
     * @private
     * Callback function for the server call of the removing of a ugc root page
     */
    _removeUGCRootCb: 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._closeBox();
        }
        else if (response.error && response.error == "no-root")
        {
            this._box.down('#removeButton').setDisabled(true);
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_UGC_ROOT_PAGE_DIALOG_ERROR_TITLE}}",
                msg: "{{i18n PLUGINS_UGC_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.
     */
    _closeBox: function()
    {
    	if (this._box)
    	{
    		this._box.close();
    	}
    }
});