/*
 *  Copyright 2015 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 step of {@link Ametys.plugins.web.page.AddPageWizard} wizard allow to choose content type or service to add
 */
Ext.define("Ametys.plugins.web.page.AddPageWizard.PageContentCard", {
    
    extend: "Ametys.plugins.web.page.AddPageWizard.Card",
    
    name: "content",

    /** 
     * @private
     * @property {String} _lastExpandedPanel The name of the panel that was expanded the last time (between the content type one, and the service one)
     */
    _lastExpandedPanel: 'add-page-pagecontent-contenttype',

    constructor: function(config)
    {
        this.callParent(arguments);
        this._model = {};
    },
    
    createPanel: function ()
    {
        this._cardPanel = Ext.create('Ext.Container', {
            border: false,
            layout: {
                type: 'accordion',
                fill: true
            },
            scrollable: false,
            
            defaults: {
                cls: "a-radio-panel",
                ui: 'light',
                border: false,
                listeners: {
                    expand: this._onAfterExpand,
                    scope: this
                }
            },
            
            items: [
                  this._createContentTypesPanel4PageContentCard(),
                  this._createServicesPanel4PageContentCard()
            ]
        });
        
        return this._cardPanel;
    },
    
    apply: function (fullModel, callback)
    {
        if (fullModel["pagecontent-type"] == null)
        {
            callback (false);
        }
        else
        {
            if (fullModel["pagecontent-type"] == "contenttype")
            {
                if (!Ametys.plugins.web.page.AddPageWizard.getInitialConfig('show-card-content-properties')
                    || (fullModel["contenttype-view-names"] && fullModel["contenttype-view-names"].indexOf(Ametys.plugins.web.page.AddPageWizard.getInitialConfig('content-createViewName')) == -1))
                {
                    // Do not create content here if there is a card to do it
                    var initConfig = Ametys.plugins.web.page.AddPageWizard.getInitialConfig();
                    
                    var contentTitle = fullModel["default-content-title"] ? fullModel["default-content-title"] : (fullModel['title-long'] ? fullModel['title-long'] : fullModel['title']);
                    
                    var params = {
                        contentType: fullModel["contenttype"],
                        contentName: fullModel['title'] + " " + (fullModel["contenttype-label"] || ""),
                        contentTitle: contentTitle,
                        contentLanguage: fullModel["page-lang"],
                        initWorkflowActionId: initConfig.workflowInitActionId,
                        editWorkflowActionId: initConfig.workflowEditActionId,
                        workflowName: initConfig['workflow-workflowName'],
                        additionalWorkflowParameters: {
                            'org.ametys.web.workflow.CreateContentFunction$pageId': fullModel["page-id"],
                            'org.ametys.web.workflow.CreateContentFunction$zoneName': fullModel["zone"],
                            'org.ametys.web.repository.site.Site': Ametys.getAppParameter('siteName')
                        },
                        viewName: initConfig['content-createViewName'],
                        editFormValues: initConfig['content-editFormValues']
                    };
                    
                    for (var c in initConfig)
                    {
                        if (c.indexOf("workflow-") == 0)
                        {
                            params.additionalWorkflowParameters[c.substr("workflow-".length)] = initConfig[c];
                        }
                    }
                        
                    Ametys.cms.content.ContentDAO.createContent(
                        params,
                        Ext.bind(this._applyContentCB, this, [fullModel, callback], true),
                        this, // scope
                        true,
                        null, 
                        null, 
                        Ametys.plugins.web.page.AddPageWizard._box
                    );
                }
                else
                {
                    callback(true);
                }
            }
            else
            {
                Ametys.plugins.web.zone.ServiceActions.open ('new', {
                    pageId: fullModel["page-id"],
                    zoneName: fullModel["zone"],
                    serviceId: fullModel["service"]
                }, fullModel["service-action"]);
                
                callback (true);
            }
        }
    },
    
    /**
     * @private
     * Callback function after creating content
     * @param {Ametys.cms.content.Content} content The created content
     * @param {Object} fullModel The full model.
     * @param {Function} callback The callback function
     */
    _applyContentCB: function (content, fullModel, callback)
    {
        fullModel['content-id'] = content.getId();
        // Open content tool
        Ametys.plugins.web.page.AddPageWizard._contentId = content.getId();
        callback(true);
    },
    
    
    getUI: function ()
    {
        return this._cardPanel;
    },
    
    resetModel: function (callback)
    {
        this._model = {};
        
        this._model["pagecontent-type"] =  Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-pagecontent-type');
        this._model["contenttype"] = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-contenttype');
        this._model["default-content-title"] = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-content-title');
        this._model["contenttype-label"] = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-contenttype-label');
        this._model["service"] = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-service');
        this._model["service-action"] = "";
        
        var showContentCard = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('show-card-content');
        var showContentPropertiesCard = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('show-card-content-properties');
        if (!showContentCard && showContentPropertiesCard && this._model["contenttype"] && !this._model["service"])
        {
            // Just load the store to have selected content type information
            var cTypeView = this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']");
            cTypeView.getStore().removeAll();
            
            // Load available content types
            cTypeView.getStore().load({
                params: {'contentTypeIds': [this._model["contenttype"]], 'withRight': false},
                callback: Ext.bind(this._initValueFromRecords, this, [callback], 1)
            });
        }
        else
        {
            callback();
        }
    },
    
    /**
     * @private
     * Update the model with default content type record 
     * @param {Object[]} records content type information
     * @param {Function} callback called after loading the store
     */
    _initValueFromRecords: function(records, callback)
    {
       var selectedRecord = records[0];
       this._model["pagecontent-type"] = "contenttype";
       this._model["contenttype"] = selectedRecord ? selectedRecord.getId() : null;
       this._model["contenttype-label"] = selectedRecord ? selectedRecord.get('label') : "";
       this._model["contenttype-view-names"] = selectedRecord ? selectedRecord.get('viewNames') : [];
       
       if (this._model["contenttype-view-names"].indexOf(Ametys.plugins.web.page.AddPageWizard.getInitialConfig('content-createViewName')) == -1)
       {
            // The selected metadata set is not available for the selected content type, so disable the card content property
            Ametys.plugins.web.page.AddPageWizard.getInitialConfig()["show-card-content-properties"] = false;
       }
       
       callback();
    },
    
    updateModel: function ()
    {
        if (this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype']").collapsed == 'top')
        {
            var serviceView = this._cardPanel.down("*[itemId='add-page-pagecontent-service-view']");

            this._model["pagecontent-type"] = "service";
            
            var selectedRecord = serviceView.getSelectionModel().getSelection()[0];
            this._model["service"] = selectedRecord != null ? selectedRecord.getId() : null;
            this._model["service-action"] = selectedRecord ? selectedRecord.get("parametersAction") : "";
        }
        else
        {
            var cTypeView = this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']");
            
            this._model["pagecontent-type"] = "contenttype";
            
            var selectedRecord = cTypeView.getSelectionModel().getSelection()[0];
            this._model["contenttype"] = selectedRecord ? selectedRecord.getId() : null;
            this._model["contenttype-label"] = selectedRecord ? selectedRecord.get('label') : "";
            this._model["contenttype-view-names"] = selectedRecord ? selectedRecord.get('viewNames') : [];
        }
    },
    
    updateUI: function (callback)
    {
        var fullModel = Ametys.plugins.web.page.AddPageWizard.getModel();
        
        var cTypeView = this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']");
        var serviceView = this._cardPanel.down("*[itemId='add-page-pagecontent-service-view']");
        
        this._clearFilter('search-filter-contenttype-input');
        this._clearFilter('search-filter-service-input');
        
        if (this._displayingValuesForPageId == Ametys.plugins.web.page.AddPageWizard.getParentId() + "###" + fullModel["template"])
        {
            var contentType = fullModel["contenttype"]
                                || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-contenttype')
                                || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-selected-contenttype');
            
            var index = cTypeView.getStore().find('id', contentType);
            
            if (index != -1)
            {
                cTypeView.getSelectionModel().select(index);
            }
            else
            {
                cTypeView.getSelectionModel().select(0);
            }
            
            this._scrollMultiselectToSelection(cTypeView);
            
            var service = fullModel["service"]
                            || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-service')
                            || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-selected-service');
            
            index = serviceView.getStore().find('id', service);
            
            if (index != -1)
            {
                serviceView.getSelectionModel().select(index);
            }
            else
            {
                serviceView.getSelectionModel().select(0);
            }
            
            this._scrollMultiselectToSelection(serviceView);
            
            var pagecontentType = this._model["pagecontent-type"]
                                    || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-pagecontent-type')
                                    || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-selected-pagecontent-type');
            
            this._cardPanel.down("*[itemId='add-page-pagecontent-" + pagecontentType + "']").expand();
            
            this._initDefaultValues();
            
            this._cardPanel.down("*[itemId='add-page-pagecontent-" + pagecontentType + "-view']").focus();

            callback(true);
        }
        else
        {
            this._displayingValuesForPageId = Ametys.plugins.web.page.AddPageWizard.getParentId() + "###" + fullModel["template"];
            
            cTypeView.getStore().removeAll();
            serviceView.getStore().removeAll();
            
            // Load available content types
            cTypeView.getStore().load({
                params: {'parentId': Ametys.plugins.web.page.AddPageWizard.getParentId(), title: fullModel["title"], template: fullModel["template"], zone: fullModel["zone"]},
                callback: Ext.bind(this._contenttypeCB4updateUI, this, [callback], 1)
            });
            
            serviceView.getStore().load({
                params: {'parentId': Ametys.plugins.web.page.AddPageWizard.getParentId(), title: fullModel["title"], template: fullModel["template"], zone: fullModel["zone"]},
                callback: Ext.bind(this._serviceCB4updateUI, this, [callback], 1)
            });
        }
    },
    
    /**
     * @private
     * Update the model with current selection  
     */
    _initDefaultValues: function()
    {
        this._model["pagecontent-type"] = "contenttype";
     
        var cTypeView = this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']");
        var selectedRecord = cTypeView.getSelectionModel().getSelection()[0];
        this._model["contenttype"] = selectedRecord ? selectedRecord.getId() : null;
        this._model["contenttype-label"] = selectedRecord ? selectedRecord.get('label') : "";
        this._model["contenttype-view-names"] = selectedRecord ? selectedRecord.get('viewNames') : [];
    },
    
    /**
     * @private
     * Callback when the content type list is loaded
     * @param {Ext.data.Model[]} records The records loaded
     * @param {Function} callback The function to callback after
     * @param {boolean} callback.success true if the update was a success
     */
    _contenttypeCB4updateUI: function (records, callback)
    {
        var currentContentType = this._model["contenttype"]
                                    || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-contenttype')
                                    || Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-selected-contenttype'); 
        
        this._model["contenttype"] = "";
        this._model["contenttype-label"] = "";
    
        var cTypeView = this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']");
        var store = cTypeView.getStore();
        
        if (store.find('id', currentContentType) != -1)
        {
            cTypeView.getSelectionModel().select(store.find('id', currentContentType));
        }
        else
        {
            cTypeView.getSelectionModel().select(0);
        }
        
        this._initDefaultValues();
            
        this._cardPanel.down("*[itemId='add-page-pagecontent-" + this._model["pagecontent-type"] + "']").expand();
        this._cardPanel.down("*[itemId='add-page-pagecontent-" + this._model["pagecontent-type"] + "-view']").focus();
        
        this._scrollMultiselectToSelection(cTypeView)
        
        callback(true);
    },
    
    /**
     * @private
     * Callback when the service list is loaded
     * @param {Ext.data.Model[]} records The records loaded
     * @param {Function} callback The function to callback after
     * @param {boolean} callback.success true if the update was a success
     */
    _serviceCB4updateUI: function (records, callback)
    {
        var currentService = this._model["service"]; 
        this._model["service"] = "";
        this._model["service-action"] = "";
    
        var serviceView = this._cardPanel.down("*[itemId='add-page-pagecontent-service-view']");
        var store = serviceView.getStore();
        
        if (store.find('id', currentService) != -1)
        {
            serviceView.getSelectionModel().select(store.find('id', currentService));
        }
        else
        {
            serviceView.getSelectionModel().select(0);
        }
        
        this._scrollMultiselectToSelection(serviceView)

        callback(true);
    },
    
    isModelOk: function (fullModel)
    {
        var contentView = this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']");
        if (fullModel["pagecontent-type"] == "contenttype" && Ext.isEmpty(fullModel["contenttype"]))
        {
            contentView.addCls('invalid');
        }
        else
        {
            contentView.removeCls('invalid');
        }
        
        var serviceView = this._cardPanel.down("*[itemId='add-page-pagecontent-service-view']");
        if (fullModel["pagecontent-type"] == "service" && Ext.isEmpty(fullModel["service"]))
        {
            serviceView.addCls('invalid');
        }
        else
        {
            serviceView.removeCls('invalid');
        }
        
        var pagecontentType = fullModel["pagecontent-type"];
        return !Ext.isEmpty(fullModel[pagecontentType]) && (pagecontentType != "contenttype" || fullModel["contenttype-label"] != "");
    },
    
    isAvailable: function (fullModel)
    {
        return fullModel["page-type"] == "template"
            && (fullModel["right-contenttype"] || fullModel["right-service"]);
    },
    
    onEnter: function()
    {
        var fullModel = Ametys.plugins.web.page.AddPageWizard.getModel();
        this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype']").setDisabled(!fullModel["right-contenttype"]);
        this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype']").setVisible(this._isTrue(Ametys.plugins.web.page.AddPageWizard.getInitialConfig('pagecontent-content')));
        this._cardPanel.down("*[itemId='add-page-pagecontent-service']").setDisabled(!fullModel["right-service"]);
        this._cardPanel.down("*[itemId='add-page-pagecontent-service']").setVisible(this._isTrue(Ametys.plugins.web.page.AddPageWizard.getInitialConfig('pagecontent-service')));
        
        if (this._model["pagecontent-type"] == "contenttype" && !fullModel["right-contenttype"])
        {
            this._model["pagecontent-type"] = "service";
        }
        
        if (!this.shouldDisplayCard())
        {
            this.getUI().hide();
        }
    },
    
    /**
     * @private
     * Filters queries by input field value.
     * @param {Ext.data.Store} store The store to clear
     * @param {String} id The input id
     * @param {String} componentId The itemId of the panel wrapping the dataview
     * @param {String} dataViewComponentId The itemId of the dataview under the component
     */
    _filterByTitle: function (store, id, componentId, dataViewComponentId)
    {
        var field = Ext.getCmp(id);
        
        var value = Ext.String.trim(field.getValue());
        if (!value)
        {
            store.removeFilter('text');
            return;
        }
        
        var regexFilter = new RegExp(value, 'i');
        
        var dataview = this._cardPanel.getComponent(componentId).getComponent(dataViewComponentId);
        var currentSelection = dataview.getSelection();
       
        store.addFilter({
            id: 'text',
            filterFn: function(record){ return regexFilter.test(record.data.label)/* || regexFilter.test(record.data.description)*/; }
        })
        
        if (currentSelection.length > 0)
        {
            var me = this;
            Ext.Array.each(currentSelection, function (sel) {
                if (store.findExact(store.getModel().idProperty, sel.getId()) == -1)
                {
                    // The current selection is not visible, clear the selection
                    dataview.deselect([sel]);
                }
            })
        }
    },
    
    /**
     * @private
     * Clear the current text filter
     * @param {String} id The input id
     */
    _clearFilter: function(id)
    {
        Ext.getCmp(id).reset();
    },  
    
    
    /**
     * @private
     * Is textual filter required for ui?
     * @param {Ext.data.Store} store The store involved
     * @param {Ext.data.Model[]} records The records to analyse
     */
    _isTooBigSoNeedsTextFilter(store, records)
    {
        // We should not consider records filtered by other filter thant the textual one
        var finalRecords = Ext.Array.clone(records);
        
        var filters = store.getFilters();
        var i = 0;
        while (i < filters.length) 
        {
            if (filters.getAt(i)._property == 'id')
            {
                finalRecords = finalRecords.filter(r => store.getFilters().getAt(i).filter(r))
            }
            i++;
        }
        
        return finalRecords.length > 7;
    },
    
    /**
     * @private
     * Create field for selecting content type
     * @return multiselect field for content types.
     */
    _createContentTypesPanel4PageContentCard: function ()
    {
        var me = this;
        
        var store = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.web.page.AddPageWizard.PageContentCard.ContentType',
            
            proxy: this._getProxyForContentTypeCard(),
            groupField: "category",
            
            listeners: [{
                load: function(s, records) { 
                    Ext.getCmp('search-filter-contenttype').setVisible(me._isTooBigSoNeedsTextFilter(s, records));
                    Ext.getCmp('search-noresult-contenttype').setVisible(records.length == 0);
                    me._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']").setVisible(records.length > 0);
                    Ext.getCmp('search-hint-contenttype').setVisible(records.length > 0);
                }
            }],
            
            sorters: [{property: 'category', direction: 'ASC'},{property: 'label', direction: 'ASC'}]
        });
        if (Ametys.plugins.web.page.AddPageWizard.getInitialConfig('pagecontent-card-content-filter') != null)
        {
            store.addFilter({
                property: 'id',
                value: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('pagecontent-card-content-filter'),
                operator: 'in'
            });
        }
        
        return {
            itemId: 'add-page-pagecontent-contenttype',
            title: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['content-type-title'],
            header: {
                titlePosition: 1
            },
            
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            
            items: [
                    {
                        xtype: 'component',
                        id: 'search-hint-contenttype',
                        cls: 'a-text',
                        html: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['content-type-help']
                    },
                    {
                        xtype: 'component',
                        cls: 'a-text',
                        id: 'search-noresult-contenttype',
                        hidden: true,
                        html: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['content-type-nocontent'],
                    },
                    {
                        xtype: 'toolbar',
                        id: 'search-filter-contenttype',
                        layout: 'hbox',
                        padding: '0 0 4 0',
                        border: false,
                        items: [
                            {
                                xtype: 'textfield',
                                id: 'search-filter-contenttype-input',
                                cls: 'ametys',
                                width: 200,
                                emptyText: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['content-type-filter'],
                                enableKeyEvents: true,
                                listeners: {change: Ext.Function.createBuffered(this._filterByTitle, 300, this, [store, 'search-filter-contenttype-input', 'add-page-pagecontent-contenttype', 'add-page-pagecontent-contenttype-view'])}
                            }, {
                                // Clear filter
                                tooltip: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['content-type-filter-clear'],
                                handler: Ext.bind (this._clearFilter, this, ['search-filter-contenttype-input'], false),
                                iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
                                cls: 'a-btn-light'
                            }
                        ]
                    },
                    {
                        xtype: 'dataview',
                        ui: 'view',
                        cls: 'data-view-pagecontent',
                        
                        itemId: 'add-page-pagecontent-contenttype-view',
                    
                        border: true,
                        scrollable: true,
                        flex: 1,
                        
                        selModel: {
                            mode: 'SINGLE'
                        },
                        
                        style: {
                            padding: 0
                        },
                        
                        overItemCls:'x-view-over',
                        itemSelector:'div.dataview-item',
                        
                        tpl: new Ext.XTemplate(
                                '<tpl if="!(values && values.length)"><div class="dataview-noresult">' + Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['content-type-filter-noresult'] + '</div></tpl>',
                                '<tpl for=".">',
                                    '<tpl if="this._isFirstOfGroup(id)"><div class="dataview-category">{categoryLabel}</div></tpl>',
                                    '<div class="dataview-item" id="add-page-contenttype-{id}">',
                                        '<tpl if="iconGlyph && iconGlyph != \'\'">',
                                            '<span class="icon {iconGlyph} {iconDecorator}"></span>',
                                        '</tpl>',
                                        '<tpl if="!iconGlyph || iconGlyph == \'\'">',
                                            '<img src="' + Ametys.CONTEXT_PATH + '{iconSmall}"/>',
                                        '</tpl>',
                                        '<div class="text">',
                                        '<span class="title" title="{description}">{label}</span>',
                                    '</div></div>',
                                '</tpl>',
                                {
                                    _isFirstOfGroup: function(id)
                                    {
                                        var targetCategory = store.getById(id).get("category");
                                        var isTargetCategoryAlreadyPresent = false;
                                        store.each(function(record) {
                                            if (record.get("id") == id)
                                            {
                                                return false;
                                            }
                                            if (record.get("category") == targetCategory)
                                            {
                                                isTargetCategoryAlreadyPresent = true;
                                                return false;
                                            }
                                        }, me, { flitered: true });
                                        return !isTargetCategoryAlreadyPresent;
                                    }
                                }
                        ),
                            
                        store: store,
                        
                        listeners: {
                            'selectionchange': Ext.bind(Ametys.plugins.web.page.AddPageWizard._onChange, Ametys.plugins.web.page.AddPageWizard)
                        }
                    }
            ]
        };
    },
    
    
    /**
     * @private
     * Get proxy for content type card
     * @return the proxy configuration for content type card
     */
    _getProxyForContentTypeCard: function()
    {
        var showContentCard = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('show-card-content');
        var showContentPropertiesCard = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('show-card-content-properties');
        var contenttype = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-contenttype');
        var service = Ametys.plugins.web.page.AddPageWizard.getInitialConfig('default-service');
        
        if (!showContentCard && showContentPropertiesCard && contenttype && !service)
        {
            return {
                type: 'ametys',
                role: 'org.ametys.cms.contenttype.ContentTypesHelper',
                methodName: 'getContentTypesInformations',
                methodArguments: ['contentTypeIds', 'withRight'],

                reader: {
                    type: 'json'
                }
            };
        }
        else
        {
            return {
                type: 'ametys',
                role: 'org.ametys.web.repository.page.PageDAO',
                methodName: 'getAvailableContentTypesForCreation',
                methodArguments: ['pageId', 'zone', 'parentId', 'title', 'template'],

                reader: {
                    type: 'json'
                }
            };
       }
    },
    
    /**
     * @private
     * Create field for selecting service
     * @return multiselect field for services.
     */
    _createServicesPanel4PageContentCard: function ()
    {
        var me = this;
        
        var store = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.web.page.AddPageWizard.PageContentCard.Service',
            
            proxy: {
                type: 'ametys',
                role: 'org.ametys.web.repository.page.PageDAO',
                methodName: 'getAvailableServicesForCreation',
                methodArguments: ['pageId', 'zone', 'parentId', 'title', 'template'],

                reader: {
                    type: 'json'
                }
            },
            
            groupField: "category",
            
            listeners: [{
                load: function(s, records) { 
                    Ext.getCmp('search-filter-service').setVisible(me._isTooBigSoNeedsTextFilter(s, records));
                    Ext.getCmp('search-noresult-service').setVisible(records.length == 0);
                    me._cardPanel.down("*[itemId='add-page-pagecontent-service-view']").setVisible(records.length > 0);
                    Ext.getCmp('search-hint-service').setVisible(records.length > 0);
                }
            }],
            
            sorters: [{property: 'category', direction: 'ASC'},{property: 'label', direction: 'ASC'}]
        });
        
        if (Ametys.plugins.web.page.AddPageWizard.getInitialConfig('pagecontent-card-service-filter') != null)
        {
            store.addFilter({
                property: 'id',
                value: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('pagecontent-card-service-filter'),
                operator: 'in'
            });
        }
        return {
            itemId: 'add-page-pagecontent-service',
            title: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['service-title'],
            header: {
                titlePosition: 1
            },
            
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            
            items: [
                    {
                        xtype: 'component',
                        id: 'search-hint-service',
                        cls: 'a-text',
                        html: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['service-help']
                    },
                    {
                        xtype: 'component',
                        cls: 'a-text',
                        id: 'search-noresult-service',
                        hidden: true,
                        html: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['service-type-nocontent']
                    },
                    {
                        xtype: 'toolbar',
                        id: 'search-filter-service',
                        layout: 'hbox',
                        padding: '0 0 4 0',
                        border: false,
                        items: [
                            {
                                xtype: 'textfield',
                                id: 'search-filter-service-input',
                                cls: 'ametys',
                                width: 200,
                                emptyText: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['service-type-filter'],
                                enableKeyEvents: true,
                                listeners: {change: Ext.Function.createBuffered(this._filterByTitle, 300, this, [store, 'search-filter-service-input', 'add-page-pagecontent-service', 'add-page-pagecontent-service-view'])}
                            }, {
                                // Clear filter
                                tooltip: Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['service-type-filter-clear'],
                                handler: Ext.bind (this._clearFilter, this, ['search-filter-service-input'], false),
                                iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
                                cls: 'a-btn-light'
                            }
                        ]
                    },
                    {
                        xtype: 'dataview',
                        ui: 'view',
                        cls: 'data-view-pagecontent',
                        
                        itemId: 'add-page-pagecontent-service-view',
                    
                        border: true,
                        scrollable: true,
                        flex: 1,
                        
                        selModel: {
                            mode: 'SINGLE'
                        },
                        
                        style: {
                            padding: 0
                        },
                        
                        overItemCls:'x-view-over',
                        itemSelector:'div.dataview-item',
                        
                        tpl: new Ext.XTemplate(
                                '<tpl if="!(values && values.length)"><div class="dataview-noresult">' + Ametys.plugins.web.page.AddPageWizard.getInitialConfig('i18n')['content']['service-type-filter-noresult'] + '</div></tpl>',
                                '<tpl for=".">',
                                    '<tpl if="this._isFirstOfGroup(id)"><div class="dataview-category">{categoryLabel}</div></tpl>',
                                    '<div class="dataview-item" id="add-page-contenttype-{id}">',
                                        '<tpl if="iconGlyph && iconGlyph != \'\'">',
                                            '<span class="icon {iconGlyph} {iconDecorator}"></span>',
                                        '</tpl>',
                                        '<tpl if="!iconGlyph || iconGlyph == \'\'">',
                                            '<img src="' + Ametys.CONTEXT_PATH + '{iconSmall}"/>',
                                        '</tpl>',
                                        '<div class="text">',
                                        '<span class="title" title="{description}">{label}</span>',
                                    '</div></div>',
                                '</tpl>',
                                {
                                    _isFirstOfGroup: function(id)
                                    {
                                        var targetCategory = store.getById(id).get("category");
                                        var isTargetCategoryAlreadyPresent = false;
                                        store.each(function(record) {
                                            if (record.get("id") == id)
                                            {
                                                return false;
                                            }
                                            if (record.get("category") == targetCategory)
                                            {
                                                isTargetCategoryAlreadyPresent = true;
                                                return false;
                                            }
                                        }, me, { flitered: true });
                                        return !isTargetCategoryAlreadyPresent;
                                    }
                                }
                        ),                      
                            
                        store: store,
                        
                        listeners: {
                            'selectionchange': Ext.bind(Ametys.plugins.web.page.AddPageWizard._onChange, Ametys.plugins.web.page.AddPageWizard)
                        }
                    }
            ]
        };
    },
    
    //------------------------------------------------------------------------------------------------
    /**
     * @private
     * Listener after expanding panel
     * @param {Ext.Panel} panel the expanded panel
     */
    _onAfterExpand: function (panel)
    {
        Ametys.plugins.web.page.AddPageWizard._onChange();
        this._scrollMultiselectToSelection(this._cardPanel.down("*[itemId='add-page-pagecontent-contenttype-view']"));
        this._scrollMultiselectToSelection(this._cardPanel.down("*[itemId='add-page-pagecontent-service-view']"));
    },
    
    /**
     * @private
     * Scroll to current selection into multiselect field 
     * @param {Ext.ux.form.MultiSelect} field the multiselect field 
     */
    _scrollMultiselectToSelection: function(field)
    {
        if (field.rendered)
        {
            var eltScrolling = field.getEl();
            var eltSelected = eltScrolling.down('.x-item-selected', true);
            if (eltSelected)
            {
                var tmpId = eltSelected.id
                eltSelected.id = Ext.id();
                Ext.fly(eltSelected);
                eltSelected.id = tmpId;
                
                eltSelected.scrollIntoView(eltScrolling, false);
            }
        }
    }
});
        
Ext.define('Ametys.plugins.web.page.AddPageWizard.PageContentCard.ContentType', { 
    extend: 'Ext.data.Model', 
    fields: [ 
        { name: 'id', type: 'string' }, 
        { name: 'label', type: 'string' }, 
        { name: 'category', type: 'string', convert: function(v) { return v || "PLUGINS_CMS_CONTENT_CREATECONTENTMENU_GROUP_10_CONTENT"} }, 
        { name: 'categoryLabel', type: 'string', convert: function(v) { return v || "{{i18n plugin.cms:PLUGINS_CMS_CONTENT_CREATECONTENTMENU_GROUP_10_CONTENT}}"} }, 
        { name: 'description', type: 'string' }, 
        { name: 'iconGlyph', type: 'string' },
        { name: 'iconDecorator', type: 'string' },
        { name: 'iconSmall', type: 'string' },
        { name: 'iconMedium', type: 'string' },
        { name: 'iconLarge', type: 'string' }
    ]
}); 

Ext.define('Ametys.plugins.web.page.AddPageWizard.PageContentCard.Service', { 
    extend: 'Ext.data.Model', 
    fields: [ 
        { name: 'id', type: 'string' }, 
        { name: 'label', type: 'string' }, 
        { name: 'category', type: 'string', convert: function(v) { return v || "PLUGINS_WEB_SERVICE_CATEGORY_90_OTHERS"} }, 
        { name: 'categoryLabel', type: 'string', convert: function(v) { return v || "{{i18n plugin.web:PLUGINS_WEB_SERVICE_CATEGORY_90_OTHERS}}"} }, 
        { name: 'description', type: 'string' }, 
        { name: 'iconGlyph', type: 'string' },
        { name: 'iconDecorator', type: 'string' },
        { name: 'iconSmall', type: 'string' },
        { name: 'iconMedium', type: 'string' },
        { name: 'iconLarge', type: 'string' },
        { name: 'defaultTitle', type: 'string' }
    ]
});