/*
 *  Copyright 2018 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 display all contents referencing with a specific entry of a reference table
 * @private
 */
Ext.define('Ametys.plugins.cms.content.tool.ReferenceTableReferencingContentsTool', {
	extend: "Ametys.tool.Tool",
		
	statics: {
		/**
		 * @property {Number}
		 * @readonly
		 * @static
		 * The number of records to display by 'page'
		 */
		PAGE_SIZE: 50
	},
	
	/**
	 * @private
	 * @property {Ext.Template} _hintTpl The template for hint
	 */
	_hintTpl: Ext.create ('Ext.XTemplate', ["{{i18n PLUGINS_CMS_UITOOL_REFERENCE_TABLE_REFERENCING_CONTENTS_HINT1}}",  
	                                       "<b>'{[Ext.String.escapeHtml(values.title)]}'</b>", "{{i18n PLUGINS_CMS_UITOOL_REFERENCE_TABLE_REFERENCING_CONTENTS_HINT2}}",
	                                       "<b>'{referenceTable}'</b>"
	]),
	
	/**
	 * @private
	 * @property {Ext.Template} _titleTpl The template for tool's title
	 */
	_titleTpl: Ext.create ('Ext.Template', ["{{i18n PLUGINS_CMS_UITOOL_REFERENCE_TABLE_REFERENCING_CONTENTS_TOOL_TITLE}}", "{title}"]),
	
	/**
	 * @private
	 * @property {Ext.Template} _descriptionTpl The template for tool's description
	 */
	_descriptionTpl: Ext.create ('Ext.Template', ["{{i18n PLUGINS_CMS_UITOOL_REFERENCE_TABLE_REFERENCING_CONTENTS_TOOL_DESC}}",  
	                                       "<b>'{title}'</b>"
	]),
	
	createPanel: function()
	{
		this.grid = this._createResultGrid();
		return this.grid;
	},
	
	setParams: function (params)
	{
		this.callParent(arguments);
		
		this._contentId = params.id;
		this.refresh();
		
    	// Register the tool on the history tool
		var toolId = this.getFactory().getId();
	    var toolParams = this.getParams();

        Ametys.navhistory.HistoryDAO.addEntry({
			id: this.getId(),
			label: this.getTitle(),
            description: Ext.String.format("{{i18n PLUGINS_CMS_UITOOL_REFERENCE_TABLE_REFERENCING_CONTENTS_NAVHISTORY_ACTION_DESC}}", toolParams.title),
			iconSmall: this.getSmallIcon(),
			iconMedium: this.getMediumIcon(),
			iconLarge: this.getLargeIcon(),
			type: Ametys.navhistory.HistoryDAO.TOOL_TYPE,
			action: Ext.bind(Ametys.tool.ToolsManager.openTool, Ametys.tool.ToolsManager, [toolId, toolParams], false)
        });
	},
	
	refresh: function ()
	{
		this.callParent(arguments);
		
		this.showUpToDate();
		this._setGridDisabled(true);
        
        this.setTitle(this._titleTpl.applyTemplate(this.getParams()));
        this.setDescription(this._descriptionTpl.applyTemplate(this.getParams()));
        
        var referenceTable = null;
        if (this.getParams().contenttypes)
        {
            Ext.Array.each(this.getParams().contenttypes, function(id) {
                var cType = Ametys.cms.content.ContentTypeDAO.getContentType(id);
                if (cType.isReferenceTable())
                {
                    referenceTable = cType.getLabel();
                    return false; // stop iteration
                }
            });
        }
        
        var html = this._hintTpl.applyTemplate({
            title: this.getParams().title,
            referenceTable: referenceTable
        });
        
        this.grid.getDockedItems('#hint-message')[0].update(html);
        this.store.loadPage(1);
		
	},
	
	/**
	 * @protected
	 * Create the grid panel for results
	 * @return {Ext.grid.Panel} The created grid
	 */
	_createResultGrid: function ()
	{
		this.store = this._createStore();
        
        var contentTypes = Ametys.cms.content.ContentTypeDAO.getContentTypes().createFiltered(function(contentType) {
            return !contentType.isMixin() && !contentType.isAbstract();
        });
        
        var cTypeData = Ext.Array.map(contentTypes.getRange(), function(contentType) {
            return {'id': contentType.getId(), 'text': contentType.getLabel()};
        });
            
		return Ext.create("Ametys.cms.content.EditContentsGrid", { 
			store: this.store,
			
			dockedItems: [{
				xtype: 'component',
	        	ui: 'tool-hintmessage',
                itemId: 'hint-message',
				dock: 'top',
				html: ''
			}],
			
			stateful: true,
			stateId: this.self.getName()  + "$grid",
            
            plugins: [{ptype: 'gridfilters'}],
            
			columns: [
                // Some SearchGridHelper renderers require an additional parameter to be provided
			    {stateId: this.self.getName()  + '$title', header: "{{i18n PLUGINS_CMS_METADATA_TITLE_LABEL}}", width: 200, dataIndex: 'title', renderer: Ametys.plugins.cms.search.SearchGridHelper.renderTitle},
			    {
                    stateId: this.self.getName()  + '$contentType',
                    header: "{{i18n UITOOL_SEARCH_CONTENT_ALL_CONTENT_TYPE}}", 
                    width: 180, 
                    dataIndex: 'contentTypes', 
                    renderer: Ametys.plugins.cms.search.SearchGridHelper.renderMultipleString, 
                    filter: {
	                    type: 'list',
	                    store: Ext.create('Ext.data.Store', {
	                        fields: ['id', 'text'],
                            data: cTypeData,
	                        sorters: 'text'
                        }),
                        showFilteringLimit: 10
	                }
                },
			    {stateId: this.self.getName() + '$language', header: "{{i18n UITOOL_SEARCH_LANGUAGE}}", width: 80, hidden: false, dataIndex: 'language', renderer: Ext.bind(Ametys.plugins.cms.search.SearchGridHelper.renderLanguage, null, ['language'], true)},
			    {stateId: this.self.getName() + '$creator', header: "{{i18n UITOOL_SEARCH_CONTENT_CREATOR}}", width: 160, hidden: false, dataIndex: 'creator', renderer: Ext.bind(Ametys.grid.GridColumnHelper.renderUser, null, ['creator'], true)},
			    {stateId: this.self.getName() + '$contributor', header: "{{i18n UITOOL_SEARCH_CONTENT_AUTHOR}}", width: 160, dataIndex: 'contributor', renderer: Ext.bind(Ametys.grid.GridColumnHelper.renderUser, null, ['contributor'], true)},
			    {stateId: this.self.getName() + '$lastModified', header: "{{i18n UITOOL_SEARCH_CONTENT_LASTMODIFIED}}", width: 140, dataIndex: 'lastModified', xtype: 'datecolumn', format: Ext.Date.patterns.FriendlyDateTime},
			    {stateId: this.self.getName() + '$workflowStep', header: "{{i18n UITOOL_SEARCH_CONTENT_WORKFLOW_STEP}}", width: 90, dataIndex: 'workflowStep', renderer: Ext.bind(Ametys.plugins.cms.search.SearchGridHelper.renderWorkflowStep, null, ['workflowStep'], true)}
			],
			
			messageTarget: Ametys.message.MessageTarget.CONTENT,
			
			selModel : {
				mode: 'MULTI'
			},
			
			viewConfig: {
				loadingText: "{{i18n plugin.cms:UITOOL_SEARCH_WAITING_MESSAGE}}"
			},
			
			listeners: {
				'itemdblclick': {fn: function (view, record, item, index, e) { this.openContent(record); }, scope: this}
			}
		});
	},
	
	/**
	 * Open content (on double-click for example)
	 * @param {Ext.data.Model} record The content to open
	 */
	openContent: function (record)
	{
		Ametys.cms.content.EditContentsGrid.openContent (record);
	},
	
	sendCurrentSelection: function()
	{
		this.grid.sendCurrentSelection();
	},
	
	getMBSelectionInteraction: function() 
	{
	    return Ametys.tool.Tool.MB_TYPE_ACTIVE;
	},
	
	/**
	 * @private
	 * Get the store the grid should use as its data source.
	 * @return {Ext.data.Store} The store
	 */
	_createStore: function ()
	{
		return Ext.create('Ext.data.Store', {
			model: 'Ametys.plugins.cms.content.tool.ReferenceTableReferencingContentsTool.ContentEntry',
			remoteSort: false,
            remoteFilter: true,
            statefulFilters: false, // do not saved filters
			proxy: {
				type: 'ametys',
				plugin: 'cms',
				url: 'reference-tables/referencing-contents.json',
				reader: {
					type: 'json',
					rootProperty: 'contents'
				},
                extraParams:
                {
                    lang: Ametys.cms.language.LanguageDAO.getCurrentLanguage()
                }
			 },
			 
			 pageSize: Ametys.plugins.cms.content.tool.ReferenceTableReferencingContentsTool.PAGE_SIZE,
			 sortOnLoad: true,
			 sorters: [{property: 'title', direction:'ASC'}],
			 
			 listeners: {
				 'beforeload': {fn: this._onBeforeLoad, scope: this},
				 'load': {fn: this._onLoad, scope: this}
			 }
		});
	},
	
	/**
	 * Function called before loading the store
	 * @param {Ext.data.Store} store The store
	 * @param {Ext.data.operation.Operation} operation The object that will be passed to the Proxy to load the store
	 * @private
	 */
	_onBeforeLoad: function (store, operation)
	{
		this.grid.getView().unmask();
		
		operation.setParams(Ext.apply(operation.getParams() || {}, {
			contentId: this._contentId
		}));
	},
	
	/**
	 * Function called after loading results
	 * @param {Ext.data.Store} store The store
	 * @param {Ext.data.Model[]} records An array of records
	 * @param {Boolean} successful True if the operation was successful.
	 * @private
	 */
	_onLoad: function (store, records, successful)
	{		
		this._setGridDisabled(false);
		
		if (!successful)
		{
			Ametys.log.ErrorDialog.display({
				title: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR_TITLE}}",
				text: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR}}",
				details: "",
				category: "Ametys.plugins.cms.content.tool.ReferencingContentsTool"
			});
			return;
		}
		
		if (records.length == 0)
		{
			this.grid.getView().mask("{{i18n plugin.cms:UITOOL_CONTENTEDITIONGRID_NO_RESULT}}", 'ametys-mask-unloading');
		}
	},
	
	/**
	 * Enable or disable the grid columns and paging toolbar
	 * @param {Boolean} disabled true to disable.
	 * @private
	 */
	_setGridDisabled: function (disabled)
	{
		this.grid.getPageBar().setDisabled(disabled);
		
		var columns = this.grid.columnManager.getColumns();
		Ext.Array.each (columns, function (column) {
			column.setDisabled(disabled);
		})
	}
});

Ext.define('Ametys.plugins.cms.content.tool.ReferenceTableReferencingContentsTool.ContentEntry', {
	extend: 'Ext.data.Model',
	
    fields: [
        { name: 'id'},
        {
            name: 'title', 
            type: 'string', 
            convert: function(value, record)
            {
                if (Ext.isObject(value))
                {
                    // Handle multilingual title
                    var message = Ametys.message.MessageBus.getCurrentSelectionMessage();
                    var contentTarget = message.getTarget(Ametys.message.MessageTarget.CONTENT) || message.getTarget(Ametys.message.MessageTarget.REFERENCE_TABLE_CONTENT);
                    
                    return Ametys.plugins.cms.search.SearchGridHelper.getDefaultLocalizedValue(value, contentTarget ? contentTarget.getParameters().lang : null);
                }
                else
                {
                    return value;
                }
            }
         },
        { name: 'iconGlyph', convert: function(v) { return v || ''; }},
        { name: 'iconDecorator', convert: function(v) { return v || ''; }},
        { name: 'smallIcon', convert: function(v) { return v || ''; }},
        { name: 'mediumIcon', convert: function(v) { return v || ''; }},
        { name: 'largeIcon', convert: function(v) { return v || ''; }},
        // Some SearchGridHelper converters require an additional parameter to be provided
        { name: 'contentTypes', convert: Ext.bind(Ametys.plugins.cms.search.SearchGridHelper.convertMultipleValue, null, ['contentTypes'], true)},
        { name: 'mixins' },
        { name: 'lastModified' },
        { name: 'creationDate' },
        { name: 'language', convert: Ext.bind(Ametys.plugins.cms.search.SearchGridHelper.convertLanguage, null, ['language'], true)},
        { name: 'workflowStep', convert: Ext.bind(Ametys.plugins.cms.search.SearchGridHelper.convertWorkflowStep, null, ['workflowStep'], true)}
    ]
});