/*
 *  Copyright 2014 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 to delete ODF contents
 * @private
 */
Ext.define('Ametys.plugins.odf.content.DeleteContentAction', {
    singleton: true,
    
    /**
     * @readonly
     * @property {String} SINGLE_MODE Constant for single deletion mode
     */
    SINGLE_MODE : 'single',
    /**
     * @readonly
     * @property {String} STRUCTURE_ONLY_MODE Constant for "structure only" deletion mode
     */
    STRUCTURE_ONLY_MODE: 'structure_only',
    /**
     * @readonly
     * @property {String} FULL_MODE Constant for full deletion mode
     */
    FULL_MODE: 'full',
    
    /**
	 * Action function to be called by the controller.
	 * Will delete the contents registered by the controller.
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	act: function (controller)
	{
        var contentIdsToDelete = controller.getContentIds();
        
        if (contentIdsToDelete.length > 0)
        {
            var contentTargets = controller.getMatchingTargets();
            
            controller.serverCall('getStructureInfo', [contentIdsToDelete], Ext.bind(this._getStructureInfoCB, this),
                {
                    arguments: {
                        controller: controller,
                        contentIdsToDelete: contentIdsToDelete,
                        contentTargets: contentTargets
                    },
                    waitMessage: true
                }
            );
        }
	},
    
    actWithoutStructureCheck: function (controller)
    {
        var contentIdsToDelete = controller.getContentIds();
        var contentTargets = controller.getMatchingTargets();
        
        if (contentIdsToDelete.length > 0)
        {
            this._showConfirmMsg(controller, contentTargets, this.SINGLE_MODE, contentIdsToDelete, {}, []);
        }
    },
	
	/**
	 * Callback function called after #_getContentInfo is processed.
	 * @param {Object} response The JSON result 
	 * @param {Object} args The callback arguments
     * @param {Ametys.ribbon.element.ui.ButtonController} args.controller The controller
     * @param {Ametys.message.MessageTarget[]} args.contentTargets The content targets
     * @param {String[]} args.contentIdsToDelete The content IDs to delete
	 * @private
	 */
	_getStructureInfoCB: function(response, args)
	{
        var contentTargets = args.contentTargets;
        var types = contentTargets[0].getParameters().types;
        var chooseOptsFn = this._getChooseOptionsFnByTypes(types);
        
        var contentIdsToDelete = args.contentIdsToDelete;
        
        var atLeastOneContentChildren = false;
        
        var contentsInfo = {};
        var pathsToReferencedContents = [];
        Ext.Array.each(contentIdsToDelete, function(id) {
            var structureInfo = response[id];
            contentsInfo[id] = { 'code': structureInfo.code };

            if (structureInfo.hasParent)
            {
                var paths = structureInfo["paths"];
                
                Ext.Array.forEach (paths, function (path) {
                    pathsToReferencedContents.push({
                        title: structureInfo.title,
                        code: structureInfo.code,
                        path: path.substring(0, path.lastIndexOf('>') + 2)
                    });
                });
            }
            
            if (structureInfo.hasChildren)
            {
                atLeastOneContentChildren = true;
            }
        });
        
        // If we have at least one content with a children, we display a box to select how to handle it.
        if (atLeastOneContentChildren)
        {
            chooseOptsFn.call(this, args.controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, response.nbOnlyStructureContents, response.nbCourses);
        }
        else
        {
            // prepare deletion
            this._showConfirmMsg(args.controller, contentTargets, this.SINGLE_MODE, contentIdsToDelete, contentsInfo, pathsToReferencedContents);
        }
    },
    
    /**
     * @private
     * Get the function to display options to user
     * @param {String[]} types The content's types
     * @return {Function} The function
     */
    _getChooseOptionsFnByTypes: function (types)
    {
        if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.course"))
        {
            return this._showCourseDialog;
        }
        else if (Ext.Array.contains(types, "org.ametys.plugins.odf.Content.courseList"))
        {
            return this._showCourseListDialog;
        }
        else
        {
            return this._showProgramPartDialog;
        }
    },
    
    /**
     * @private
     * Open the dialog to choose options of deletion for program parts
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
     * @param {Integer} nbCourses The number of child ELPs concerned by deletion
     */
    _showProgramPartDialog: function(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
    {
        this._drawDeleteProgramPartDialog(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses);
        this._deleteProgramPartBox.show();
    },
	
    /**
     * @private
     * Open the dialog to choose options of deletion for course lists
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
     * @param {Integer} nbCourses The number of child ELPs concerned by deletion
     */
    _showCourseListDialog: function(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
    {
        this._drawDeleteCourseListDialog(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses);
        this._deleteCourseListBox.show();
    },
    
    /**
     * @private
     * Open the dialog to choose options of deletion for courses
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
     * @param {Integer} nbCourses The number of child ELPs concerned by deletion
     */
    _showCourseDialog: function(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
    {
        this._drawDeleteCourseDialog(controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses);
        this._deleteCourseBox.show();
    },
	
	/**
	 * Draw the delete course list dialog box
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
     * @param {Integer} nbCourses The number of child ELPs concerned by deletion
     * @private
	 */
	_drawDeleteCourseListDialog: function (controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
	{
        let fullHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + nbCourses + contentIdsToDelete.length); // add the size of selected contents to be deleted
        if (this._deleteCourseListBox == null)
		{
			this._deleteCourseListBox = Ext.create('Ametys.window.DialogBox', {
				title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_TITLE}}",
				iconCls : 'ametysicon-delete30',
				
				width : 500,
				items : [{
			                xtype: 'component',
			                html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_HINT1}}",
			                cls: 'a-text'
			            },
			            {
			            	 xtype: 'form',
			            	 items: [{
					                	xtype: 'radiofield',
					                	hideLabel: true,
					                	checked: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_SINGLE_LABEL}}",
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_SINGLE_DESC}}",
					                	name: 'mode',
					                	inputValue: this.SINGLE_MODE,
                                        itemId: "courselist-single",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                },
					                {
										xtype: 'radiofield',
					                	hideLabel: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint,
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_CHILD_DESC}}",
					                	name: 'mode',
					                	inputValue: this.FULL_MODE,
                                        itemId: "courselist-full",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                }]
			            },
	                    {
			                xtype: 'component',
			                html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_HINT2}}",
			                cls: 'a-text'
			            }
					],
				
				closeAction: 'hide',
				defaultButton: 'validate',
				
				buttonAlign: 'center',
				buttons : [ {
                    itemId: 'validate',
					reference: 'validate',
					text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_OK}}",
					handler : function () { this._validateDelete(controller, this._deleteCourseListBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); },
					scope: this
				},
				{
                    itemId: 'cancel',
					reference: 'cancel',
					text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_CANCEL}}",
					handler : function () { this._deleteCourseListBox.close(); },
					scope: this
				}]
			});
		}
        else
        {
            this._deleteCourseListBox.down("#validate").setHandler(function () { this._validateDelete(controller, this._deleteCourseListBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); });
            this._deleteCourseListBox.down("#courselist-full").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_LIST_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint);
        }
	},
	
	/**
	 * Draw the delete course dialog box
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets to delete
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
     * @param {Integer} nbCourses The number of child ELPs concerned by deletion
     * @private
	 */
	_drawDeleteCourseDialog: function (controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
	{
        let fullHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + nbCourses + contentIdsToDelete.length); // add the size of selected contents to be deleted
		if (this._deleteCourseBox == null)
		{
			this._deleteCourseBox = Ext.create('Ametys.window.DialogBox', {
				title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_TITLE}}",
				iconCls : 'ametysicon-delete30',
				
				width : 400,
				items : [{
			                xtype: 'component',
			                html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_HINT1}}",
			                cls: 'a-text'
			            },
			            {
			            	 xtype: 'form',
			            	 items: [{
					                	xtype: 'radiofield',
					                	hideLabel: true,
					                	checked: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_SINGLE_LABEL}}",
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_SINGLE_DESC}}",
					                	name: 'mode',
					                	inputValue: this.SINGLE_MODE,
                                        itemId: "course-single",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                },
					                {
										xtype: 'radiofield',
					                	hideLabel: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint,
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_CHILD_DESC}}",
					                	name: 'mode',
					                	inputValue: this.FULL_MODE,
                                        itemId: "course-full",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                }]
			            },
	                    {
			                xtype: 'component',
			                html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_HINT2}}",
			                cls: 'a-text'
			            }
					],
				
				closeAction: 'hide',
				defaultButton: 'validate',
				
				buttonAlign: 'center',
				buttons : [ {
                    itemId: 'validate',
					reference: 'validate',
					text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_OK}}",
					handler : function () { this._validateDelete(controller, this._deleteCourseBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); },
					scope: this
				},
				{
                    itemId: 'cancel',
					reference: 'cancel',
					text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_CANCEL}}",
					handler : function () { this._deleteCourseBox.close(); },
					scope: this
				}]
			});
		}
        else
        {
            this._deleteCourseBox.down("#validate").setHandler(function () { this._validateDelete(controller, this._deleteCourseBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); });
            this._deleteCourseBox.down("#course-full").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_COURSE_MSGBOX_RADIO_CHILD_LABEL}}<br/>" + fullHint);
        }
	},
	
	/**
	 * Draw the delete program dialog box
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets to delete
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @param {Integer} nbOnlyStructureContents The number of child contents in the structure concerned by deletion
     * @param {Integer} nbCourses The number of child ELPs concerned by deletion
     * @private
	 */
	_drawDeleteProgramPartDialog: function (controller, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents, nbOnlyStructureContents, nbCourses)
	{
        let structureOnlyHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + contentIdsToDelete.length); // add the size of selected contents to be deleted
        let fullHint = Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_RADIO_NB_CONTENT_HINT}}", nbOnlyStructureContents + nbCourses + contentIdsToDelete.length); // add the size of selected contents to be deleted
		if (this._deleteProgramPartBox == null)
		{
			this._deleteProgramPartBox = Ext.create('Ametys.window.DialogBox', {
				title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_TITLE}}",
				iconCls : 'ametysicon-delete30',
				
				width : 600,
				items : [{
			                xtype: 'component',
			                html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_HINT1}}",
			                cls: 'a-text'
			            },
			            {
			            	 xtype: 'form',
			            	 items: [{
					                	xtype: 'radiofield',
					                	hideLabel: true,
					                	checked: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_SINGLE_LABEL}}",
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_SINGLE_DESC}}",
					                	name: 'mode',
					                	inputValue: this.SINGLE_MODE,
                                        itemId: "program-part-single",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                },
					                {
										xtype: 'radiofield',
					                	hideLabel: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_STRUCTURE_LABEL}}<br/>" + structureOnlyHint,
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_STRUCTURE_DESC}}",
					                	name: 'mode',
					                	inputValue: this.STRUCTURE_ONLY_MODE,
                                        itemId: "program-part-structure-only",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                },
					                {
										xtype: 'radiofield',
					                	hideLabel: true,
					                	boxLabel: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_ALL_LABEL}}<br/>" + fullHint,
					                	ametysDescription: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_ALL_DESC}}",
					                	name: 'mode',
					                	inputValue: this.FULL_MODE,
                                        itemId: "program-part-full",
					                	style: {
					                    	marginLeft: '15px'
					                    }
					                }]
		            	},
	                    {
			                xtype: 'component',
			                html: "{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_HINT2}}",
			                cls: 'a-text'
			            }
					],
				
				closeAction: 'hide',
				defaultButton: 'validate',
				
				buttonAlign: 'center',
				buttons : [ {
                    itemId: 'validate',
					reference: 'validate',
					text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_OK}}",
					handler : function () { this._validateDelete(controller, this._deleteProgramPartBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); },
					scope: this
				},
				{
                    itemId: 'cancel',
					reference: 'cancel',
					text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_CANCEL}}",
					handler : function () { this._deleteProgramPartBox.close(); },
					scope: this
				}]
			});
		}
        else
        {
            this._deleteProgramPartBox.down("#validate").setHandler(function () { this._validateDelete(controller, this._deleteProgramPartBox, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents); });
            this._deleteProgramPartBox.down("#program-part-structure-only").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_STRUCTURE_LABEL}}<br/>" + structureOnlyHint);
            this._deleteProgramPartBox.down("#program-part-full").setBoxLabel("{{i18n PLUGINS_ODF_CONTENT_DELETE_PROGRAM_PART_MSGBOX_RADIO_ALL_LABEL}}<br/>" + fullHint);
        }
	},
    
    /**
     * Function invoked when validating the dialog box
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.window.DialogBox} box The dialog box
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentsInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @private
     */
    _validateDelete: function (controller, box, contentTargets, contentIdsToDelete, contentsInfo, pathsToReferencedContents)
    {
        var deleteMode = box.down('form').getForm().findField("mode").getGroupValue();
        box.close();
        this._showConfirmMsg(controller, contentTargets, deleteMode, contentIdsToDelete, contentsInfo, pathsToReferencedContents);
    },
    
    /**
     * Show confiramtion before deletion
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets to delete
     * @param {String} deleteMode the deletion mode
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object} contentInfo information retrieved by the server organized by content id
     * @param {Array} pathsToReferencedContents List of all the path referencing any of the content to delete
     * @private
     */
    _showConfirmMsg: function(controller, contentTargets, deleteMode, contentIdsToDelete, contentsInfo, pathsToReferencedContents)
    {
        var contentDescriptions = this._getContentDescriptions(contentTargets, contentIdsToDelete, contentsInfo);
        
        var intro = "";
        switch (deleteMode)
        {
            case this.STRUCTURE_ONLY_MODE:
                intro = contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_STRUCTURE_ONLY_MODE_MSGBOX_SINGLE}}": "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_STRUCTURE_ONLY_MODE_MSGBOX_SEVERAL}}";
                break;
            case this.FULL_MODE:
                intro = contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_FULL_MODE_MSGBOX_SINGLE}}": "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_FULL_MODE_MSGBOX_SEVERAL}}";
                break;
            case this.SINGLE_MODE:
            default:
                intro = contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_SINGLE_MODE_MSGBOX_SINGLE}}": "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_SINGLE_MODE_MSGBOX_SEVERAL}}";
                break;
        }
        
        
        var contentList = "<ul>";
        var idx = 0;
        var maxItems = Ext.Array.min([contentDescriptions.length, 5]);
        while (idx < maxItems)
        {
            if (idx < 4 || contentDescriptions.length == 5)
            {
                contentList += "<li>" + contentDescriptions[idx] + "</li>";
            }
            else
            {
                contentList += "<li>" + Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_MORE}}", contentDescriptions.length - 4) + "</li>";
            }
            idx++;
        }
                contentList += "</ul>";
        
        var items = [
            {
                xtype: 'component',
                html: intro,
                cls: 'a-text'
            },
            {
                xtype: 'component',
                html: contentList,
                border: true,
                cls: 'a-text',
                scrollable: true,
                maxHeight: 300
            },
        ];
        
        if (pathsToReferencedContents.length > 0)
        {
            var message = "<ul>\n";
            pathsToReferencedContents.forEach(function(path, idx, paths) {
                    message += '<li>' + path.path + ' <strong>' + path.title + '</strong> (' + path.code + ')</li>\n';
            });
            message += "</ul>\n"
            
            items.push(
                {
                    xtype: 'component',
                    html: contentDescriptions.length == 1 ? "{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_REFERENCED_SINGLE}}" : Ext.String.format("{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_REFERENCED_SEVERAL}}", contentTargets.length),
                    cls: 'a-text'
                }
            );
            items.push(
                {
                    xtype: 'component',
                    html: message,
                    border: true,
                    cls: 'a-text',
                    scrollable: true,
                    maxHeight: 150
                }
            );
        }
        
        
        var box = Ext.create('Ametys.window.DialogBox', {
                title :"{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_TITLE}}",
                iconCls : 'ametysicon-sign-question',
                
                width : 650,
                maxHeight: 500,
                
                items : items,
                
                defaultButton: 'validate',
                closeAction: 'destroy',
                
                buttonAlign: 'center',
                buttons : [ {
                    itemId: 'validate',
                    reference: 'validate',
                    text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_YES_BTN}}",
                    handler : function () { box.close(); this._deleteConfirmed(controller, contentTargets, deleteMode, contentIdsToDelete); },
                    scope: this
                },
                {
                    itemId: 'cancel',
                    reference: 'cancel',
                    text :"{{i18n PLUGINS_ODF_CONTENT_DELETE_CONFIRM_MSGBOX_NO_BTN}}",
                    handler : function () { box.close(); },
                    scope: this
                }]
        });
        
        box.show();
    },
    
    _getContentDescriptions: function(contentTargets, contentIdsToDelete, contentsInfo)
    {
        var contentDescriptions = [];
        contentTargets.forEach(function(target, _idx, _targets) {
            if (Ext.Array.contains(contentIdsToDelete, target.getParameters().id))
            {
                if (contentsInfo[target.getParameters().id])
                {
                    contentDescriptions.push("<strong>" + target.getParameters().title + "</strong> (" + contentsInfo[target.getParameters().id].code + ")");
                }
                else
                {
                    contentDescriptions.push("<strong>" + target.getParameters().title + "</strong>");
                }
            }
        });
        return contentDescriptions;
    },
    
	/**
	 * Callback function invoked after the _showConfirmMsg box is closed
	 * @param {String} answer Id of the button that was clicked
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the #act function
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets
     * @param {String} deleteMode The deletion mode
     * @param {String[]} contentIdsToDelete The content IDs to delete
	 * @private
	 */
    _deleteConfirmed: function(controller, contentTargets, deleteMode, contentIdsToDelete)
    {
        controller.serverCall('deleteContents', [contentIdsToDelete, { "mode": deleteMode }], Ext.bind(this._deleteCb, this),
            {
                priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
                arguments: {
                    contentTargets: contentTargets,
                    contentIdsToDelete: contentIdsToDelete
                },
                errorMessage: {
                    msg: "{{i18n PLUGINS_ODF_CONTENT_DELETE_MSGBOX_ERROR_MSG}}",
                    category: 'Ametys.plugins.odf.content.DeleteContentAction'
                },
                waitMessage: false
            }
        );
    },
    
	/**
	 * Callback function called after #act is processed.
	 * @param {Object} response The JSON result 
	 * @param {Object} args The arguments
     * @param {Ametys.message.MessageTarget[]} args.contentTargets The content targets
     * @param {String[]} args.contentIdsToDelete The content IDs to delete
	 * @private
	 */
	_deleteCb: function (response, args)
	{
        var contentIdsToDelete = args.contentIdsToDelete;
        var contentTargets = args.contentTargets;
        var allInitialDeletedContents = [];
        var deletedContentTargets = [];
        for (var k in contentIdsToDelete)
        {
        	var contentId = contentIdsToDelete[k];
    		var deletedContents = response[contentId]['deleted-contents'];
			var initialContent = response[contentId]['initial-content'];
            for (var i=0; i < deletedContents.length; i++)
			{
				var deletedContentId = deletedContents[i].id;
				if (deletedContentId == initialContent.id)
				{
    				allInitialDeletedContents.push(initialContent);
				}

				// Remove content from navigation history
        		Ametys.navhistory.HistoryDAO.removeEntry (deletedContentId);
        		
				var contentTarget = this._getTargetFromId(contentTargets, deletedContentId);
	        	if (contentTarget)
				{
	        		deletedContentTargets.push(contentTarget);
				}
			}
        }
        
        // Fires deleted event
        Ext.create("Ametys.message.Message", {
            type: Ametys.message.Message.DELETED,
            // All ODF contents are trashable
            parameters : {trashed : true},
            targets: deletedContentTargets
        });

        this._showReport(response, contentIdsToDelete, allInitialDeletedContents);
	},
	
	/**
     * Get the target from the content id
     * @param {Ametys.message.MessageTarget[]} contentTargets The content targets 
     * @param {String} contentId The content ID
     * @private
     */
	_getTargetFromId: function (contentTargets, contentId)
    {
    	var target = null;
        Ext.Array.forEach (contentTargets, function (localContentTarget) {
            if (contentId == localContentTarget.getParameters().id)
            {
                target = localContentTarget;
                return false; // stop iteration;
            }
        });
        
        return target;
    },
	
	/**
	 * Display report after deletion
	 * @param {Object} response The JSON result 
     * @param {String[]} contentIdsToDelete The content IDs to delete
     * @param {Object[]} allInitialDeletedContents The initial deleted contents 
	 * @private
	 */
	_showReport: function(response, contentIdsToDelete, allInitialDeletedContents)
	{
		var referencedContents = response["all-referenced-contents"];
        var lockedContents = response["all-locked-contents"];
        var unauthorizedContents = response["all-unauthorized-contents"];
        var undeletedContents = response["all-undeleted-contents"];
        
		for (var i in contentIdsToDelete)
		{
			var contentIdToDelete = contentIdsToDelete[i];
			var contentInfo = response[contentIdToDelete];
			
			// If check before deletion failed, the initial content is no deleted because some contents are referenced, locked or unauthorized
			if (contentInfo['check-before-deletion-failed'])
			{
				if (contentInfo['referenced-contents'].length > 0 || contentInfo['unauthorized-contents'].length > 0 || contentInfo['locked-contents'].length > 0)
				{
					undeletedContents.push(contentInfo['initial-content']);
				}
			}
		}
	
    	// Prerequisites for deletion are not met, display an error message
		if (undeletedContents.length > 0 || lockedContents.length > 0 || unauthorizedContents.length > 0 || referencedContents.length > 0)
		{
            var message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, undeletedContents, "{{i18n plugin.cms:CONTENT_DELETE_FAILED_CONTENTS}}<strong>", "</strong>");
            
            if (lockedContents.length > 0 || unauthorizedContents.length > 0 || referencedContents.length > 0)
            {
            	// If there are some undeleted contents, we add this message to explain the following reasons
            	if (undeletedContents.length > 0)
            	{
                    message += "<br/><br/>{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_ERROR_START}}";
            	}
                
                message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, lockedContents, "{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_LOCKED_CONTENTS}}<strong>", "</strong>");
                message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, unauthorizedContents, "{{i18n plugin.cms:CONTENT_DELETE_UNAUTHORIZED_CONTENTS}}<strong>", "</strong>");
                message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, referencedContents, "{{i18n plugin.cms:CONTENT_DELETE_REFERENCED_CONTENTS}}<strong>", "</strong>.<br/>{{i18n plugin.cms:CONTENT_DELETE_REFERENCED_CONTENTS_END}}");
            }
            
            // Notify error in content deletion
            Ametys.notify({
                type: 'error',
                iconGlyph: 'ametysicon-text70',
                title: "{{i18n plugin.cms:CONTENT_DELETE_LABEL}}",
                description: message
            });
		}
		
		if (allInitialDeletedContents.length > 0)
        {
        	var message = '';
        	if (allInitialDeletedContents.length > 1)
        	{
        		var msgPart1 = Ext.String.format("{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SEVERAL_PART1}}", allInitialDeletedContents.length);
                message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, allInitialDeletedContents, msgPart1 + "<strong>", "</strong>{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SEVERAL_PART2}}");
        	}
        	else
        	{
        	    message = Ametys.cms.content.ContentDAO._buildErrorMessage(message, allInitialDeletedContents, "{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SINGLE_PART1}}<strong>", "</strong>{{i18n plugin.odf:PLUGINS_ODF_CONTENT_DELETE_CONTENTS_OK_MSG_SINGLE_PART2}}");
        	}
        	
        	// Notify content deletion
            Ametys.notify({
                type: 'info',
                iconGlyph: 'ametysicon-text70',
                title: "{{i18n plugin.cms:PLUGINS_CMS_NOTIFICATION_DELETE_CONTENT_TITLE}}",
                description: message
            });
        }
	}
});