/*
 *  Copyright 2010 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 tool does display the history of a content in a timeline
 * @private
 */
Ext.define('Ametys.plugins.cms.content.tool.HistoryTool', {
    extend: "Ametys.tool.SelectionTool",
    
    /**
     * @private
     * @readonly
     * @property {Number} MIN_WIDTH The min width
     */
    MIN_WIDTH: 350,
    
    /**
     * @private
     * @property {Ext.Template} _contentHintTpl The template used for hint description
     */
    _contentHintTpl: new Ext.XTemplate("{{i18n PLUGINS_CMS_UITOOL_HISTORY_CONTENT_HINT}} <strong>{[Ext.String.escapeHtml(values.title)]}</strong>"),
    
    /**
     * @private
     * @property {Ext.Template} _versionTpl The template used for versions
     */
    _versionTpl: Ext.create ('Ext.XTemplate', '<tpl for="."><div class="version {cls}" data-record-first="{first}" data-record-last="{last}">{version}</div></tpl>'),
    
    /**
     * @private
     * @property {List} _workflow The list of versions of the workflow
     */
    _workflow: [],
    
     /**
     * @cfg {String} showJCRVersionButtonIconCls The separated CSS classes to apply to button to show JCR versions
     */
    showJCRVersionButtonIconCls: 'ametysicon-code-css-border-radius decorator-ametysicon-body-part-eye',
    
    /**
     * @cfg {String} showJCRVersionButtonTooltip Tooltip of the button to show JCR versions
     */
    showJCRVersionButtonTooltip: "{{i18n PLUGINS_CMS_UITOOL_HISTORY_SHOW_JCR_VERSIONS_BUTTON}}",
    
    /**
     * @cfg {String} showOnlyWorkflowVersionsButtonIconCls The separated CSS classes to apply to button to hide JCR Versions
     */
    showOnlyWorkflowVersionsButtonIconCls: 'ametysicon-code-css-border-radius decorator-ametysicon-body-part-eye-no',
    /**
     * @cfg {String} showOnlyWorkflowVersionsButtonTooltip Tooltip of the button to hide JCR versions
     */
    showOnlyWorkflowVersionsButtonTooltip: "{{i18n PLUGINS_CMS_UITOOL_HISTORY_HIDE_JCR_VERSIONS_BUTTON}}",
    
    constructor: function(config)
    {
        this.callParent(arguments);
        
        Ametys.message.MessageBus.on(Ametys.message.Message.WORKFLOW_CHANGED, this._onWorkflowChanged, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onDeleted, this);
    },
    
    createPanel: function()
    {
        var me = this;
        this._button = Ext.create("Ext.Button", {
            // show JCR versions
            iconCls: this.showJCRVersionButtonIconCls,
            tooltip: this.showJCRVersionButtonTooltip,
            scope: this,
            enableToggle: true,
            toggleHandler: function(btn, state) {
                // The starting applyState triggers this function... too soon
                if (me._button)
                {
                    me._showJCRVersions(btn, state);
                    btn.saveState();
                }
            },
            cls: 'a-btn-light',
            stateful: true,
            stateId: this.getId() + "$jcrversion",
            itemId: 'button-toggle-jcr',
            applyState: function(state) {
                this.setPressed(state && state.pressed);
            },
            getState: function() {
                return {
                    pressed: this.pressed
                };
            }
        });
        
        this._timeline = Ext.create('Ametys.timeline.Timeline', {
            scrollable: true,
            
            minInsideWidth: this.MIN_WIDTH,
            
            dockedItems: {
                dock: 'top',
                xtype: 'container',
                layout: {
                    type: 'hbox',
                    align: 'middle'
                },
                ui: 'tool-hintmessage',
                cls:'hint',
                items: [
                    {
                        // hint
                        xtype: 'component',
                        itemId: 'content-info',
                        ui: 'tool-hintmessage',
                        html: '',
                        flex: 1
                    },
                    {
                        xtype: 'container',
                        layout: {
                            type: 'vbox',
                            align: 'stretch'
                        },
                        items: [
                            {
                                xtype: 'button',
                                cls: 'a-btn-light',
                                iconCls: 'ametysicon-sign-info',
                                disabled: true, 
                                tooltip: "{{i18n PLUGINS_CMS_UITOOL_HISTORY_CONTENT_HINT_2}}"
                            },
                            this._button
                        ] 
                    }
                ]
            },
            
            viewConfig: {
                getRowClass: function(record) { 
                    return record.get('live') ? 'row-live' : (record.get('valid') ? 'row-valid' : ''); 
                },
            
                listeners: {
                    'afterrender': Ext.bind(this._onAfterViewRender, this)
                }
            },
            
            cls: ['a-timeline', 'uitool-history'],
            
            timelineItemHTML: ['<div class="step-wrap {stepCls} {additionalCls}"><div class="step">{step}</div></div>',
                               '<div class="timeline-item {additionalCls}">',
                               '<tpl if="profileImg">',
                                    '<div class="profile-img-wrap" data-qtip="{userTooltip}">',
                                        '<tpl if="profileImg"><img src="{profileImg}" alt=""/></tpl>',
                                        '<tpl if="profileGlyph"><span style="height:46px; width: 46px; font-size: 46px" class="profile-img-glyph {profileGlyph}"></span></tpl>',
                                        '<div>{hour}</div>',
                                    '</div>',
                                '<tpl else>',
                                    '<div class="profile-hour-wrap">',
                                        '<div>{hour}</div>',
                                    '</div>',
                                '</tpl>',
                                '<div class="version-line"></div>',
                                '<tpl if="profileImg">',
                                  '<div class="contents-wrap">',
                                    '<span class="vertical-line"></span>',
                                        '<tpl if="topText && topText != \'\'">',
                                            '<div class="top">{topText}</div>',
                                        '</tpl>',
                                        '<div class="text" data-qtip="{userTooltip}">{text}</div>',
                                        '<tpl if="comment && comment != \'\'">',
                                            '<div class="comment"><span class="x-fa fa-quote-left"></span>{comment}</div>',
                                        '</tpl>',
                                        '<div class="bg-image" style="background-image:url(\'{icon}\')"></div>',
                                    '</div>',
                               '</tpl>',
                            '</div>'],
                            
            listeners: {
                'afterlayout': Ext.bind(this._onAfterLayout, this),
            }               
        });
        
        this._timeline.getStore().on('datachanged', this._onLoad, this);
        
        return Ext.create('Ext.panel.Panel', {
            scrollable: false, 
            border: false,
            layout: 'card',
            activeItem: 0,
            
            items: [{
                    xtype: 'component',
                    cls: 'a-panel-text-empty',
                    border: false,
                    html: ''
                }, 
                this._timeline
            ]
        });
    },
    
    /**
     * @private
     * Toggle handle of the show JCR versions button
     * @param {Object} btn the button
     * @param {Object} state the new state of the button
     */
    _showJCRVersions: function(btn, state)
    {
        if (state)
        {
            btn.setIconCls(this.showOnlyWorkflowVersionsButtonIconCls);
            btn.setTooltip(this.showOnlyWorkflowVersionsButtonTooltip)
        }
        else
        {
            btn.setIconCls(this.showJCRVersionButtonIconCls);
            btn.setTooltip(this.showJCRVersionButtonTooltip);
        }
        
        // Update the versions displayed, display or not the intermediate JCR versions
        this._updateHistoryView(this._workflow);
    },
    
    _isShowJCRVersionPressed: function()
    {
        return this._button.pressed;
    },
    
    refresh: function (manual)
    {
        this.showRefreshing();
        this._workflow = [];
        
        var contentTarget = this.getCurrentSelectionTargets().length > 0 ? this.getCurrentSelectionTargets()[0] : null;
        if (contentTarget != null)
        {
            this._contentId = contentTarget.getParameters().id;
            
            this.getContentPanel().down("#content-info").update(this._contentHintTpl.applyTemplate({'title': contentTarget.getParameters().title}));
            
            Ametys.data.ServerComm.send({
                plugin: this.getPluginName(),
                url: 'history.json',
                parameters: {contentId: this._contentId}, 
                priority: Ametys.data.ServerComm.PRIORITY_MAJOR, 
                callback: {
                    handler: this._updateHistoryViewWithServerResponse,
                    scope: this,
                    arguments: [this._contentId]
                },
                responseType: 'text'
            });
        }
        else
        {
            // Nothing to do.
            // Do not use the noSelectionMatch method to avoid erasing the current message
            this.showRefreshed();
        }
    },
    
    /**
     * @private
     * Callback function to update the history view with the server response
     * @param {Object} response the server response
     * @param {Object} args the callback arguments
     */
    _updateHistoryViewWithServerResponse : function (response, args)
    {
        var result = Ext.JSON.decode(Ext.dom.Query.selectValue("", response));
        
        if (result != null && result.hasRight == false)
        {
            this._workflow = [];
            
            var panel = this.getContentPanel().items.get(0);
            panel.update(this.getInitialConfig("selection-description-noright"));
            this.getContentPanel().getLayout().setActiveItem(0);
            this.showRefreshed();
        }
        else if (result != null)
        {
            this._workflow = result.workflow;
            this._updateHistoryView(this._workflow);
        }
        else
        {
            this._workflow = [];
            
            this.getContentPanel().getLayout().setActiveItem(0);
            this.showRefreshed();
        }
    },
    
    /**
     * @private
     * Check if two dates of format ''2023-10-17T10:49:23.098Z' are the same, ignoring the seconds
     * @param {String} stringDate1 the first date
     * @param {String} stringDate2 the second date
     * @return {String} true if the date are the same (at about 60 seconds), false otherwise
     */
    _sameDate(stringDate1, stringDate2)
    {
        var date1 = new Date(stringDate1);
        var date2 = new Date(stringDate2);
        
        return (new Date(date1).getTime() - new Date(date2).getTime()) < 60000;
    },
    
    /**
     * @private
     * Callback function to update the history view from the workflow
     * @param {Object} workflow the workflow
     */
    _updateHistoryView : function (workflow)
    {
        // Workflow step are order from newest to oldest
        var me = this;
        var data = [];
        
        // save the last handled version to be able to determine when we change version
        var precedeVersion = null;
        var beyondIncompatibleVersion = false;
        
        for (var i=0; i < workflow.length; i++)
        {
            var step = workflow[i];
            
            var versionIndex = 0;
            
            // All step version except the first one are newer than the step itself
            // So we start by handling them.
            if (me._isShowJCRVersionPressed() && step.versions.length > 1)
            {
                // Ignore the oldest version of the step, it will be handled by the step itself
                for (; versionIndex < step.versions.length - 1; versionIndex++)
                {
                    var version = step.versions[versionIndex];
                    
                    var currentVersion = version.name;
                    var nextVersion = versionIndex < step.versions.length - 1 ? step.versions[versionIndex+1].name : null;
                    
                    var isFirstOfSameVersion = nextVersion != currentVersion;
                    var isLastOfSameVersion = precedeVersion != currentVersion;
                    
                    precedeVersion = currentVersion;
                    
                    // The step is the current step if the parent step is current and we are dealing with the first element of the list (= the last version)
                    var d = this._convertSubStep2Timeline(version, (step.current && versionIndex == 0), isLastOfSameVersion, isFirstOfSameVersion, isLastOfSameVersion, beyondIncompatibleVersion);
                    data.push(d);
                    beyondIncompatibleVersion = d.beyondIncompatibleVersion;
                }
            }
            
            // Handled the step version using the next version index for version
            // ie newest when hidding JCR version or oldest when displaying the JCR version
            var currentVersion = step.versions[versionIndex].name;
            // Next version to consider is always in the next step
            var nextVersion = i < workflow.length - 1 ? workflow[i+1].versions[0].name : null;
            
            var isFirstOfSameVersion = nextVersion != currentVersion;
            var isLastOfSameVersion = precedeVersion != currentVersion;
            
            precedeVersion = currentVersion;
            
            var d = me._convertStep2Timeline(step, i < workflow.length - 1 ? workflow[i+1] : null, isLastOfSameVersion, isFirstOfSameVersion, isLastOfSameVersion, beyondIncompatibleVersion);
            data.push(d);
            beyondIncompatibleVersion = d.beyondIncompatibleVersion;
        }
        
        this._timeline.getStore().loadData(data);
        
        this.getContentPanel().getLayout().setActiveItem(1);
        
        this.showRefreshed();
    },
    
    /**
     * @private
     * Get the label of the version
     * @param {Ext.view.Table} view the view
     */
    _getVersionLabel: function (showVersion, isCurrent, beyondIncompatibleVersion, versionToUse)
    {
        var version = null;
        if (showVersion)
        {
            var versionName = versionToUse.name;
            var versionLabel = "{{i18n PLUGINS_CMS_UITOOL_HISTORY_VERSION_NAME}}" + (versionName.length > 3 ? '<br/>' : ' ') + versionName;
            
            if (!isCurrent)
            {
                var rawName = versionToUse.rawName;
                if (!rawName)
                {
                    version = "<span class='not-compatible' title=\"{{i18n PLUGINS_CMS_UITOOL_HISTORY_UNAVAILABLE_VERSION}}\">"
                                + versionLabel
                                + '</span>';
                }
                else if (!beyondIncompatibleVersion)
                {
                    version = '<a href="javascript:(function(){Ametys.tool.ToolsManager.getTool(\'' + this.getId() + '\').openRevision(\'' + versionName + '\', \'' + rawName + '\')})()">'
                                + versionLabel
                                + '</a>';
                }
                else
                {
                    version = "<span class='not-compatible' title=\"{{i18n PLUGINS_CMS_UITOOL_HISTORY_NOTCOMPATIBLE_VERSION}}\">"
                                + versionLabel
                                + '</span>';
                }
            }
            else
            {
                version = "<span>" + versionLabel + "<br/>{{i18n PLUGINS_CMS_UITOOL_HISTORY_CURRENT_VERSION}}</span>";
            }
        }
        
        return version;
    },
    
    /**
     * @private
     * Convert a non workflow step record to a timeline record
     * @param {Object} step the step
     * @param {boolean} current true if the step is the current one, false otherwise
     * @param {Boolean} showVersion should show version
     * @param {Boolean} isFirstOfSameVersion true if this step is the first of the current version
     * @param {Boolean} isLastOfSameVersion true if this step is the last of the current version
     * @param {Boolean} beyondIncompatibleVersion true if we are in the incompatible versions
     * @return {Object} the configuration of a timeline record
     */
    _convertSubStep2Timeline: function (version, current, showVersion, isFirstOfSameVersion, isLastOfSameVersion, beyondIncompatibleVersion)
    {
        var additionalCls = [];
        var isLive = Ext.Array.contains (version.label, 'Live');
        var isVersionValid = version.valid;
        
        beyondIncompatibleVersion = beyondIncompatibleVersion || Ext.Array.contains (version.label, 'NotCompatible'); // At this time only check the most recent version
        
        if (current)
        {
            additionalCls.push('current');
        }
        
        if (isVersionValid)
        {
            additionalCls.push('valid');
        }
        
        if (isLive)
        {
            additionalCls.push('live');
        }
        
        if (isFirstOfSameVersion)
        {
            additionalCls.push('first');
        }
        
        var versionLabel = this._getVersionLabel(showVersion, current, beyondIncompatibleVersion, version);
        
        return {
            id: this.getId() + '-' + Ext.id(),
            date: version.createdAt,
            icon: Ametys.CONTEXT_PATH + version.actionIconMedium,
            stepCls: isLastOfSameVersion ? 'last' : '',
            additionalCls: additionalCls.join(' '),
            versionName: version.name,
            version: versionLabel,
            live: isLive,
            valid: isVersionValid,
            beyondIncompatibleVersion: beyondIncompatibleVersion || (version.label == 'NotCompatible'), // For the followers, we need to check the tag in all versions
            topText: '',
            cls: 'step'
        }
    },
    
    /**
     * @private
     * Compute the tooltip
     * @param {Object} user The user to display
     * @returns {String} The tooltip
     */
    _getUserTooltip: function(user)
    {
        var login = user.login;
        var populationId = user.populationId;
        var username = user.fullname || "{{i18n plugin.core:PLUGINS_CORE_USERS_UNKNOWN_USER}}";
        
        var populationLabel = user.populationLabel || populationId;
        return Ametys.helper.Users.renderUser(login, populationLabel, username);
    },
    
    /**
     * @private
     * Convert a workflow step record to a timeline record
     * @param {Object} step the workflow step
     * @param {Boolean} showVersion should show version
     * @param {Boolean} isFirstOfSameVersion true if this step is the first of the current version
     * @param {Boolean} isLastOfSameVersion true if this step is the last of the current version
     * @param {Boolean} beyondIncompatibleVersion true if we are in the incompatible versions
     * @return {Object} the configuration of a timeline record
     */
    _convertStep2Timeline: function (step, previousStep, showVersion, isFirstOfSameVersion, isLastOfSameVersion, beyondIncompatibleVersion)
    {
        function _hasTag(versions, tag)
        {
            for (var i = 0; i < versions.length; i++)
            {
                if (versions[i].label == tag)
                {
                    return true;
                }
            }
            return false;
        }
        
        var additionalCls = [];
        var isValid = step.validation;
        var isVersionValid = step.versions[0].valid;
        
        beyondIncompatibleVersion = beyondIncompatibleVersion || Ext.Array.contains (step.versions[0].label, 'NotCompatible'); // At this time only check the most recent version
        
        var versions = step.versions;
        var versionToUse = versions[0];
        
        if (this._isShowJCRVersionPressed() && versions.length > 1)
        {
            versionToUse = versions[versions.length - 1];
            if (!this._sameDate(versionToUse.createdAt, step.date))
            {
                if (previousStep != null)
                {
                    
                    versionToUse = previousStep.versions[0];
                }
            }
        }
        
        var isLive = Ext.Array.contains (versionToUse.label, 'Live');
        var isCurrent = versionToUse == versions[0] ? step.current : false;

        if (isCurrent)
        {
            additionalCls.push('current');
        }
        
        if (isValid || isVersionValid)
        {
            additionalCls.push('valid');
        }
        
        if (isLive)
        {
            additionalCls.push('live');
        }
        
        if (isFirstOfSameVersion)
        {
            additionalCls.push('first');
        }
        
        var version = this._getVersionLabel(showVersion, isCurrent, beyondIncompatibleVersion, versionToUse);
        
        return {
            id: this.getId() + '-' + Ext.id(),
            date: step.date,
            username: (step.caller ? step.caller.fullname : '') || "{{i18n plugin.core:PLUGINS_CORE_USERS_UNKNOWN_USER}}",
            userTooltip: step.caller ? this._getUserTooltip(step.caller) : null,
            profileImg: Ametys.helper.Users.getUserImage(step.caller ? step.caller.login : 'undefined', step.caller ? step.caller.populationId : 'undefined', 46),
            icon: Ametys.CONTEXT_PATH + step.actionIconMedium,
            text: step.actionLabel,
            step: step.description,
            stepCls: isLastOfSameVersion ? 'last' : '',
            comment: step.comment,
            additionalCls: additionalCls.join(' '),
            versionName: versionToUse.name,
            version: version,
            live: isLive,
            valid: isValid || isVersionValid,
            beyondIncompatibleVersion: beyondIncompatibleVersion || _hasTag(step.versions, 'NotCompatible'), // For the followers, we need to check the tag in all versions
            topText: '',
            cls: 'step'
        }
    },
    
    /**
     * @private
     * Listener when the view is rendered.
     * Insert a container element for versions
     * @param {Ext.view.Table} view the view
     */
    _onAfterViewRender: function (view)
    {
        // 1 - Insert container for versions
        view.getEl().insertFirst({
            tag: 'div',
            style: 'min-width: ' + this.MIN_WIDTH + 'px',
            cls: 'versions-container'
        });
        view.mon(view.getEl(), 'scroll', Ext.bind(this._onScroll, this));
    },
    
    /**
     * @private
     * Listener when the store is loaded
     * @param {Ametys.timeline.Timeline.TimelineStore} store The store
     */
    _onLoad: function (store)
    {
        // 2 - Insert versions labels in container
        var versions = [];
        
        var currentVersion = null;
        var beginRecord = null;
        var lastRecord = null;
        
        var record1, record2;
        store.getData().each (function (record) {
            
            var v = record.get('versionName');
            if (v != currentVersion)
            {
                if (currentVersion != null)
                {
                    versions.push ({
                        version: beginRecord.get('version'),
                        first: beginRecord.getId(),
                        last: lastRecord.getId(),
                        cls: beginRecord.get('additionalCls')
                    });
                }
                currentVersion = v;
                beginRecord = record;
            }
            
            lastRecord = record;
        });
        
        versions.push ({
            version: beginRecord.get('version'),
            first: beginRecord.getId(),
            last: lastRecord.getId(),
            cls: beginRecord.get('additionalCls')
        });
        
        this._timeline.getView().getEl().down('.versions-container').update('');
        
        var html = this._versionTpl.apply(versions);
        this._timeline.getView().getEl().down('.versions-container').update(html);
    },
    
    /**
     * @private
     * Positions the versions in right place
     */
    _positionVersions: function (force)
    {
        // 3 - Position versions in right place
        var vEl = this._timeline.getView().getEl().down('.versions-container').down('.version');
        var scrollTop = this._timeline.getView().getEl().getScrollTop();
        
        while (vEl != null)
        {
            if (!vEl.alreadySet || force)
            {
                var firstId = vEl.getAttribute("data-record-first");
                var firstRecord = this._timeline.getStore().getById(firstId);
                var firstRow = this._timeline.getView().getRow(firstRecord);
                
                if (firstRow) // firstRow may not exists since the render can be delayed when there are too many elements
                {
                    var lastId = vEl.getAttribute("data-record-last");
                    var lastRecord = this._timeline.getStore().getById(lastId);
                    var lastRow = this._timeline.getView().getRow(lastRecord);
                    
                    var top1 = Ext.get(firstRow).down('.timeline-item').getOffsetsTo(this._timeline.getView().getEl())[1];
                    var top2 = Ext.get(lastRow).getOffsetsTo(this._timeline.getView().getEl())[1] + Ext.get(lastRow).getHeight() - 5;
                    
                    vEl.show();
                    vEl.removeCls('rotate'); // remove rotate transformation before calculating
                    
                    vEl.setTop(scrollTop + top1 + (top2 - top1 - vEl.getHeight())/2);
                    vEl.setRight(25 - vEl.getWidth()/2);
                    
                    vEl.addCls('rotate');
                    vEl.alreadySet = true;
                }
                else
                {
                    vEl.hide();
                }
            }
            vEl = vEl.next();
        }
    },
    
    /**
     * @private
     * Set the css classes for headers
     */
    _setGroupHeaderCls: function ()
    {
        var tableEl = this._timeline.getView().getEl().down('table').next(); // ignore first header group
        while (tableEl != null)
        {
            var hdEl = tableEl.down('.x-group-hd-container');
            if (hdEl != null)
            {
                var prevTableEl = tableEl.prev();
                
                if (prevTableEl.down('.timeline-item.first') != null)
                {
                    // It is not the same version, cut the line of versions
                    hdEl.addCls('hd-blank');
                }
                else
                {
                    var rowEl = tableEl.down('.x-grid-row');
                    var cls = rowEl.getAttribute('class');
                    
                    if (cls.indexOf('row-live') != -1)
                    {
                        hdEl.addCls('hd-live');
                    }
                    else if (cls.indexOf('row-valid') != -1)
                    {
                        hdEl.addCls('hd-valid');
                    }
                }
                
            }
            
            tableEl = tableEl.next();
        }
    },
    
    /**
     * @private
     * Listener after the layout of the timeline
     */
    _onAfterLayout: function ()
    {
        this._positionVersions(true);
        this._setGroupHeaderCls();
    },
    
    /**
     * @private
     * Listener after the scroll of the timeline
     */
    _onScroll: function ()
    {
        // Some versions may not have been positioned yet
        this._positionVersions();
    },
    
    /**
     * Open a content revision
     * @param versionName The version name of old revision
     * @param contentVersion The content version
     */
    openRevision: function (versionName, contentVersion)
    {
        Ametys.tool.ToolsManager.openTool("uitool-old-content", {id: this._contentId, versionName: versionName, contentVersion: contentVersion});
    },
    
    setNoSelectionMatchState: function (message)
    {
        this.callParent(arguments);
        
        var panel = this.getContentPanel().items.get(0);
        panel.update(message);
        this.getContentPanel().getLayout().setActiveItem(0);
        
        this._contentId = null;
        this._workflow = [];
    },
    
    /**
     * Listener on {@link Ametys.message.Message#WORKFLOW_CHANGED} message. If the current
     * content is concerned, the tool will be out-of-date.
     * 
     * @param {Ametys.message.Message} message The workflow changed message.
     * @protected
     */
    _onWorkflowChanged: function (message)
    {
        if (this.getTargetsInCurrentSelectionTargets(message).length > 0)
        {
            this.showOutOfDate();
        }
    },
    
    /**
     * Listener on {@link Ametys.message.Message#DELETED} message. If the current content is concerned, the tool will be set in no selection mode.
     * @param {Ametys.message.Message}  message The deleted message.
     * @protected
     */
    _onDeleted: function (message)
    {
        if (this.getTargetsInCurrentSelectionTargets(message).length > 0)
        {
            this.setNoSelectionMatchState();
        }
    },
    
    _getMatchingSelectionTargets: function(message)
    {
        var targets = this.callParent(arguments);
        var trueTargets = []
        
        // Let's check if the content is WorkflowAware
        for (var i = 0; i < targets.length; i++)
        {
            var target = targets[i];
            if (target.getParameters()['workflowName'])
            {
                trueTargets.push(target);
            }
        }
        
        return trueTargets;
    }
    
});