/*
 *  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.
 */

/**
 * {@link} Ext.data.TreeStore for sites
 * @private
 */
Ext.define('Ametys.web.site.SitesTree', {
	extend: 'Ext.tree.Panel',
	
	/**
	 * @cfg {String} [url=list/sites.json] The proxy url of the store 
	 */
	
	/**
	 * @cfg {String} [plugin=web] The plugin for the url. 
	 */
	
	/**
	 * @cfg {Boolean} [showColumns=false] Set to true to show columns
	 */
    /**
     * @cfg {Boolean} [readAccessOnly=false] true to list sites on read access only. Defaults to false.
     */
	readAccessOnly: false,
    /**
     * @cfg {Boolean} [sharedSitesOnly=false] true to list sites with shared contents only. Defaults to false.
     */
	sharedSitesOnly: false,
	
	/**
	 * @private
	 * @property {Ext.Template} _siteTooltipTpl The template used for site' tooltip
	 */
	_siteTooltipTpl: Ext.create ('Ext.Template', [
	                                            '{description}',
	                                  			'<u>{{i18n PLUGINS_WEB_HELPER_CHOOSESITE_TOOLTIP_SHARED_CONTENTS}}</u> : {sharedContentsCount}<br/>',
	                                  			'<u>{{i18n PLUGINS_WEB_HELPER_CHOOSESITE_TOOLTIP_URL}}</u> : {url}<br/>'
	                                		]),
	
	constructor: function(config)
	{
	    if ('readAccessOnly' in config)
        {
	        this.readAccessOnly = config.readAccessOnly;
        }
	    if ('sharedSitesOnly' in config)
        {
	        this.sharedSitesOnly = config.sharedSitesOnly;
        }
	    
		var columns;
		if (config.showColumns)
		{
			columns = [{
		        xtype: 'treecolumn',
		        text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_TITLE}}",
                stateId: 'text',
		        dataIndex: 'text',
		        width: 250,
		        sortable: true
		    }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_NAME}}",
                stateId: 'name',
                dataIndex: 'name',
                width: 150,
                sortable: true,
                hidden: true,
                renderer: function (name) { return name == 'ametys:sites' ? '' : name }
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_ID}}",
                stateId: 'id',
                dataIndex: 'id',
                width: 320,
                sortable: true,
                hidden: true
            }, {
		        text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_DESCRIPTION}}",
                stateId: 'description',
		        dataIndex: 'description',
		        flex: 0.4,
		        sortable: true
		    },
		    {
		        text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_URL}}",
                stateId: 'url',
		        dataIndex: 'url',
		        flex: 0.6,
		        sortable: true
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_GROUPS_SKIN}}",
                stateId: 'skinLabel',
                dataIndex: 'skinLabel',
                flex: 0.2,
                sortable: true,
                renderer: this._renderSkin
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_GROUPS_SKINID}}",
                stateId: 'skin',
                dataIndex: 'skin',
                flex: 0.2,
                sortable: true,
                hidden: true
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_POPULATIONS}}",
                stateId: 'populations',
                dataIndex: 'populations',
                flex: 0.6,
                sortable: true,
                renderer: this._renderPopulations
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_GROUPS}}",
                stateId: 'groups',
                dataIndex: 'groups',
                flex: 0.4,
                sortable: true,
                renderer: this._renderGroupDirectories
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_POPULATIONS_FO}}",
                stateId: 'populationsFO',
                dataIndex: 'populationsFO',
                flex: 0.4,
                sortable: true,
                renderer: this._renderPopulations
            }, {
                text: "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_GROUPS_FO}}",
                stateId: 'groupsFO',
                dataIndex: 'groupsFO',
                flex: 0.2,
                sortable: true,
                renderer: this._renderGroupDirectories
            }]
		}
        
        config.viewConfig = config.viewConfig || {};
        config.viewConfig.markDirty = false;
		
		Ext.applyIf (config, {
			rootVisible: true,
			
			cls: 'sites-tree',
			border: false,
			scrollable: true,
			
			columns: columns,
            
			store: Ext.create('Ext.data.TreeStore', {
				model: 'Ametys.web.site.SitesTree.Site',
				
				root: {
					allowDrag: false,
					expanded: true,
					valid: true,
					iconGlyph: "ametysicon-world91",
					title: "{{i18n PLUGINS_WEB_SITES_TREE_SITES_ROOT_LABEL}}",
					description: "{{i18n PLUGINS_WEB_SITES_TREE_SITES_ROOT_DESCRIPTION}}",
					id: 'root',
					name: 'ametys:sites'
				},			
				
		        proxy: {
		        	type: 'ametys',
					plugin: config.plugin || 'web',
					url: config.url || 'list/sites.json',
		        	reader: {
		        		type: 'json',
						rootProperty: 'sites'
		        	}
		        },
		        
		        listeners: {
					'beforeload': Ext.bind(this._onBeforeLoad, this)
				},
		        
		        sorters: [ { property: 'title', direction: "ASC" }]
			})
		});

        this.callParent(arguments);
		
		this.addListener('itemmouseenter', this._createQtip, this);
	},
    
    /**
     * Renders an array of populations
     * @param {Array} value The data value for the current cell.
     * @return {String} The html representation
     * @private
     */
    _renderPopulations: function(value)
    {
        var result = "",
            separator = ", ",
            styleAttr = 'style="opacity: 0.7; font-style: italic"',
            enabledPopulations = [],
            disabledPopulations = [];
            
        Ext.Array.forEach(Ext.Array.from(value), function(population) {
            population.enabled ? enabledPopulations.push(population.label) : disabledPopulations.push('<span ' + styleAttr + '>' + population.label + '</span>');
        }, this);
        
        result += enabledPopulations.join(separator);
        if (enabledPopulations.length > 0 && disabledPopulations.length > 0)
        {
            result += separator;
        }
        result += disabledPopulations.join(separator);
        
        return result;
    },
    
    /**
     * Renders an array of group directories
     * @param {Array} value The data value for the current cell.
     * @return {String} The html representation
     * @private
     */
    _renderGroupDirectories: function(value)
    {
        var result = "";
        
        Ext.Array.forEach(Ext.Array.from(value), function(item, index) {
            if (index > 0)
            {
                result += ", ";
            }
            result += item.label;
        }, this);
        
        return result;
    },
    
    /**
     * Renders a skin label
     * @param {String} value The data value for the current cell.
     * @param {Object} metadata See Ext.grid?column.Column#renderer 
     * @param {Ext.data.Model} record The record to display
     * @return {String} The html representation
     * @private
     */
    _renderSkin: function(value, metadata, record)
    {
        let skinId = record.get("skin");
        if (value && skinId)
        {
            return value + " (" + record.get("skin") + ")";
        }
        else if (!value && skinId)
        {
            return "{{i18n PLUGINS_WEB_SITES_TREE_COLUMN_GROUPS_SKIN_UNKNOWN}} " + skinId;
        }
        else
        {
            return value;
        }
    },
    
	/**
	 * @private
	 * Listener before loading tree node
	 * @param {Ext.data.TreeStore} store The tree store
	 * @param {Ext.data.operation.Operation} operation The operation object that will be passed to the Proxy to load the Store
	 */
	_onBeforeLoad: function(store, operation)
    {
	    var params = operation.getParams() || {};
	    Ext.apply(params, {
            readAccessOnly: this.readAccessOnly,
            sharedSitesOnly: this.sharedSitesOnly
	    });
	    
		var node = operation.node;
		if (node != null && !node.isRoot())
		{
		    params.id = node.getId();
		}
		
		operation.setParams(params);
    },
    
    /**
     * Destroy and create the node tooltip when the mouse enters the node
     * @param {Ext.view.View} view The tree view
     * @param {Ext.data.Model} node The tree node
     * @param {HTMLElement} el The node's element
     */
    _createQtip: function (view, node, el)
    {
    	if (!node.isRoot())
    	{
    		Ext.QuickTips.unregister(el);
    		
    		var text = this._siteTooltipTpl.applyTemplate ({
    			url: node.get('url'), 
    			sharedContentsCount: node.get('sharedContentsCount')
    		});
    		
    		Ext.QuickTips.register({
            	target: el,
                
            	id: el.id + '-tooltip',
            	glyphIcon: node.get('iconGlyph'),
            	iconDecorator: node.get('valid') ? null : 'decorator-ametysicon-caution9 site-warning',
            	image: node.get('iconGlyph') ? null : Ametys.CONTEXT_PATH + node.get('iconLarge'),
                title: node.get('title') + ' (' + node.get('name') + ')',
                text:  text,
                inribbon: false
            });
    	}
    },
    
    /**
     * Expand the tree to the given path. 
     * @param {String[]} path The path to expand
     * @param {Function} callback The callback function to call after expand. Can be null.
     * @param {Boolean} callback.success true if the node expansion was successful
     * @param {Ext.data.Model} callback.record If successful, the target record
     * @param {HTMLElement} callback.node If successful, the record's view node. If unsuccessful, the last view node encountered while expanding the path.
     * @param {Object} [scope] The scope for the callback
     */
    expandNodeByPath: function(path, callback, scope) 
    {
        var path = this.getRootNode().getPath('name') + '/' + path,
            callback = callback || Ext.emptyFn,
            scope = scope || window;
        
        this.expandPath(path, {
            field: 'name',
            callback: callback,
            scope: scope
        });
    }
});