/*
 *  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 defines methods to retrieve and configure service parameters.
 */
Ext.define("Ametys.plugins.web.zone.ZoneItemManager", {
    singleton: true,
    
    constructor: function(config)
    {
        /**
         * @callable
         * @param member Ametys.plugins.web.zone.ZoneItemManager
         * @method getServiceParameterDefinitions
         * Retrieves the parameter definitions of the given service
         * This calls the method 'getServiceParameterDefinitions' of the server DAO 'org.ametys.web.repository.page.ZoneItemManager'.
         * @param {Object[]} parameters The parameters to transmit to the server method
         * @param {String} parameters.serviceId Identifier of the service
         * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
         * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occured, the callback may not be called depending on the value of errorMessage).
         * @param {Object} callback.arguments Other arguments specified in option.arguments                 
         * @param {Object} [options] Advanced options for the call.
         * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerComm#callMethod errorMessage.
         * @param {Boolean/String/Object} [options.waitMessage] Display a waiting message. See Ametys.data.ServerComm#callMethod waitMessage.
         * @param {Number} [options.scope] This parameter is the scope used to call the callback. Moreover is the given class is a mixin of Ametys.data.ServerCaller, its methods Ametys.data.ServerCaller#beforeServerCall and Ametys.data.ServerCaller#afterServerCall will be used so see their documentation to look for additional options (such a refreshing on Ametys.ribbon.element.ui.ButtonController#beforeServerCall).
         * @param {Number} [options.priority] The message priority. See Ametys.data.ServerComm#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
         * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerComm#callMethod cancelCode.
         * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
         * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerComm#callMethod ignoreOnError.
         */
        this.addCallables({
            role: "org.ametys.web.repository.page.ZoneItemManager",
            methodName:"getServiceParameterDefinitions",
            waitMessage: true,
            errorMessage: {
                msg: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_GET_SERVICE_PARAMETER_DEFINITIONS_ERROR}}",
                category: Ext.getClassName(this)
            }
        });
        
        /**
         * @callable
         * @param member Ametys.plugins.web.zone.ZoneItemManager
         * @method getServiceParameterValues
         * Get the service parameter values
         * This calls the method 'getServiceParameterValues' of the server DAO 'org.ametys.web.repository.page.ZoneItemManager'.
         * @param {Object[]} parameters The parameters to transmit to the server method
         * @param {String} parameters.zoneItemId The zone item id
         * @param {String} parameters.serviceId The service Id
         * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
         * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occured, the callback may not be called depending on the value of errorMessage).
         * @param {Object} callback.arguments Other arguments specified in option.arguments                 
         * @param {Object} [options] Advanced options for the call.
         * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerComm#callMethod errorMessage.
         * @param {Boolean/String/Object} [options.waitMessage] Display a waiting message. See Ametys.data.ServerComm#callMethod waitMessage.
         * @param {Number} [options.scope] This parameter is the scope used to call the callback. Moreover is the given class is a mixin of Ametys.data.ServerCaller, its methods Ametys.data.ServerCaller#beforeServerCall and Ametys.data.ServerCaller#afterServerCall will be used so see their documentation to look for additional options (such a refreshing on Ametys.ribbon.element.ui.ButtonController#beforeServerCall).
         * @param {Number} [options.priority] The message priority. See Ametys.data.ServerComm#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
         * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerComm#callMethod cancelCode.
         * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
         * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerComm#callMethod ignoreOnError.
         */
        this.addCallables({
            role: "org.ametys.web.repository.page.ZoneItemManager",
            methodName:"getServiceParameterValues",
            waitMessage: true,
            errorMessage: {
                msg: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_GET_SERVICE_PARAMETER_VALUES_ERROR}}",
                category: Ext.getClassName(this)
            }
        });
        
        /**
         * @callable
         * @param member Ametys.plugins.web.zone.ZoneItemManager
         * @method addService
         * Add the service to the given zone on given page
         * This calls the method 'addService' of the server DAO 'org.ametys.web.repository.page.ZoneItemManager'.
         * @param {Object[]} parameters The parameters to transmit to the server method
         * @param {String} parameters.pageId The page identifier
         * @param {String} parameters.zoneName The zone name
         * @param {String} parameters.serviceId The identifier of the service to add
         * @param {Object} parameters.parameterValues The service parameter values. Can be empty
         * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
         * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occured, the callback may not be called depending on the value of errorMessage).
         * @param {Object} callback.arguments Other arguments specified in option.arguments                 
         * @param {Object} [options] Advanced options for the call.
         * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerComm#callMethod errorMessage.
         * @param {Boolean/String/Object} [options.waitMessage] Display a waiting message. See Ametys.data.ServerComm#callMethod waitMessage.
         * @param {Number} [options.scope] This parameter is the scope used to call the callback. Moreover is the given class is a mixin of Ametys.data.ServerCaller, its methods Ametys.data.ServerCaller#beforeServerCall and Ametys.data.ServerCaller#afterServerCall will be used so see their documentation to look for additional options (such a refreshing on Ametys.ribbon.element.ui.ButtonController#beforeServerCall).
         * @param {Number} [options.priority] The message priority. See Ametys.data.ServerComm#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
         * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerComm#callMethod cancelCode.
         * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
         * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerComm#callMethod ignoreOnError.
         */
        this.addCallables({
            role: "org.ametys.web.repository.page.ZoneItemManager",
            methodName:"addService",
            callback: {
                handler: this._setServiceCb
            },
            waitMessage: true,
            errorMessage: {
                msg: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_ADD_SERVICE_ERROR}}",
                category: Ext.getClassName(this)
            }
        });
        
        /**
         * @callable
         * @param member Ametys.plugins.web.zone.ZoneItemManager
         * @method editServiceParameterValues
         * Edit the parameter values of the given service
         * This calls the method 'addService' of the server DAO 'org.ametys.web.repository.page.ZoneItemManager'.
         * @param {Object[]} parameters The parameters to transmit to the server method
         * @param {String} parameters.zoneItemId The identifier of the zone item holding the service
         * @param {String} parameters.serviceId The service identifier
         * @param {Object} parameters.parameterValues The service parameter values to update
         * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
         * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occured, the callback may not be called depending on the value of errorMessage).
         * @param {Object} callback.arguments Other arguments specified in option.arguments                 
         * @param {Object} [options] Advanced options for the call.
         * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerComm#callMethod errorMessage.
         * @param {Boolean/String/Object} [options.waitMessage] Display a waiting message. See Ametys.data.ServerComm#callMethod waitMessage.
         * @param {Number} [options.scope] This parameter is the scope used to call the callback. Moreover is the given class is a mixin of Ametys.data.ServerCaller, its methods Ametys.data.ServerCaller#beforeServerCall and Ametys.data.ServerCaller#afterServerCall will be used so see their documentation to look for additional options (such a refreshing on Ametys.ribbon.element.ui.ButtonController#beforeServerCall).
         * @param {Number} [options.priority] The message priority. See Ametys.data.ServerComm#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
         * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerComm#callMethod cancelCode.
         * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
         * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerComm#callMethod ignoreOnError.
         */
        this.addCallables({
            role: "org.ametys.web.repository.page.ZoneItemManager",
            methodName:"editServiceParameterValues",
            callback: {
                handler: this._setServiceCb
            },
            waitMessage: true,
            errorMessage: {
                msg: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_EDIT_SERVICE_ERROR}}",
                category: Ext.getClassName(this)
            }
        });
        
        /**
         * @callable
         * @param member Ametys.plugins.web.zone.ZoneItemManager
         * @method pasteService
         * Paste the service to the given zone on given page
         * This calls the method 'pasteService' of the server DAO 'org.ametys.web.repository.page.ZoneItemManager'.
         * @param {Object[]} parameters The parameters to transmit to the server method
         * @param {String} parameters.srcZoneItemId The service to copy identifier
         * @param {String} parameters.targetPageId The page identifier
         * @param {String} parameters.targetZoneName The zone name
         * @param {String} parameters.serviceId The identifier of the service to add
         * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
         * @param {Object} callback.returnedValue The value return from the server. Null on error (please note that when an error occured, the callback may not be called depending on the value of errorMessage).
         * @param {Object} callback.arguments Other arguments specified in option.arguments                 
         * @param {Object} [options] Advanced options for the call.
         * @param {Boolean/String/Object} [options.errorMessage] Display an error message. See Ametys.data.ServerComm#callMethod errorMessage.
         * @param {Boolean/String/Object} [options.waitMessage] Display a waiting message. See Ametys.data.ServerComm#callMethod waitMessage.
         * @param {Number} [options.scope] This parameter is the scope used to call the callback. Moreover is the given class is a mixin of Ametys.data.ServerCaller, its methods Ametys.data.ServerCaller#beforeServerCall and Ametys.data.ServerCaller#afterServerCall will be used so see their documentation to look for additional options (such a refreshing on Ametys.ribbon.element.ui.ButtonController#beforeServerCall).
         * @param {Number} [options.priority] The message priority. See Ametys.data.ServerComm#callMethod for more information on the priority. PRIORITY_SYNCHRONOUS cannot be used here.
         * @param {String} [options.cancelCode] Cancel similar unachieved read operations. See Ametys.data.ServerComm#callMethod cancelCode.
         * @param {Object} [options.arguments] Additional arguments set in the callback.arguments parameter.                  
         * @param {Boolean} [options.ignoreCallbackOnError] If the server throws an exception, should the callback beeing called with a null parameter. See Ametys.data.ServerComm#callMethod ignoreOnError.
         */
        this.addCallables({
            role: "org.ametys.web.repository.page.ZoneItemManager",
            methodName:"pasteService",
            callback: {
                handler: this._pasteServiceCb
            },
            waitMessage: true,
            errorMessage: {
                msg: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_PASTE_SERVICE_ERROR}}",
                category: Ext.getClassName(this)
            }
        });
    },
    
    /**
     * Callback function after updating pages
     * @param {Object} response The server response
     * @param {Object} args The callback arguments
     */
    _setServiceCb: function (response, args)
    {
        var errors = response.errors;
        if (!Ext.isEmpty(errors))
        {
            var details = "";
            for (var error in errors)
            {
                details += error + ": " + errors[error].join("; ") + "\n";
            }
            
            Ametys.log.ErrorDialog.display({
                title: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_CONFIGURESERVICE_FAILED_TITLE}}",
                text: "{{i18n PLUGINS_WEB_ZONE_ITEM_MANAGER_CONFIGURESERVICE_FAILED_DESC}}",
                details: details,
                category: this.self.getName() 
            });
        }
        else
        {
            Ext.create('Ametys.message.Message', {
                type: Ametys.message.Message.MODIFIED,
                parameters: {"creation": "service"},
                targets: [{
                    id: response.id.startsWith('sitemap://') ? Ametys.message.MessageTarget.SITEMAP : Ametys.message.MessageTarget.PAGE,
                    parameters: Ext.apply(response.id.startsWith('sitemap://') ? { id: response.id } : {ids: [response.id]}, { 
                        'zone-name': null,
                        'zoneitem-id': response['zoneitem-id']
                    })
                }]
            });
        }
    },
	
    /**
     * Callback function after pasting service
     * @param {Object} response The server response
     * @param {Object} args The callback arguments
     */
    _pasteServiceCb: function (response, args)
    {
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.MODIFIED,
            parameters: {"creation": "service"},
            targets: [{
                id: response.id.startsWith('sitemap://') ? Ametys.message.MessageTarget.SITEMAP : Ametys.message.MessageTarget.PAGE,
                parameters: Ext.apply(response.id.startsWith('sitemap://') ? { id: response.id } : {ids: [response.id]}, { 
                    'zone-name': null,
                    'zoneitem-id': response['zoneitem-id']
                })
            }]
        });
    }
});