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

/**
 * This helper provides a dialog box to copy an odf content as a new content. 
 * The dialog box brings the duplication mode for the odf content.
 * See #open method.
 * @private
 */
Ext.define('Ametys.plugins.odf.content.helper.CopyODFContent', {
	singleton: true,
	
	/**
	 * @readonly
     * @property {String} SINGLE_MODE Constant for single duplication mode
     */
    SINGLE_MODE : 'single',
    /**
     * @readonly
     * @property {String} STRUCTURE_ONLY_MODE Constant for "structure only" duplication mode
     */
    STRUCTURE_ONLY_MODE: 'structure_only',
    /**
     * @readonly
     * @property {String} FULL_MODE Constant for full duplication mode
     */
    FULL_MODE: 'full',
	
	/**
	 * @property {Ametys.window.DialogBox} _box The dialog box
	 * @private
	 */
	
	/**
	 * @property {String} _content The copied content.
	 * @private
	 */
	/**
	 * @property {Number} [_workflowInitActionId=111] The id of the workflow action to initialize the duplicated content. Can be null to use the default value.
	 * @private
	 */
	/**
	 * @property {Number} [_workflowEditActionId=2] The id of the workflow action to edit the target content. 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 to 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 {Object} _parentContentTarget The parent content of the copied content. Can be null
	 * @private
	 */
	/**
	 * @property {Boolean} _hasChildren True if the content to be copied has children
	 * @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
	 */
	
	
	/**
	 * Open a dialog box to select duplication mode to copy content as a new content
	 * @param {Object} config The configuration options. Has the following parameters:
	 * @param {Ametys.cms.content.Content} config.content (required) The content to copied
	 * @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.helpMsg] 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=2] The workflow action id for editing the target content
	 * @param {String} [config.viewName="default-edition"] The view name
     * @param {String} [config.fallbackViewName="main"] The fallback view name
	 * @param {String} [config.viewMode="edition"] The view mode ('view' or 'edition')
	 * @param {Object} config.parentContentTarget The parent content of the copied content.
	 * @param {Boolean} config.hasChildren True if the content to be copied has children
	 * @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.content)
		{
			Ametys.Msg.show({
				title: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENTVALUES_ERROR_TITLE}}",
				msg: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_NO_COPIED_CONTENT}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
			return;
		}
		
		this._cbFn = config.callback || Ext.emptyFn;
		this._scope = config.scope;
		
		this._content = config.content;
		this._viewName = config.viewName || 'default-edition';
        this._fallbackViewName = config.fallbackViewName || 'main';
		this._viewMode = config.viewMode || 'edition';
		this._workflowInitActionId = config.workflowInitActionId || 111;
		this._workflowEditActionId = config.workflowEditActionId || 2;
		this._parentContentTarget = config.parentContentTarget || null;
		this._hasChildren = config.hasChildren || false;
		
		// Check the user rights by retrieve the content type
		var me = this;
        var contentTypes = Ametys.cms.content.ContentTypeDAO.getContentTypes().createFiltered(function(contentType) {
            return me._content.getTypes().indexOf(contentType.getId()) != -1
                && contentType.hasRight()
                && !contentType.isMixin()
                && !contentType.isAbstract();
        });
        
        if (contentTypes.count() != this._content.getTypes().length)
        {
            Ametys.Msg.show({
                title: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENTVALUES_ERROR_TITLE}}",
                msg: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_NO_RIGHT_MSG}}",
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.WARNING
            });
            return;
        }

		var types = this._content.getTypes();
		if (!this._hasChildren)
		{
			this._drawDuplicateDefaultBox('ametysicon-clipboard99', 
					"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}", 
					"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
		}
		else if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.course"))
		{
			this._drawDuplicateCourseBox('ametysicon-clipboard99', 
					"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}", 
					"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
		}
		else if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.courseList"))
		{
			this._drawDuplicateCourseListBox('ametysicon-clipboard99', 
					"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}", 
					"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
		}
		else
		{
			this._drawDuplicateProgramPartBox('ametysicon-clipboard99', 
					"{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}", 
					"{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_DIALOG_HELPMESSAGE1}}" + "<b>'" + this._content.getTitle() + "'</b>.");
		}
		
	},
	
	/**
	 * Creates the duplicate dialog box if it is not already created. Only for odf content with no children, we don't ask for duplication mode.
	 * @param {String} iconCls The css classname to display an icon (with a glyph for example)
	 * @param {String} title The title of the dialog box.
	 * @param {String} helpMsg The message displayed at the top of the dialog box.
	 * @private
	 */
	_drawDuplicateDefaultBox: function(iconCls, title, helpMsg)
	{
		if (this._duplicateDefaultBox == null)
		{
			this._duplicateDefaultBox = Ext.create('Ametys.window.DialogBox', {
				title: title,
				iconCls: iconCls,
				width: 600,
				scrollable: false,
				items: this._getDefaultItems(helpMsg),
				closeAction: 'hide',
				defaultFocus: 'content-title',
				selectDefaultFocus: true,
				referenceHolder: true,
				defaultButton: 'validate',
				buttons : [{
					reference: 'validate',
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
					handler: function() {this._ok(this._duplicateDefaultBox)},
					scope: this,
					itemId: 'btn-ok'
				}, {
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
					handler: Ext.bind(function() {this._duplicateDefaultBox.close();}, this) 
				}]
			});
		}
		else
		{
			this._duplicateDefaultBox.setIconCls(iconCls);
			this._duplicateDefaultBox.setTitle(title);
			this._duplicateDefaultBox.items.getAt(0).update(helpMsg);
		}
		
		this._duplicateDefaultBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
		this._duplicateDefaultBox.show();
	},
	
	/**
	 * Creates the duplicate dialog box for course if it is not already created.
	 * @param {String} iconCls The css classname to display an icon (with a glyph for example)
	 * @param {String} title The title of the dialog box.
	 * @param {String} helpMsg The message displayed at the top of the dialog box.
	 * @private
	 */
	_drawDuplicateCourseBox: function(iconCls, title, helpMsg)
	{
		if (this._duplicateCourseBox == null)
		{
			var items = this._getDefaultItems(helpMsg);
			items.push({
				xtype: 'form',
				items: [
					this._createRadioField(this.STRUCTURE_ONLY_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_RADIO_FIELD_SINGLE_LABEL}}", false),
					this._createRadioField(this.FULL_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_RADIO_FIELD_FULL_LABEL}}", true)
				]
			});
			
			this._duplicateCourseBox = Ext.create('Ametys.window.DialogBox', {
				title: title,
				iconCls: iconCls,
				width: 600,
				scrollable: false,
				items: items,
				closeAction: 'hide',
				defaultFocus: 'content-title',
				selectDefaultFocus: true,
				referenceHolder: true,
				defaultButton: 'validate',
				buttons : [{
					reference: 'validate',
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
					handler: function() {this._ok(this._duplicateCourseBox)},
					scope: this,
					itemId: 'btn-ok'
				}, {
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
					handler: Ext.bind(function() {this._duplicateCourseBox.close();}, this) 
				}]
			});
		}
		else
		{
			this._duplicateCourseBox.setIconCls(iconCls);
			this._duplicateCourseBox.setTitle(title);
			this._duplicateCourseBox.items.getAt(0).update(helpMsg);
		}
		
		this._duplicateCourseBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
		this._duplicateCourseBox.show();
	},
	
	/**
	 * Creates the duplicate dialog box for course list if it is not already created
	 * @param {String} iconCls The css classname to display an icon (with a glyph for example)
	 * @param {String} title The title of the dialog box.
	 * @param {String} helpMsg The message displayed at the top of the dialog box.
	 * @private
	 */
	_drawDuplicateCourseListBox: function(iconCls, title, helpMsg)
	{
		if (this._duplicateCourseListBox == null)
		{
			var items = this._getDefaultItems(helpMsg);
			items.push({
				xtype: 'form',
				items: [
					this._createRadioField(this.SINGLE_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_LIST_RADIO_FIELD_SINGLE_LABEL}}", false),
					this._createRadioField(this.FULL_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_COURSE_LIST_RADIO_FIELD_FULL_LABEL}}", true)
				]
			});
			
			this._duplicateCourseListBox = Ext.create('Ametys.window.DialogBox', {
				title: title,
				iconCls: iconCls,
				width: 600,
				scrollable: false,
				items: items,
				closeAction: 'hide',
				defaultFocus: 'content-title',
				selectDefaultFocus: true,
				referenceHolder: true,
				defaultButton: 'validate',
				buttons : [{
					reference: 'validate',
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
					handler: function() {this._ok(this._duplicateCourseListBox)},
					scope: this,
					itemId: 'btn-ok'
				}, {
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
					handler: Ext.bind(function() {this._duplicateCourseListBox.close();}, this) 
				}]
			});
		}
		else
		{
			this._duplicateCourseListBox.setIconCls(iconCls);
			this._duplicateCourseListBox.setTitle(title);
			this._duplicateCourseListBox.items.getAt(0).update(helpMsg);
		}
		
		this._duplicateCourseListBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
		this._duplicateCourseListBox.show();
	},
	
	/**
	 * Creates the duplicate dialog box for program part if it is not already created
	 * @param {String} iconCls The css classname to display an icon (with a glyph for example)
	 * @param {String} title The title of the dialog box.
	 * @param {String} helpMsg The message displayed at the top of the dialog box.
	 * @private
	 */
	_drawDuplicateProgramPartBox: function(iconCls, title, helpMsg)
	{
		if (this._duplicateProgramPartBox == null)
		{
			var items = this._getDefaultItems(helpMsg);
			items.push({
				xtype: 'form',
				items: [
					this._createRadioField(this.SINGLE_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_PROGRAM_PART_RADIO_FIELD_SINGLE_LABEL}}", false),
					this._createRadioField(this.STRUCTURE_ONLY_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_PROGRAM_PART_RADIO_FIELD_STRUCTURE_LABEL}}", true),
					this._createRadioField(this.FULL_MODE, "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_PROGRAM_PART_RADIO_FIELD_FULL_LABEL}}", false)
				]
			});
			
			this._duplicateProgramPartBox = Ext.create('Ametys.window.DialogBox', {
				title: title,
				iconCls: iconCls,
				width: 600,
				scrollable: false,
				items: items,
				closeAction: 'hide',
				defaultFocus: 'content-title',
				selectDefaultFocus: true,
				referenceHolder: true,
				defaultButton: 'validate',
				buttons : [{
					reference: 'validate',
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_OK}}",
					handler: function() {this._ok(this._duplicateProgramPartBox)},
					scope: this,
					itemId: 'btn-ok'
				}, {
					text: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_BTN_CANCEL}}",
					handler: Ext.bind(function() {this._duplicateProgramPartBox.close();}, this) 
				}]
			});
		}
		else
		{
			this._duplicateProgramPartBox.setIconCls(iconCls);
			this._duplicateProgramPartBox.setTitle(title);
			this._duplicateProgramPartBox.items.getAt(0).update(helpMsg);
		}
		
		this._duplicateProgramPartBox.down('#content-title').setValue(this._content.getTitle() + "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_SUFFIX}}");
		this._duplicateProgramPartBox.show();
	},
	
	/**
	 * Creates one radio field item
	 * @param {String} inputValue the input value
	 * @param {String} label The label of the radio field
	 * @param {Boolean} checked True if the radio field is checked
	 * @private
	 */
	_createRadioField: function(inputValue, label, checked)
	{
		return {
			xtype: 'radiofield',
			hideLabel: true,
			checked: checked,
			boxLabel: label,
			name: 'mode',
			inputValue: inputValue,
			style: {
				marginLeft: '15px'
			}
		};
	},
	
	/**
	 * Get the default item of duplicate dialog box : the help message with the new title field
	 * @param {String} helpMsg The message displayed at the top of the dialog box.
	 * @private
	 */
	_getDefaultItems: function(helpMsg)
	{
		return [{
					xtype: 'component',
					cls: 'a-text',
					html: helpMsg
				},
				{
					xtype: 'container',
					style: {
						marginTop: '5px',
			            marginBottom: '5px'
			        },
					items: {
						xtype: 'textfield',
						width: 340,
						labelAlign: 'right',
						labelWidth: 70,
						cls: 'ametys',
						name: 'contentTitle',
						fieldLabel: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_LABEL}}",
						ametysDescription: "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_DESC}}",
						itemId: 'content-title',
						allowBlank: false,
						msgTarget: 'side',
						validator: function (value) {
							var s = Ext.String.deemphasize(value);
							if (/^([0-9\-]*|[0-9\-]+.*)[a-z].*$/i.test(s))
							{
								return true;
							}
							else
							{
								return "{{i18n plugin.cms:PLUGINS_CMS_HELPER_COPYCONTENT_TITLE_INVALID}}";
							}
						}
					},
				}];
	},
	
	/**
	 * This function is called when validating the dialog box.
	 * Aggregate the parameters to make the server request.
	 * Run the duplication action on the server.
	 * @param {Ametys.window.DialogBox} box The dialog box
	 * @private
	 */
	_ok: function(box)
	{
		// Title
		var titleField = box.down('#content-title');
		if (!titleField.isValid())
		{
			return null;
		}
		
		var baseContentId = this._content.getId();
		var newContentTitle = titleField.getValue();
		var viewName = this._viewName;
        var fallbackViewName = this._fallbackViewName;
		var viewMode = this._viewMode;
		var duplicationMode = box.down('form') != null ? box.down('form').getForm().findField("mode").getGroupValue() : null;
		var parentContentId = this._parentContentTarget != null ? this._parentContentTarget.getParameters().id : null;

		Ametys.data.ServerComm.callMethod({
			role: "org.ametys.core.ui.RibbonControlsManager",
            id: "org.ametys.odf.content.PasteContent",
			methodName: "createContentByCopy",
			priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
			parameters: [baseContentId, newContentTitle, viewName, fallbackViewName, viewMode, this._workflowInitActionId, this._workflowEditActionId, duplicationMode, parentContentId],
			callback: {
				scope: this,
				handler: this._okCb,
                ignoreOnError: false
			},
			errorMessage: {
				category: Ext.getClassName(this) + '._ok'
			}
		});
        
        Ametys.Msg.show({
               title: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_LABEL}}",
               msg: "{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_WAIT_INFO}}",
               buttons: Ext.Msg.OK,
               icon: Ext.MessageBox.INFO
        });
        
        box.close();
	},
	
	/**
	 * Callback function called after copy is processed.
	 * Fires Ametys.message.Message.CREATED message for new created content
	 * @param {Object} response The JSON result from server :
	 * @param {String} response.mainContentId The id of main created content
	 * @param {String[]} response.contentIds The id of created 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 contentIds = response.contentIds ? Object.values(response.contentIds) : [];

			if (contentIds.length > 0 && contentIds[0] != '')
			{
				Ext.create("Ametys.message.Message", {
					type: Ametys.message.Message.CREATED,
					targets: {
						id: Ametys.message.MessageTarget.CONTENT,
						parameters: { ids: contentIds }
					}
				});
				
				if (this._parentContentTarget != null)
				{
					Ext.create("Ametys.message.Message", {
						type: Ametys.message.Message.MODIFIED,
						targets: {
							id: Ametys.message.MessageTarget.CONTENT,
							parameters: { ids: [this._parentContentTarget.getParameters().id] }
						}
					});
				}
			}
			
			this._cbFn.call(this._scope, response);
			
			// CMS-5137 Open directly the main created content after copied
			var mainContentId = response.mainContentId;
			if (mainContentId)
			{
				Ametys.tool.ToolsManager.openTool('uitool-content', {id: mainContentId});
			}
		}
	}
});