/*
 *  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 tool displays information about the selected content type
 */
Ext.define('Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool',  {
    extend: 'Ametys.tool.Tool',
    
    statics: {
        /**
         * Get the icon css class for metadata
         * @param {Object} data The medatata attributes
         * @return {String} the icon css class
         */
        getMetatadaIconCls: function(data)
        {
            if (data.enumerated)
            {
                return 'ametysicon-drop-down-list';
            }
            else
            {
                var iconCls = 'ametysicon-question-mark1';
                switch(data.type)
                {
                    case 'string':
                        iconCls = 'ametysicon-text';
                        break;
                    case 'date':
                        iconCls = 'ametysicon-calendar146';
                        break;
                    case 'datetime':
                        iconCls = 'ametysicon-datetime';
                        break;
                    case 'long':
                    case 'double':
                        iconCls = 'ametysicon-number-one';
                        break;
                    case 'geocode':
                        iconCls = 'ametysicon-placeholder19';
                        break;
                    case 'content':
                        if (data.linkedContentType && data.linkedContentType.iconGlyph)
                        {
                            iconCls = data.linkedContentType.iconGlyph;
                        }
                        else
                        {
                            iconCls = 'ametysicon-document209';
                        }
                        break;
                    case 'boolean':
                        iconCls = 'ametysicon-check51';
                        break;
                    case 'rich-text':
                        iconCls = 'ametysicon-alignment';
                        break;
                    case 'binary':
                    case 'file':
                        iconCls = 'ametysicon-text70';
                        break;
                    case 'user':
                        iconCls = 'ametysicon-black302';
                        break;
                    case 'reference':
                        iconCls = 'ametysicon-file98';
                        break;
                    case 'multilingual-string':
                        iconCls = 'ametysicon-translation';
                        break;
                    case 'repeater':
                         iconCls = 'ametysicon-multiple-windows';
                        break;
                    case 'composite':
                        iconCls = 'ametysicon-window';
                        break;
                    default:
                        break;
                    
                }
                return iconCls;
            }
        },
        
        /**
         * If the value is multilingual, will the current language one
         * @param {Object} value Multilingual label. Is a map with a boolean 'isMultilingual' and 'values' that can be a string or a map(language, localizedValue) 
         * @return {String} The localized label
         */
        getTranslatedValue: function(value)
        {
            if (value.values)
            {
                if (value.isMultilingual)
                {
                    var language = Ametys.cms.language.LanguageDAO.getCurrentLanguage();
                    return value.values[language];
                }
                else
                {
                    return value.values;
                }
            }
            
            return value;
        }
    },

    /**
     * @private
     * @property {Ext.XTemplate} __generalInfosTpl Template to display general informations
     */
    _generalInfosTpl: Ext.create(
        'Ext.XTemplate',
        '<div class="general-infos">',
            '<ul class="ctype-tags">',
                '<li class="{[this.getTagClass(values.private)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_PRIVATE}}</li>',
                '<li class="{[this.getTagClass(values.abstract)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_ABSTRACT}}</li>',
                '<li class="{[this.getTagClass(values.referencetable)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REFERENCE_TABLE}}</li>',
                '<li class="{[this.getTagClass(values.simple)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_SIMPLE}}</li>',
                '<li class="{[this.getTagClass(values.mixin)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_MIXIN}}</li>',
                '<li class="{[this.getTagClass(values.multilingual)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_MULTILINGUAL}}</li>',
             '</ul>',
            '<div class="attribute-intro">',
                '<tpl if="iconGlyph || largeIcon">',
                    '<p class="ctype-icon<tpl if="iconGlyph"> {iconGlyph}<tpl if="iconDecorator"> {iconDecorator}</tpl></tpl>">',
                        '<tpl if="!iconGlyph">',
                            '<img style="background-image:url({[Ametys.CONTEXT_PATH]}{largeIcon});" />',
                        '</tpl>',
                    '</p>',
                '</tpl>',
                '<h1>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.label)]}</h1>',
                '<tpl if="!Ext.Object.isEmpty(category) && !category.isNew"><h2>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.category)]}</h2></tpl>',
                '<tpl if="!Ext.Object.isEmpty(category) && category.isNew && !Ext.Object.isEmpty(newCategory)"><h2>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.newCategory)]}</h2></tpl>',
                '<tpl if="!Ext.Object.isEmpty(description)"><p>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.description)]}</p></tpl>',
                '<table class="ctype-properties">',
                    // Id
                    '<tr>',
                        '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_ID_LABEL}}</td>',
                        '<td>{pluginName}/{id}</td>',
                    '</tr>',
                    // Default title
                    '<tpl if="!Ext.Object.isEmpty(defaultTitle)">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_DEFAULT_TITLE_LABEL}}</td>',
                            '<td>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.defaultTitle)]}</td>',
                        '</tr>',
                    '</tpl>',
                    // Right
                    '<tpl if="!Ext.Object.isEmpty(right)">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_RIGHT_LABEL}}</td>',
                            '<td>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.right)]}</td>',
                        '</tr>',
                    '</tpl>',
                    // Super types
                    '<tpl if="superTypes.length &gt; 0">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_SUPER_TYPES_LABEL}}</td>',
                            '<td>',
                                '<tpl for="superTypes" between=",&nbsp;">',
                                   '<a href="javascript:Ametys.plugins.contenttypeseditor.ContentTypesActions.openById(\'{id}\')">{label}</a>',
                                '</tpl>',
                            '</td>',
                        '</tr>',
                    '</tpl>',
                    // Parent ref
                    '<tpl if="parentRef">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_PARENT_REF_LABEL}}</td>',
                            '<td>',
                                '{parentRef}',
                            '</td>',
                        '</tr>',
                    '</tpl>',
                '</table>',
            '</div>',
        '</div>',
        {
            getTagClass: function(value){
                return 'ctype-tag' + (value ? ' toggled' : ' hidden');
            }
        }),
        
     /**
     * @private
     * @property {Ext.XTemplate} _metadataDetailsTpl Template to display metadata details
     */
    _metadataDetailsTpl: Ext.create(
        'Ext.XTemplate',
        '<div class="attribute-details">',
            '<ul class="metadata-tags">',
                '<li class="{[this.getTagClass(values.mandatory)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_MANDATORY_LABEL}}</li>',
                '<li class="{[this.getTagClass(values.multiple)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_MULTIPLE_LABEL}}</li>',
                '<li class="{[this.getTagClass(values.enumerated)]}">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_ENUMERATION_LABEL}}</li>',
             '</ul>',
            '<div class="attribute-intro">',
                '<span class="metadata-icon {iconCls}"></span>',
                '<tpl if="!Ext.Object.isEmpty(label)"><h1>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.label)]}</h1></tpl>',
                '<tpl if="!Ext.Object.isEmpty(description)">{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.description)]}</tpl>',
                '<table class="metadata-properties">',
                    // Name
                    '<tr>',
                        '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_NAME_LABEL}}</td>',
                        '<td>{name}</td>',
                    '</tr>',
					// Path
                    '<tr>',
                    	'<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_PATH_LABEL}}</td>',
                    	'<td>{path}</td>',
                    '</tr>',
                    // Property's references
                    '<tpl if="references && references.length &gt; 0">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_PROPERTY_REFERENCES_LABEL}}</td>',
                            '<td>',
                                '<ul class="ctype-property-references">',
                                    '<tpl for="references">',
                                        '<li class="ctype-property-reference">{.}</li>',
                                    '</tpl>',
                                '</ul>',
                            '</td>',
                        '</tr>',
                    '</tpl>',
                    // Property's class
                    '<tpl if="class">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_PROPERTY_CLASS}}</td>',
                            '<td>{class}</td>',
                        '</tr>',
                    '</tpl>',
                    // Defined by
                    '<tpl if="referenceContentTypeId && referenceContentTypeLabel">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_CONTENT_TYPE_REF_LABEL}}</td>',
                            '<tpl if="referenceContentTypeId == \'system-property\' || contentTypeId == referenceContentTypeId">',
                                '<td>{referenceContentTypeLabel}</td>',
                            '<tpl else>',
                                '<td><a href="javascript:Ametys.plugins.contenttypeseditor.ContentTypesActions.openById(\'{referenceContentTypeId}\')">{referenceContentTypeLabel}</a></td>',
                            '</tpl>',
                        '</tr>',
                    '</tpl>',
                    // Type
                    '<tr>',
                        '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_TYPE_LABEL}}</td>',
                        '<tpl if="linkedContentType">',
                            '<td><a href="javascript:Ametys.plugins.contenttypeseditor.ContentTypesActions.openById(\'{linkedContentType.id}\')">{linkedContentType.label}</a></td>',
                        '<tpl else>',
                            '<td>{type}</td>',
                        '</tpl>',
                    '</tr>',
                    // Default value
                    '<tpl if="defaultValue">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_DEFAULT_VALUE_LABEL}}</td>',
                            '<td>{defaultValue}</td>',
                        '</tr>',
                    '</tpl>',
                    // Insert relation
                    '<tpl if="invertRelationPath">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_INVERT_RELATION_PATH_LABEL}}</td>',
                            '<td>{invertRelationPath} <tpl if="forceInvert">({{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_FORCE_INVERT_LABEL}})</tpl></td>',
                        '</tr>',
                    '</tpl>',
                    // Repeater,
                    '<tpl if="initializeSize"><tr><td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REPEATER_INITIALIZE_SIZE_LABEL}}</td><td>{initializeSize}</td></tr></tpl>',
                    '<tpl if="minSize"><tr><td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REPEATER_MIN_SIZE_LABEL}}</td><td>{minSize}</td></tr></tpl>',
                    '<tpl if="maxSize && maxSize !== -1"><tr><td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REPEATER_MAX_SIZE_LABEL}}</td><td>{maxSize}</td></tr></tpl>',
                    '<tpl if="headerLabel"><tr><td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REPEATER_HEADER_LABEL_LABEL}}</td><td>{headerLabel}</td></tr></tpl>',
                    '<tpl if="!Ext.Object.isEmpty(addLabel)"><tr><td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REPEATER_ADD_LABEL_LABEL}}</td><td>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.addLabel)]}</td></tr></tpl>',
                    '<tpl if="!Ext.Object.isEmpty(deleteLabel)"><tr><td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_REPEATER_DEL_LABEL_LABEL}}</td><td>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.deleteLabel)]}</td></tr></tpl>',
                    // Semantic annotation
                    '<tpl if="semanticAnnotations && semanticAnnotations.length &gt; 0">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_RICH_TEXT_SEMANTIC_ANNOTATIONS_LABEL}}</td>',
                            '<td class="colhead">',
                                '<dl class="ctype-semantic-annotations">',
                                    '<tpl foreach="semanticAnnotations">',
                                        '<dt class="ctype-semantic-annotation-label">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_RICH_TEXT_SEMANTIC_ANNOTATION_ID_LABEL}}</dt>',
                                        '<dd class="ctype-semantic-annotation-value">{id}</dd>',
                                        '<dt class="ctype-semantic-annotation-label">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_RICH_TEXT_SEMANTIC_ANNOTATION_LABEL_LABEL}}</dt>',
                                        '<dd class="ctype-semantic-annotation-value">{label}</dd>',
                                        '<dt class="ctype-semantic-annotation-label">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_RICH_TEXT_SEMANTIC_ANNOTATION_DESC_LABEL}}</dt>',
                                        '<dd class="ctype-semantic-annotation-value">{description}</dd>',
                                    '</tpl>',
                                '</dl>',
                            '</td>',
                        '</tr>',
                    '</tpl>',
                    // Widget
                    '<tpl if="widget">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_WIDGET_LABEL}}</td>',
                            '<td>{widget}</td>',
                        '</tr>',  
                    '</tpl>',
                    '<tpl if="!Ext.Object.isEmpty(widgetParams)">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_WIDGET_PARAMS_LABEL}}</td>',
                            '<td>',
                                '<ul>',
                                    '<tpl foreach="widgetParams">',
                                        '<li>',
                                            '{label} : {[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.value)]}',
                                        '</li>',
                                    '</tpl>',
                                '</ul>',
                            '</td>',
                        '</tr>',  
                    '</tpl>',
                    // Validator
                    '<tpl if="defaultValidator">',
                        '<tpl if="!Ext.Object.isEmpty(defaultValidator)">',
                            '<tr>',
                                '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_LABEL}}</td>',
                                '<td>',
                                    '<ul>',
                                        '<tpl if="defaultValidator.mandatory">',
                                            '<li>',
                                               "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_MANDATORY_LABEL}}",
                                            '</li>',
                                        '</tpl>',
                                        '<tpl if="defaultValidator.regexp">',
                                            '<li>',
                                               '{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_REGEXP_LABEL}} : {defaultValidator.regexp}',
                                            '</li>',
                                        '</tpl>',
                                        '<tpl if="!Ext.Object.isEmpty(defaultValidator.invalidText)">',
                                            '<tpl if="Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.defaultValidator.invalidText)">',
                                                '<li>',
                                                   '{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_INVALIDTEXT_LABEL}} : {[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.defaultValidator.invalidText)]}',
                                                '</li>',
                                            '</tpl>',
                                        '</tpl>',
                                    '</ul>',
                                '</td>',
                            '</tr>',
                        '</tpl>',
                    '<tpl elseif="customValidatorClass">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_LABEL}}</td>',
                            '<td>',
                                '{customValidatorClass}',
                            '</td>',
                        '</tr>',
                        '<tpl if="customValidatorConfiguration">',
                            '<tr>',
                                '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_VALIDATOR_CONFIGURATION_LABEL}}</td>',
                                '<td>',
                                    '{customValidatorConfiguration}',
                                '</td>',
                            '</tr>',
                        '</tpl>',
                    '</tpl>',
                    // Enumeration
                    '<tpl if="defaultEnumerator">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_ENUMERATOR_LABEL}}</td>',
                            '<td>',
                                '<ul>',
                                    '<tpl foreach="defaultEnumerator">',
                                        '<li>',
                                            '{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.value)]}',
                                        '</li>',
                                    '</tpl>',
                                '</ul>',
                            '</td>',
                        '</tr>',
                    '<tpl elseif="customEnumeratorClass">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_ENUMERATOR_LABEL}}</td>',
                            '<td>',
                                '{customEnumeratorClass}',
                            '</td>',
                        '</tr>',
                        '<tpl if="customEnumeratorConfiguration">',
                            '<tr>',
                                '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_ENUMERATOR_CONFIGURATION_LABEL}}</td>',
                                '<td>',
                                    '{customEnumeratorConfiguration}',
                                '</td>',
                            '</tr>',
                        '</tpl>',
                    '</tpl>',
                '</table>',
            '</div>',
        '</div>',
        {
            getTagClass: function(value){
                return 'metadata-tag' + (value ? ' toggled' : '');
            }
        }
    ),
        
    /**
     * @private
     * @property {Ext.XTemplate} _metadataSetDetailsTpl Template to display metadata set details
     */
    _metadataSetDetailsTpl: Ext.create(
        'Ext.XTemplate',
        '<div class="attribute-details">',
            '<div class="attribute-intro">',
                '<tpl if="iconGlyph || largeIcon">',
                    '<p class="metadata-icon<tpl if="iconGlyph"> {iconGlyph}<tpl if="iconDecorator"> {iconDecorator}</tpl></tpl>">',
                        '<tpl if="!iconGlyph">',
                            '<img style="background-image:url({[Ametys.CONTEXT_PATH]}{largeIcon});" />',
                        '</tpl>',
                    '</p>',
                '</tpl>',
                '<tpl if="!Ext.Object.isEmpty(label)">',
                    '<h1>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.label)]}</h1>',
                '<tpl elseif="!Ext.Object.isEmpty(name)">',
                    '<h1>{name}</h1>',
                '</tpl>',
                '<tpl if="!Ext.Object.isEmpty(description)">{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.description)]}</tpl>',
                '<table class="metadataset-properties">',
                    // Name
                    '<tr>',
                        '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_SET_NAME}}</td>',
                        '<td>{name}</td>',
                    '</tr>',
                    // Type
                    '<tr>',
                        '<td colspan="2">',
                            '<tpl if="isEdition">',
                                '<span class="view-icon ametysicon-edit45"></span>',
                                "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_SET_TYPE_EDITION_VALUE}}",
                            '<tpl else>',
                                '<span class="view-icon ametysicon-visibility1"/></span>',
                                "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_SET_TYPE_VIEW_VALUE}}",
                            '</tpl>',
                        '</td>',
                    '</tr>',
                '</table>',
            '</div>',
        '</div>'
    ),
        
    /**
     * @private
     * @property {Ext.XTemplate} _fieldsetDetailsTpl Template to display fieldset details
     */
    _fieldsetDetailsTpl: Ext.create(
        'Ext.XTemplate',
        '<div class="attribute-details">',
            '<div class="attribute-intro">',
                '<span class="metadata-icon {iconCls}"></span>',
                '<tpl if="!Ext.Object.isEmpty(label)">',
                    '<h1>{[Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(values.label)]}</h1>',
                '<tpl elseif="!Ext.Object.isEmpty(name)">',
                    '<h1>{name}</h1>',
                '</tpl>',
                '<table class="fieldset-properties">',
                    // Name
                    '<tpl if="!Ext.Object.isEmpty(name)">',
                        '<tr>',
                            '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_FIELDSET_NAME_LABEL}}</td>',
                            '<td>{name}</td>',
                        '</tr>',
                    '</tpl>',
                    // Role
                    '<tr>',
                        '<td class="colhead">{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_FIELDSET_ROLE_LABEL}}</td>',
                        '<td>{role}</td>',
                    '</tr>',
                '</table>',
            '</div>',
        '</div>'
    ),

    /**
     * @private
     * @property {String} _id The identifier of content type.
     */
    createPanel: function()
    {
        this._generalInfosComponent = Ext.create("Ext.Component", {
            html: ''
        });
        
        var treeStore = Ext.create('Ext.data.TreeStore', {
            model: 'Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.NodeEntry',
            root: {
                text: 'root'
            }
        });
        
        // Fake store for creation only, see #_updateTreeComponent for the real store
        this._treeComponent = Ext.create("Ext.tree.Panel", {
            scrollable: true,
            animate: false,
            split: {},
            flex: 1,
            cls : 'contenttype-attributes-tree',
            store: treeStore,
            listeners: [
                {'selectionchange': this.sendCurrentSelection, scope: this},
                {'selectionchange': this._displayAttributeDetails, scope: this},
                {'select': this._selectTreePanel, scope: this}
            ]
        });
        
        this._attributeDetailsComponent = Ext.create("Ext.Component", {
            flex: 2,
            html: ''
        });
        
        this._changedContentTypeCmp = Ext.create("Ext.Component", {
            style: {
                textAlign: 'center'
            },
            ui: 'tool-hintmessage',
            html: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_TAKE_INTO_ACCOUNT_CHANGES}}",
            hidden: false
        });
        this._changedContentTypeCmp.setVisible(false);
        
        this._noSelectionCmp = Ext.create("Ext.Component", {
            style: {
                textAlign: 'center'
            },
            ui: 'tool-hintmessage',
            html: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_SELECT_NODE}}",
            hidden: false
        });
        
        var attributesContainer = Ext.create("Ext.panel.Panel", {
            layout: {
                type: 'hbox',
                align: 'stretch'
            },
            flex: 1,
            border: false,
            items: [
                this._treeComponent,
                {
                    xtype: 'panel',
                    border: true,
                    scrollable: true,
                    flex: 2,
                    items: [this._noSelectionCmp, this._attributeDetailsComponent]
                }
            ]
        });
        
        return Ext.create("Ext.Container", {
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            cls: 'uitool-contenttypeseditor',
            items: [this._changedContentTypeCmp, this._generalInfosComponent, attributesContainer]
        });
    },
    
    /**
     * Select the record in the tree component
     * @param {Ext.selection.RowModel} rowModel The row model
     * @param {Ext.data.Model} record The newly selected record
     * @param {Number} index The row index selected
     */
    _selectTreePanel: function(rowModel, record, index)
    {
        this._treeComponent.ensureVisible(record.id);
    },
    
    /**
     * @private
     * Display metadata detail according to the metadata path
     * @param {String} path The metadata path
     */
    displayMetadataDetailByPath: function(path)
    {
        var node = this._treeComponent.getStore().findNode('path', path);
        if (node)
        {
            this._treeComponent.getSelectionModel().select(node);
            this._treeComponent.ensureVisible(node.getPath());
        }
    },
    
    /**
     * @private
     * Display metadataset detail according to the metadataset index
     * @param {Number[]} indexTabView The index of the metadataset to select
     */
    _displayMetadataSetByIndex: function(indexTabView)
    {
        var node;
        var metadataSetCount = 0;
        var itemsStore = this._treeComponent.getStore().data.items;
        
        for (var i = 0; i < itemsStore.length ; i++)
        {
            if (indexTabView.length == 0)
            {
                if (itemsStore[i].data.depth == 1 && itemsStore[i].data.index == 1)
                {
                    node = this._treeComponent.getStore().findNode('id', itemsStore[i].data.id);
                    break;
                }
            }
            else if (itemsStore[i].data && itemsStore[i].data.dataType == 'view')
            {
                if (metadataSetCount == indexTabView[0])
                {
                    if (indexTabView.length == 1)
                    {
                        node = this._treeComponent.getStore().findNode('id', itemsStore[i].data.id);
                        break;
                    }
                    else
                    {
                        if (itemsStore[i].data.children && itemsStore[i].data.children.length > 0)
                        {
                            node = this._displayMetadataSetByChildrenIndex(itemsStore[i].data.children, indexTabView, 1);
                            break;
                        }
                    }
                }
                metadataSetCount = metadataSetCount + 1;
            }
        }
        if (node)
        {
            this._treeComponent.getSelectionModel().select(node);
        }
    },

    /**
     * @private
     * Display metadataset ref detail according to the metadataset index
     * @param {Ext.data.NodeInterface} childrenNode The tree node
     * @param {Number[]} indexTabView The index of the metadataset to select
     * @param {Number} index The index in the indexTabView
     */
    _displayMetadataSetByChildrenIndex: function(childrenNode, indexTabView, index)
    {
        var node;
        for (var i = 0; i < childrenNode.length; i++)
        {
            if (indexTabView[index] == i)
            {
                if (index < indexTabView.length-1)
                {
                    if (childrenNode[i].children && childrenNode[i].children.length > 0)
                    {
                        node = this._displayMetadataSetByChildrenIndex(childrenNode[i].children, indexTabView, index +1);
                    }
                }
                else
                {
                    node = this._treeComponent.getStore().findNode('id', childrenNode[i].id);
                    break;
                }
            }
        }
        return node;
    },
    
    getMBSelectionInteraction: function() 
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
    
    sendCurrentSelection: function()
    {
        var selections = this._treeComponent.getSelectionModel().getSelection();
        var subtargets;
        
        if (selections.length > 0)
        {
            var dataSelection = selections[0].data;
            if ((dataSelection.depth == 1 && dataSelection.index == 0) || dataSelection.dataType == 'model_item')
            {
                subtargets = {
                    id: Ametys.message.MessageTarget.METADATA_CONTENT_TYPE,
                    parameters: {}
                };
                
                if (dataSelection.isParentMetadata)
                {
                    subtargets.parameters.type = 'isParentMetadata';
                }
                else
                {
                    subtargets.parameters.type = dataSelection.type || 'metadata';                    
                }
            }
            else if ((dataSelection.depth == 1 && dataSelection.index == 1) || dataSelection.dataType == 'view' || dataSelection.dataType == 'model_item_ref' || dataSelection.dataType == 'fieldset')
            {
                var type = dataSelection.dataType;
                if (dataSelection.isParentMetadataSet)
                {
                    type = 'isParentMetadataSet';
                }
                else if (dataSelection.dataType == 'model_item_ref' && dataSelection.isRepeaterOrComposite)
                {
                    type = 'metadata_ref_children';
                }
                
                subtargets = {
                    id: Ametys.message.MessageTarget.METADATA_SET_CONTENT_TYPE,
                    parameters: {
                        type: type || 'view'
                    }
                };
            }
        }
        
        var targets = [];
        targets.push({
            id: Ametys.message.MessageTarget.CONTENT_TYPE,
            parameters: {
                id: this._contentTypeId,
                isNew: this._mode == 'add' || this._mode == 'save',
                editor: true
            },
            subtargets: subtargets
        });
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.SELECTION_CHANGED,
            targets: targets
        });
    },
    
    getType: function()
    {
        return Ametys.tool.Tool.TYPE_CONTENT_TYPE;
    },
    
    setParams: function(params)
    {
        this.callParent(arguments);
        this._contentTypeId = params['id'] || this._contentTypeId;
        this._mode = params['mode'] || this._mode;
        this._newContentTypeInfos = params['contentTypeInfos'];
        this._selectMetadata = params['selectMetadata'];
        this._selectMetadataSet = params['selectMetadataSet'];
        this._hideInheritedMetadata = params['hideInheritedMetadata'] === true || params['hideInheritedMetadata'] == 'true';
        this.refresh();
    },
    
    refresh: function()
    {
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.contenttypeseditor.edition.ContentTypeStateComponent",
            methodName: "getStateContentType",
            parameters: [this._contentTypeId],
            callback: {
                handler: this._refreshCb,
                scope: this
            }
        });
    },
    
    /**
     * @private
     * Callback to #refresh method
     * @param {String} stateContentType The current content type state "edit", "save" or "restart"
     */
    _refreshCb: function(stateContentType)
    {
        if (stateContentType === 'edit')
        {
            this.setDirty(true);
            this._changedContentTypeCmp.setVisible(false);
            if (this._mode === 'add')
            {
                this.showRefreshing();
                Ametys.data.ServerComm.callMethod({
                    role: "org.ametys.plugins.contenttypeseditor.edition.EditContentTypeInformationHelper",
                    methodName: "getContentTypeInfos",
                    parameters: [this._newContentTypeInfos.superTypes],
                    callback: {
                        handler: this._setContentTypeInfos,
                        scope: this
                    }
                });
            }
            if (this._mode === 'edit')
            {
                this._setContentTypeInfos();
            }
        }
        else if (stateContentType === 'save')
        {
            this.setDirty(false);
            this._changedContentTypeCmp.setVisible(true);
            if (this._newContentTypeInfos)
            {
                this._setContentTypeInfos();
            }
            else if (!this._contentTypeInfos)
            {
                this.showRefreshing();
                this.setDirty(false);
                this.serverCall('getContentTypeInfos', [this._contentTypeId, this._hideInheritedMetadata], Ext.bind(this._finalizeParams, this));
                this._changedContentTypeCmp.setVisible(true);
            }
        }
        else if (stateContentType === 'restart')
        {
            this.showRefreshing();
            this.setDirty(false);
            this.serverCall('getContentTypeInfos', [this._contentTypeId, this._hideInheritedMetadata], Ext.bind(this._finalizeParams, this));
            this._changedContentTypeCmp.setVisible(false);
        }  
    },
    
    /**
     * @private
     * Set the contenttype informations
     * @param {Object} serverContentTypeInfo The server side informations for the current content type
     */
    _setContentTypeInfos: function(serverContentTypeInfo)
    {
        if (serverContentTypeInfo)
        {
            this._newContentTypeInfos.attributes = serverContentTypeInfo.attributes;
            this._newContentTypeInfos.views = serverContentTypeInfo.views;
        }
        this._finalizeParams(this._newContentTypeInfos); 
    },
    
    /**
     * @private
     * Finalize refreshment of tool
     * @param {Object} contentTypeInfos All informations about the content type
     */
    _finalizeParams: function (contentTypeInfos)
    {
        if (contentTypeInfos)
        {
            this._contentTypeInfos = contentTypeInfos;         
            this._updateTitle();
            this._updateGeneralInfos();
            this._updateTreeComponent();
            this.showRefreshed();
            if (this._selectMetadata)
            {
                this.displayMetadataDetailByPath(this._selectMetadata);
                this._displayAttributeDetails();
                this._selectMetadata = "";
            }
            else if (this._selectMetadataSet)
            {
                this._displayMetadataSetByIndex(this._selectMetadataSet);
                this._selectMetadataSet = "";
            }
        }
        else
        {
            // Content type not found
            Ametys.log.ErrorDialog.display({
                title: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_CONTENTTYPE_NOT_FOUND}}",
                text: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_CONTENTTYPE_NOT_FOUND_ERROR}}",
                details: "id : " + this._contentTypeId,
                category: this.self.getName()
            });
             
            this.close();
        }
    },
    
    /**
     * @private
     * Update the title, icons and other infos
     */
    _updateTitle: function ()
    {
        this.setGlyphIcon(this._contentTypeInfos.iconGlyph);
        this.setIconDecorator(this._contentTypeInfos.iconDecorator);
        this.setLargeIcon(this._contentTypeInfos.largeIcon);
        this.setMediumIcon(this._contentTypeInfos.mediumIcon);
        this.setSmallIcon(this._contentTypeInfos.smallIcon);
        this.setTitle(Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(this._contentTypeInfos.label));
        
        var tooltip = Ametys.plugins.cms.contenttype.ContentTypeTree.CONTENT_TYPE_TOOLTIP_TPL.applyTemplate ({
            description: this._contentTypeInfos.description ? Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(this._contentTypeInfos.description) : '', 
            'isPrivate': this._contentTypeInfos.isPrivate, 
            'isReferenceTable': this._contentTypeInfos.isReferenceTable, 
            'isAbstract': this._contentTypeInfos.isAbstract,
            'isMixin': false,
            'isSimple': false,
            'isMultilingual': false
        });
        this.setDescription(tooltip);
    },
    
    /**
     * @private
     * Update the general information of the tool
     */
    _updateGeneralInfos: function ()
    {
        var infos = Ext.applyIf(this._contentTypeInfos, { 
            right: null, 
            isMultilingual: null,
            isSimple: null,
            isMixin: null
        });
        
        var html = this._generalInfosTpl.applyTemplate(infos);
        this._generalInfosComponent.update(html);
    },
    
    /**
     * @private
     * Update the content type tree
     */
    _updateTreeComponent: function ()
    {
        // The store is created for each update because otherwise child nodes are not loaded when the setRootNode method is used a second time
        var treeStore = Ext.create('Ext.data.TreeStore', {
            model: 'Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.NodeEntry',
            sorters: [{
				sorterFn: function(n1, n2)
				{
					if (n1.get('dataType') == 'model_item' && n2.get('dataType') == 'model_item')
					{
						return n1.data.text.localeCompare(n2.data.text)				
					}
				}
			}],
            root: {
	            expanded: true,
	            text: Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getTranslatedValue(this._contentTypeInfos.label),
	            children: [
	                { label: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_LABEL}}", expanded: true, children: this._contentTypeInfos.attributes },
	                { label: "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_SETS_LABEL}}", expanded: true, children: this._contentTypeInfos.views }
	            ]
	        }
        });
        this._treeComponent.setStore(treeStore);
    },
	
    /**
     * Display the detail view of a selected node in the tree
     * @private
     */
    _displayAttributeDetails: function ()
    {
        var selection = this._treeComponent.getSelectionModel().getSelection();
        
        if (selection.length > 0 && !selection[0].isRoot() && selection[0].get('dataType'))
        {
            this._attributeDetailsComponent.setVisible(true);
            this._noSelectionCmp.setVisible(false);
            this._attributeDetailsComponent.update(this._getHTMLForAttributeDetails(selection[0].data));
        }
        else
        {
            this._attributeDetailsComponent.setVisible(false);
            this._noSelectionCmp.setVisible(true);
        }
    },
    
    /**
     * Get the HTML node for detail view
     * @param {Object} attribute The node data
     * @return {String} the HTML for detail view
     */
    _getHTMLForAttributeDetails: function(attribute)
    {
        switch (attribute.dataType)
        {
            case "model_item":
            case "model_item_ref":
                return this._metadataDetailsTpl.applyTemplate(Ext.applyIf(attribute, {semanticAnnotations: null, maxSize: null, addLabel: null, deleteLabel: null, widgetParams: null, description: null, referenceContentTypeId: null}));
            case "view":
                return this._metadataSetDetailsTpl.applyTemplate(attribute);
            case "fieldset":
                return this._fieldsetDetailsTpl.applyTemplate(attribute);
            default:
                return '';
        }
    },
    
    close: function (manual)
    {
        if (this.isDirty())
        {
            var me = this;
            Ametys.Msg.confirm("{{i18n PLUGINS_CONTENTTYPESEDITOR_CANCEL_MODIFICATION_CONFIRMATION_TITLE_CONTENT_TYPE_LABEL}}", 
                    "{{i18n PLUGINS_CONTENTTYPESEDITOR_CANCEL_MODIFICATION_CONFIRMATION_CONTENT_TYPE_LABEL}}", 
                    function (answer) {
                        if (answer == 'yes')
                        {
                            Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.superclass.close.call(me, [manual]);
                        }
                    },
                    this
            );
            return;
        }
        
        this.callParent (arguments);
    },
    
    onClose: function()
    {
        if (this._mode == 'add' || this._mode == 'edit')
        {
            Ametys.data.ServerComm.callMethod({
                role: "org.ametys.plugins.contenttypeseditor.edition.ContentTypeStateComponent",
                methodName: "removeContentTypeMarkedAsEdited",
                parameters: [this._contentTypeId]
            });
        }
    }
});

Ext.define('Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.NodeEntry', { 
    extend: 'Ext.data.Model',
    
    fields: [
         'dataType',
         'name',
         'label',
         'description',
         'iconSmall',
         'iconMedium',
         'iconLarge',
         'iconGlyph',
         'iconDecorator',
         'path',
         'edition',
         {
            name: 'text',
            depends: ['label', 'name', 'dataType', 'edition'],
            calculate: function (data)
            {
                if (data.dataType)
                {
                    if (data.dataType == 'view')
                    {
                        var type = data.isEdition ? "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_SETS_EDITION_LABEL}}" : "{{i18n PLUGINS_CONTENTTYPESEDITOR_EDITOR_TOOL_METADATA_SETS_VIEW_LABEL}}";          
                        
                        var label = data.name;
                        if (data.label && data.label.values)
                        {
                            var language = Ametys.cms.language.LanguageDAO.getCurrentLanguage();
                            if (data.label.isMultilingual)
                            {
                                label = data.label.values[language];
                            }
                            else
                            {
                                label = data.label.values;
                            }
                        }
                        
                        return  label + ' (' + type + ')';
                    }
                    else
                    {
                        var edition = data.edition ? " *" : "";
                        var label = data.name;
                        if (data.label && data.label.values)
                        {
                            var language = Ametys.cms.language.LanguageDAO.getCurrentLanguage();
                            if (data.label.isMultilingual)
                            {
                                label = data.label.values[language];
                            }
                            else
                            {
                                label = data.label.values;
                            }
                        }
                        return  label + edition;
                    }
                }
                else
                {
                    return data.label || data.name;
                }
            }
        },
        {
            name: 'iconCls',
            depends: ['dataType'],
            calculate: function (data)
            {
                if (data.dataType == 'fieldset')
                {
                    return 'ametysicon-menu';
                }
                
                if (data.dataType == 'model_item' || data.dataType == 'model_item_ref')
                {
                    return Ametys.plugins.contenttypeseditor.editor.ContentTypeEditorTool.getMetatadaIconCls(data);
                }
                
                return data.iconGlyph;
            }
        }
    ]
});