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

/**
 * Singleton class defining actions of duplication :
 * - copy / paste a content.
 * - copy / paste a set of attributes.
 * @private
 */
Ext.define('Ametys.plugins.odf.content.actions.CopyODFContentActions', {
	singleton: true,
	
	/**
	 * This action pastes the copied content in a new content
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	pasteContent: function (controller)
	{
        var clipboardData = Ametys.clipboard.Clipboard.getData();
        if (clipboardData.length > 0 && Ametys.clipboard.Clipboard.getType() == Ametys.message.MessageTarget.CONTENT)
        {
            this._content = clipboardData[0];
            this._parentTarget = this._getParentTarget(this._content);
            
            if (this._parentTarget != null)
            {
                // Check the content is compatible with the selected parent
                controller.serverCall('canCopyTo', [this._content.getId(), this._parentTarget.getParameters().id, {}], Ext.bind(this._canCopyToCb, this),
                       {
                            arguments: {
                                controller: controller,
                                content: this._content,
                                parentTarget: this._parentTarget
                            },
                            waitMessage: false
                       });
            }
            else
            {
                // Get the structure of copied content
                Ametys.data.ServerComm.callMethod({
	                role: "org.ametys.odf.ODFHelper",
	                methodName: "getStructureInfo",
	                parameters: [this._content.getId()],
	                callback: {
	                    scope: this,
	                    handler: this._pasteContentCB,
	                    arguments: {
                            controller: controller,
                            content: this._content,
                            parentTarget: this._parentTarget
                        }
	                },
	                waitMessage: true
	            });
            }
        }
        else
        {
            Ametys.Msg.show({
                title: "{{i18n plugin.cms:CONTENT_COPY_PASTE_AS_NEW_LABEL}}",
                msg: "{{i18n plugin.cms:CONTENT_COPY_PASTE_AS_NEW_NO_COPIED_CONTENT_MSG}}",
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
        }
	},
    
    /**
     * Callback function called after checking copy is available
     * @param {Object} response The JSON result 
     * @param {Object} args The callback arguments
     * @private
     */
    _canCopyToCb: function(response, args)
    {
        if (response.success)
        {
            // Get the structure of copied content
            Ametys.data.ServerComm.callMethod({
                role: "org.ametys.odf.ODFHelper",
                methodName: "getStructureInfo",
                parameters: [args.content.getId()],
                callback: {
                    scope: this,
                    handler: this._pasteContentCB,
                    arguments: {
                        controller: args.controller,
                        content: args.content,
                        parentTarget: args.parentTarget
                    }
                },
                waitMessage: true
            });
        }
        else
        {
            // Invalid target
            var errors = response.errorMessages;
            if (errors && errors.length > 0)
            {
                var detailedMsg = '<ul>';
                for (var i=0; i < errors.length; i++)
                {
                    detailedMsg += '<li>' + errors[i] + '</li>';
                }
                detailedMsg += '</ul>';
                
                Ametys.form.SaveHelper.SaveErrorDialog.showErrorDialog ("{{i18n PLUGINS_ODF_COPY_TO_ERROR_TITLE}}", "{{i18n PLUGINS_ODF_COPY_TO_ERROR_TEXT}}", detailedMsg);
            }
        }
    },
	
	/**
	 * Callback function called retrieving the copied content's structure
	 * @param {Object} response The JSON result 
	 * @param {Object} args The callback arguments
	 * @private
	 */
	_pasteContentCB: function (response, args)
	{
        var controller = args.controller;
        
        Ametys.plugins.odf.content.helper.CopyODFContent.open ({
			content: args.content,
			workflowInitActionId: controller.getInitialConfig('creationActionId'),
			workflowEditActionId: controller.getInitialConfig('editionActionId'),
			viewName: controller.getInitialConfig('viewName'),
			viewMode: controller.getInitialConfig('viewMode'),
			parentContentTarget: args.parentTarget,
			hasChildren: response.hasChildren,
			callback: this._displayReport,
			scope: this});
	},
	
	/**
	 * @private
	 * Get the parent content target.
	 */
	_getParentTarget: function (content)
	{
		var message = Ametys.message.MessageBus.getCurrentSelectionMessage();
		var target = message.getTarget();
		if (target != null && target.getId() == Ametys.message.MessageTarget.CONTENT && content.getId() != target.getParameters().id)
		{
			return target;
		}
		
		return null;
	},
	
	/**
	 * @private
	 * Displays the copy report to the user in a simple message box.
	 * @param {Object} response The report object containing the list of successful copies and the list of contents or attributes that encountered an error.
	 * @param {Object[]} response.editedContents List of successfully modified contents. Each entry has the following keys : id, title.
	 * @param {Object[]} response.createdContents List of successfully created contents. Each entry has the following keys : id, title.
	 * @param {Object[]} response.failedContentCopies List of content copy errors.
	 * Each entry represents a base content for which the copy has failed and has the following keys : id, title (can be null if not retrieved).
	 * @param {Object[]} response.attributesErrors List of attributes errors.
	 * Each entry represents an attribute for which the copy has failed and has the following keys : label, contentId, contentTitle.
	 */
	_displayReport: function(response)
	{
		if (response["check-before-duplication-failed"])
		{
			// Prerequisites for duplication are not met, display an error message
            var lockedContents = response['locked-contents'];
            
            var message = "";
            if (this._parentTarget != null)
            {
            	message = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_ERROR_WITH_PARENT_MSG}}", this._content.getTitle(), this._parentTarget.getParameters().title)
            }
            else
            {
            	message = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_ERROR_MSG}}", this._content.getTitle())
            }
            
            message += "<ul>";
            message += "<li>" + Ametys.cms.content.ContentDAO._buildErrorMessage("", lockedContents, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LOCKED_CONTENTS}}") + "</li>";
            message += "</ul>";
            
            Ametys.Msg.show({
                   title: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
                   msg: message,
                   buttons: Ext.Msg.OK,
                   icon: Ext.MessageBox.ERROR
            });
		}
		else
		{
            var report = response.report;
            var mainContent = report.mainContent;
            var nbCreatedContents = report.createdContents.length;
            var nbEditedContents = report.editedContents.length;
            var nbFailedContentCopies = report.failedContentCopies.length;

            if (Ext.Object.isEmpty(report.mainContent) && nbFailedContentCopies > 0)
            {
                var errorMsg = [];
                Ext.Array.each(report.failedContentCopies, function(c) {
                    if (c.error)
                    {
                        errorMsg.push(c.error);
                    }
                })
                Ametys.notify({
                    type: 'error',
                    iconGlyph: 'ametysicon-text70',
                    title: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_ERROR_TITLE}}",
                    description: errorMsg.length == 0 ? "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_ERROR_DESC}}" : errorMsg.join('<br/>')
                });
                return;
            }
            
            var msg = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT}}", mainContent.title);
            if (nbCreatedContents > 0)
            {
                var key = nbCreatedContents > 2 ? "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_DETAILS}}" : "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_DETAILS_SINGLE}}";
                msg += Ext.String.format(key, nbCreatedContents);
            }
            if (nbFailedContentCopies > 0)
            {
                msg += Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_WARN}}", nbFailedContentCopies);
                
                var errorMsg = [];
                Ext.Array.each(report.failedContentCopies, function(c) {
                    if (c.error)
                    {
                        errorMsg.push(c.error);
                    }
                });
                
                if (errorMsg.length > 0)
                {
                    msg += errorMsg.join('<br/>');
                }
                
                Ametys.notify({
                    type: 'warn',
                    iconGlyph: 'ametysicon-text70',
                    title: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_TITLE}}",
                    action: Ext.bind(Ametys.tool.ToolsManager.openTool, Ametys.tool.ToolsManager, ['uitool-content', {id: mainContent.id}], false),
                    description: msg
                });
            }
            else
            {
                Ametys.notify({
                    type: 'info',
                    iconGlyph: 'ametysicon-text70',
                    title: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_REPORT_TITLE}}",
                    action: Ext.bind(Ametys.tool.ToolsManager.openTool, Ametys.tool.ToolsManager, ['uitool-content', {id: mainContent.id}], false),
                    description: msg
                });
            }
		}
	}
});