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

/**
 * The newsletter category DAO.
 */
 Ext.define('Ametys.cms.newsletter.CategoryDAO', {
 	singleton: true,
 	
 	constructor: function(config)
 	{
 		/**
		 * @callable
		 * @member Ametys.cms.newsletter.CategoryDAO
		 * @method createCategory 
		 * Creates a newsletter category.
		 * This calls the method 'createCategory' of the server DAO 'CategoryDAO'.
		 * @param {Object[]} parameters The parameters to transmit to the server method
		 * @param {String} parameters.parentId The id of the parent
 		 * @param {String} parameters.title The title
 		 * @param {String} parameters.description The description
 		 * @param {String} parameters.siteName The site name
 		 * @param {String} parameters.language The language
		 * @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.plugins.newsletter.category.CategoryDAO",
				methodName: "createCategory",
				callback: {
					handler: this._createCategoryCb,
					scope: this
				},
				errorMessage: {
				    msg: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_CREATE_ERROR}}",
				    category: Ext.getClassName(this)
				}
			}
		);
		
		/**
		 * @callable
		 * @member Ametys.cms.newsletter.CategoryDAO
		 * @method editCategory 
		 * Edits a newsletter category.
		 * This calls the method 'editCategory' of the server DAO 'CategoryDAO'.
		 * @param {Object[]} parameters The parameters to transmit to the server method
		 * @param {String} parameters.id The id of the category to edit
 		 * @param {String} parameters.title The title
 		 * @param {String} parameters.description The description
		 * @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.plugins.newsletter.category.CategoryDAO",
	     		methodName: "editCategory",
	     		callback: {
					handler: this._editCategoryCb,
					scope: this
				},
	     		errorMessage: {
	     			category: Ext.getClassName(this)
	     		}
			}
		);
		
		/**
		 * @callable
		 * @member Ametys.cms.newsletter.CategoryDAO
		 * @method deleteCategory 
		 * Deletes a newsletter category.
		 * This calls the method 'deleteCategory' of the server DAO 'CategoryDAO'.
		 * @param {Object[]} parameters The parameters to transmit to the server method
		 * @param {String} parameters.id The id of the category to delete
		 * @param {Ametys.message.MessageTarget} parameters.target The message target corresponding to the id. It is not transmitted to the server, but is needed for sending a deletion message on the bus.
		 * @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.plugins.newsletter.category.CategoryDAO",
	     		methodName: "deleteCategory",
	     		localParamsIndex: 1,
	     		callback: {
					handler: this._deleteCategoryCb,
					scope: this
				},
	     		errorMessage: {
	     			category: Ext.getClassName(this)
	     		}
			}
		);
		
		/**
		 * @callable
		 * @member Ametys.cms.newsletter.CategoryDAO
		 * @method getCategories 
		 * This calls the method 'getCategories' of the server DAO 'Ametys.cms.newsletter.CategoryDAO'.
		 * @param {Object[]} parameters The parameters to transmit to the server method are:
		 * @param {String} parameters.ids The id of categories to retrieve
		 * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
		 * @param {Ametys.cms.newsletter.NewsletterCategory[]} callback.categories The retrieved categories. Null on error (please note that when an error occurred, the callback may not be called depending on the value of errorMessage).
		 * @param {Object} callback.args 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.plugins.newsletter.category.CategoryDAO",
				methodName: "getCategories",
				convertor: this._convertCategories,
	     		waitMessage: true,
				errorMessage: {
				    msg: "{{i18n PLUGINS_NEWSLETTER_GET_CATEGORIES_ERROR}}",
				    category: Ext.getClassName(this)
				}
			}
		);
		
		/**
		 * @callable
		 * @member Ametys.cms.newsletter.CategoryDAO
		 * @method getCategory
		 * This calls the method 'getCategory' of the server DAO 'Ametys.cms.newsletter.CategoryDAO'.
		 * @param {Object[]} parameters The parameters to transmit to the server method are:
		 * @param {String} parameters.id The id of category to retrieve
		 * @param {Function} callback The function to call when the java process is over. Use options.scope for the scope. 
		 * @param {Ametys.cms.newsletter.NewsletterCategory} callback.category The retrieved category. Null on error (please note that when an error occurred, the callback may not be called depending on the value of errorMessage).
		 * @param {Object} callback.args 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.plugins.newsletter.category.CategoryDAO",
				methodName: "getCategory",
				convertor: this._convertCategory,
	     		waitMessage: true,
				errorMessage: {
				    msg: "{{i18n PLUGINS_NEWSLETTER_GET_CATEGORY_ERROR}}",
				    category: Ext.getClassName(this)
				}
			}
		);
		
		/**
		 * @callable
		 * @member Ametys.cms.newsletter.CategoryDAO
		 * @method applyTemplates 
		 * Applies a template to a given newsletter category.
		 * This calls the method 'applyTemplates' of the server DAO 'CategoryDAO'.
		 * @param {Object[]} parameters The parameters to transmit to the server method
		 * @param {String[]} parameters.categoryIds The ids of the categories to edit.
		 * @param {String} parameters.template The template to set.
		 * @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.plugins.newsletter.category.CategoryDAO",
	     		methodName: "applyTemplates",
	     		callback: {
					handler: this._applyTemplatesCb,
					scope: this
				}
			}
		);
 	},
 	
 	/**
     * @private
     * Extract and convert categories' configuration received from server.
     * @param {Object} categoryConfigs The configuration objects. Null on error (please note that when an error occurred, the callback may not be called depending on the value of errorMessage).
     * @param {Object} args Other arguments specified in option.arguments            
     * @param {Object} parameters Parameters of the initial call transmited in parameters argument.
     * @return {Ametys.cms.newsletter.NewsletterCategory[]} the categories
     */
    _convertCategories: function (categoryConfigs, args, parameters)
    {
    	var categories = [];
    	
    	if (categoryConfigs)
    	{
    		for (var i=0; i < categoryConfigs.length; i++)
    		{
    			categories.push(Ext.create ('Ametys.cms.newsletter.NewsletterCategory', categoryConfigs[i]));
    		}
    	}
    	
    	return categories;
    },
    
    /**
     * @private
     * Extract and convert category's configuration received from server.
     * @param {Object} categoryConfig The configuration object. Null on error (please note that when an error occurred, the callback may not be called depending on the value of errorMessage).
     * @param {Object} args Other arguments specified in option.arguments            
     * @param {Object} parameters Parameters of the initial call transmited in parameters argument.
     * @return {Ametys.cms.newsletter.NewsletterCategory} the newsletter category
     */
    _convertCategory: function (categoryConfig, args, parameters)
    {
    	if (categoryConfig && categoryConfig.id)
    	{
    		return Ext.create ('Ametys.cms.newsletter.NewsletterCategory', categoryConfig);
    	}
    	else
    	{
    		return null;
    	}
    },
 	
 	/**
 	 * Callback function called after {@link #createCategory} has been processed.
 	 * @param {Object} response The response provided by the {@link Ametys.data.ServerComm}
 	 * @private
 	 */
 	_createCategoryCb: function(response)
 	{
		var msg = response['message'];
		if (msg == 'unknown-category')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_CREATE}}",
				msg: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_CREATE_UNKNOWN_CATEGORY}}",
				buttons: Ext.Msg.OK,
				icon: Ext.MessageBox.ERROR
			});
		}
		else if (msg == 'already-exist')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_CREATE}}",
				msg: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_CREATE_ALREADY_EXIST}}",
				buttons: Ext.Msg.OK,
				icon: Ext.MessageBox.ERROR
			});
		}
		else
		{
			// Success
			var categoryId = response['id'];
			var parentId = response['parentId'];
	    	Ext.create("Ametys.message.Message", {
	    		type: Ametys.message.Message.CREATED,
	    		targets: {
	    		    id: Ametys.message.MessageTarget.NEWSLETTER_CATEGORY,
	    			parameters: {
	    				ids: [categoryId]
	    			}
	    		}
	    	});
		}
		
 	},
 	
 	/**
 	 * Callback function called after {@link #editCategory} has been processed.
 	 * @param {Object} response The response provided by the {@link Ametys.data.ServerComm}
 	 * @private
 	 */
 	_editCategoryCb: function(response)
 	{
		var msg = response['message'];
        if (msg == 'unknown-category')
        {
        	Ametys.Msg.show({
                title: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_EDIT}}",
                msg: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_CREATE_UNKNOWN_CATEGORY}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
        else
        {
        	// Success
	        var categoryId = response['id'];
	        var title = response['title'];
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.MODIFIED,
				targets: {
				    id: Ametys.message.MessageTarget.NEWSLETTER_CATEGORY,
					parameters: {
						ids: [categoryId]
					}
				}
			});
        }
 	},
 	
 	/**
 	 * Callback function called after {@link #deleteCategory} has been processed.
 	 * @param {Object} response The response provided by the {@link Ametys.data.ServerComm}
 	 * @param {Array} args The callback arguments
 	 * @param {Array} params The parameters
 	 * @private
 	 */
 	_deleteCategoryCb: function(response, args, params)
 	{
 		var target = params[1];
 		
		var msg = response['message'];
		if (msg == 'unknown-category')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_DELETE_ERROR}}",
				msg: "{{i18n PLUGINS_NEWSLETTER_HANDLE_CATEGORY_DELETE_UNKNOWN_CATEGORY}}",
				buttons: Ext.Msg.OK,
				icon: Ext.MessageBox.ERROR
			});
		}
		else
		{
			// Success
			Ext.create("Ametys.message.Message", {
	    		type: Ametys.message.Message.DELETED,
	    		targets: target
	    	});
		}
		
 	},
 	
 	/**
 	 * Callback function called after {@link #applyTemplates} has been processed.
 	 * @param {Object} response The response provided by the {@link Ametys.data.ServerComm}
 	 * @param {Array} args The callback arguments
 	 * @param {Array} params The parameters
 	 * @private
 	 */
 	_applyTemplatesCb: function(response, args, params)
 	{
 		var categoryIds = params[0];
 		Ext.create("Ametys.message.Message", {
			type: Ametys.message.Message.MODIFIED,
			targets: {
			    id: Ametys.message.MessageTarget.NEWSLETTER_CATEGORY,
				parameters: {
					ids: categoryIds
				}
			}
		});
		
 	}
 	
 });