/*
 *  Copyright 2013 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 helper provides a dialog box to select the content attributes in a tree in order to copy then in the list of target contents
 * See #open method.
 * @private
 */
Ext.define('Ametys.plugins.cms.content.helper.CopyContentValues', {
	singleton: true,
	
	/**
	 * @property {Ametys.window.DialogBox} _box The dialog box
	 * @private
	 */
	/**
	 * @property {Ametys.plugins.cms.content.tree.ViewTree} _tree The tree that displays the current view and allow the user to select/deselect the desired attributes.
	 * @private
	 */
	
	/**
	 * @property {String} _content The copied content.
	 * @private
	 */
	/**
	 * @property {String} _targetContentIds The ids of targets content to copy values into.
	 * @private
	 */
	/**
	 * @property {Number} [_workflowInitActionId=111] The id of the workflow action to initialize a duplicated content. Can be null to use the default value.
	 * @private
	 */
	/**
	 * @property {Number} [_workflowEditActionId=222] The id of the workflow action to edit the target contents. Can be null to use the default value.
	 * @private
	 */
	/**
	 * @property {String} [_viewName="default-edition"] The name of the view to be displayed in attributes tree. Can be null to use the default value.
	 * @private
	 */
    /**
     * @property {String} [_fallbackViewName="main"] The fallback view be displayed in attributes tree. Used (for legacy purpose) when _viewName is not found.
     * @private
     */
	/**
	 * @property {String} [_viewMode="edition"] The mode of the view to be displayed in attributes tree Can be null to use the default value.
	 * @private
	 */
	/**
	 * @property {Function} _cbFn The callback function to be called after copy process
	 * @property {Object} _cbFn.report The copy report
	 * @private
	 */
	/**
	 * @property {Object} _scope The scope of the callback function. Can be null.
	 * @private
	 */

    /**
     * @property {Boolean} [_checkByDefault=true] Indicates if the checkboxes should be checked or not.
     * @private
     */
	_checkByDefault: true,
    
	/**
	 * Open a dialog box to select content attributes in a tree in order to copy content as a new content
	 * @param {Object} config The configuration options. Has the following parameters:
	 * @param {Ametys.cms.content.Content} config.sourceContent (required) The content to copied
	 * @param {String[]} config.targetContentIds (required) The ids of target contents
	 * @param {String} [config.icon] The full path to icon (16x16) for the dialog box
	 * @param {String} [config.title] The title of the dialog box.
	 * @param {String} [config.helpMessage] The message displayed at the top of the dialog box.
	 * @param {Number} [config.workflowInitActionId=111] The workflow action id for copy content as a new content
	 * @param {Number} [config.workflowEditActionId=222] The workflow action id to edit copy by copying attributes from a another content
	 * @param {String} [config.viewName="main"] The view name
	 * @param {String} [config.viewMode="edition"] The view mode ('view' or 'edition')
	 * @param {Function} config.callback Callback function called after the dialog box is closed and the copy is processed.
	 * @param {Object} config.callback.report The copy report
	 * @param {Object} [config.scope] The callback scope.
	 */
	open: function(config)
	{
		if (!config.sourceContent || !config.targetContentIds || config.targetContentIds.length == 0)
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_MISSING_PARAMETERS}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			return;
		}
		
		this._cbFn = config.callback || Ext.emptyFn;
		this._scope = config.scope;
		this._content = config.sourceContent;
		this._targetContentIds = config.targetContentIds;
		this._viewName = config.viewName || 'default-edition';
        this._fallbackViewName = config.fallbackViewName || 'main';
		this._viewMode = config.viewMode || 'edition';
		if (config.checkByDefault != null)
	    {
		    this._checkByDefault = config.checkByDefault != "false"
	    }
        
		this._workflowInitActionId = config.workflowInitActionId || 111;
		this._workflowEditActionId = config.workflowEditActionId || 222;
		
		this._delayedInitialize(config.icon || Ametys.getPluginResourcesPrefix('cms') + '/img/content/copy/paste-in-contents_16.png', 
				config.title || "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_DIALOG_TITLE}}",
				config.helpMessage || "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_DIALOG_HELPMESSAGE}}" + "<b>'" + Ext.String.escapeHtml(this._content.getTitle()) + "'</b>.");
		
		this._box.show();
		
		this._tree.initialize({
			contentId: this._content.getId(),
			checkMandatory: false,
			viewName: this._viewName,
            fallbackViewName: this._fallbackViewName,
			viewMode: this._viewMode,
            checkByDefault: this._checkByDefault
		});
	},
	
	/**
	 * Creates the dialog box if it is not already created
	 * @param {String} icon The full path to icon (16x16 pixels) for the dialog box
	 * @param {String} title The title of the dialog box.
	 * @param {String} helpMessage The message displayed at the top of the dialog box.
	 * @private
	 */
	_delayedInitialize: function(icon, title, helpMessage)
	{
		if (!this._initialized)
		{
			this._tree = Ext.create('Ametys.plugins.cms.content.tree.ViewTree', {
				height: 400,
				scrollable: true
			});
			
			this._box = Ext.create('Ametys.window.DialogBox', {
				title: title,
				icon: icon,
				
				width: 400,
				scrollable: false,
				layout: {
					type: 'vbox',
					align: 'stretch'
				},
				
				items: [{
						xtype: 'component',
						cls: 'a-text',
						html: helpMessage
					},
					this._tree
				],
				
				closeAction: 'hide',
				
				referenceHolder: true,
				defaultButton: 'validate',
				defaultButtonTarget: 'el',
				
				buttons : [{
					reference: 'validate',
					text: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_BTN_OK}}",
					handler: Ext.bind(this._ok, this),
					itemId: 'btn-ok'
				}, {
					text: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_BTN_CANCEL}}",
					handler: Ext.bind(function() {this._box.close();}, this) 
				}],
				
				listeners: {
					resize: {fn: this._onBoxResize, scope: this}
				}
			});
			
			this._initialized = true;
		}
		else
		{
			this._box.setIcon(icon);
			this._box.setTitle(title);
			this._box.items.getAt(0).update(helpMessage);
		}
	},
	
	/**
	 * This function is called when validating the dialog box.
	 * Aggregate the parameters to make the server request.
	 * Run the duplication action on the server.
	 * @private
	 */
	_ok: function()
	{
		if (this._tree.isInErrorState())
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENTVALUES_TREE_ERROR_MSG}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			return;
		}
		
		var baseContentId = this._content.getId();
		var targetContentIds = this._targetContentIds;
		var viewName = this._viewName;
        var fallbackViewName = this._fallbackViewName;
		var viewMode = this.viewMode;
		
		// Add tree values if the tree is displayed.
		var values = this._tree.getValues();
		var valuesToCopy = values ? Ext.JSON.encode(values) : null;
		
		Ametys.data.ServerComm.callMethod({
			role: "org.ametys.cms.workflow.copy.CopyContentClientInteraction",
			methodName: "editContentByCopy",
			parameters: [baseContentId, targetContentIds, valuesToCopy, viewName, fallbackViewName, viewMode],
			callback: {
				scope: this,
				handler: this._okCb,
                ignoreOnError: false
			},
			waitMessage: {
				msg: "{{i18n PLUGINS_CMS_HELPER_COPYCONTENT_WAIT_MSG}}", 
				target: this._box
			},
			errorMessage: {
				category: Ext.getClassName(this) + '._ok'
			}
		});
	},
	
	/**
	 * Callback function called after copy is processed.
	 * Fires Ametys.message.Message.CREATED message for new created content and Ametys.message.Message.MODIFIED message for modified content
	 * @param {Object} response The JSON result from server :
	 * @param {String[]} response.createdContentIds The id of created contents
	 * @param {String[]} response.editedContentIds The id of modified contents
	 * @param {Object} response.report The copy report
	 * @param {Object[]} args The callback parameters passed to the {@link Ametys.data.ServerComm#callMethod} method
	 * @private
	 */
	_okCb: function(response, args)
	{
		if (response != null)
		{
			var editedContentIds = response.editedContentIds || [];
			var createdContentIds = response.createdContentIds || [];
			
			// FIXME does MODIFIED message should set its major parameter to true is this case?
			if (editedContentIds.length > 0 && editedContentIds[0] != '')
			{
				Ext.create("Ametys.message.Message", {
					type: Ametys.message.Message.MODIFIED,
					targets: {
						id: Ametys.message.MessageTarget.CONTENT,
						parameters: { ids: editedContentIds }
					}
				});
			}
			
			if (createdContentIds.length > 0 && createdContentIds[0] != '')
			{
				Ext.create("Ametys.message.Message", {
					type: Ametys.message.Message.CREATED,
					targets: {
						id: Ametys.message.MessageTarget.CONTENT,
						parameters: { ids: createdContentIds }
					}
				});
			}
			
			var report = response.report;
			this._cbFn.call(this._scope, report);
			
			this._box.close();
		}
		else
		{
			// In case of bad response, an error message is displayed thanks to the serverComm API
			// but we still want to close the dialog box.
			this._box.close();
		}
	}
	
});