/*

 *  Copyright 2013 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 the locked contents
 * @private
 */
Ext.define('Ametys.plugins.cms.content.tool.UnlockTool', {
	extend: "Ametys.tool.Tool",
	
	/**
	 * @property {Ext.data.ArrayStore} store The store with the locked contents
	 * @private
	 */
	
	/**
	 * @property {Ext.grid.Panel} grid The grid panel displaying the locked contents
	 * @private
	 */
	
	constructor: function(config)
	{
		this.callParent(arguments);
		Ametys.message.MessageBus.on(Ametys.message.Message.LOCK_CHANGED, this._onLockChanged, this);
	},
	
	createPanel: function()
	{
		this.store = this.createStore();
		
		this.grid = Ext.create("Ext.grid.Panel", { 
			store: this.store,
			stateful: true,
			stateId: this.self.getName() + "$grid",
			
			scrollable: true,
		    
			columns: [
		         {stateId: 'grid-title', header: "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_TITLE}}", flex: 1, sortable: true, dataIndex: 'title', renderer: this._renderTitle},
		         {stateId: 'grid-since', header: "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_SINCE}}", hidden: true, width: 180, sortable: true, dataIndex: 'since', renderer: this._renderSince},
		         {stateId: 'grid-since-hours', header: "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_SINCE}}", hidden: true, hideable: false, sortable: true, dataIndex: 'sinceHours', renderer: this._renderSinceHours},
		         {stateId: 'grid-time-left', header: "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_TTU}}", width: 220, sortable: true, dataIndex: 'unlockTimeLeft', renderer: this._renderTimeLeft},
		         {stateId: 'grid-lockBy', header: "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_BY}}", width: 300, sortable: true, dataIndex: 'lockBy'}
		    ],
		    
		    selModel : {
		    	mode: 'MULTI'
		    },
		    
		    features: [{
		        groupHeaderTpl: ['{columnName}: ',
		                         '{name}'
		        ],
                enableGroupingMenu: false,
		        ftype: 'grouping'
		    }],
		    
		    listeners: {'selectionchange': Ext.bind(this._selectContent, this)}
		});
		
		return this.grid;
	},
	
	/**
	 * Create the store for locked contents.
	 * Override if you need to override the called url or the used model
	 * @return {Ext.data.Store} the store for locked contents
	 */
	createStore: function ()
	{
		return Ext.create('Ext.data.Store', {
			autoDestroy: true,
			model: 'Ametys.plugins.cms.content.tool.UnlockTool.LockedContentEntry',
			proxy: {
				type: 'ametys',
				plugin: 'cms',
				url: 'lock/list.xml',
				reader: {
					type: 'xml',
					record: 'LockedContent',
					rootProperty: 'List'
				},
                
                extraParams: this.getLoadParameters()
			 },
			 
			 sortOnLoad: true,
			 sorters: [{property: 'title', direction:'ASC'}],
			 groupField : 'sinceHours'
		});
	},
	
	/**
	 * Get the parameters to pass along with the request when loading store.
	 * Override this function if you need to pass your own parameters.
	 * @return {Object} The parameters to pass to the request
	 */
	getLoadParameters: function ()
	{
		return {};
	},
	
	getMBSelectionInteraction: function() 
	{
	    return Ametys.tool.Tool.MB_TYPE_ACTIVE;
	},
	
	setParams: function (params)
	{
		this.callParent(arguments);
		this.refresh();
	},
	
	refresh: function ()
	{
		this.showRefreshing();
		this.store.load({callback: this.showRefreshed, scope: this});
	},
	
	/**
	 * Renderer method to transform records' title to add the lock status
	 * @param {Object} value The data value
	 * @param {Object} metaData A collection of metadata about the current cell
	 * @param {Ext.data.Model} record The record for the current row
	 * @protected
	 */
	_renderTitle: function (value, metaData, record)
	{
		if (record.get('isLockOwner') == 'true')
		{
			return Ext.String.format('<span class="a-grid-glyph ametysicon-lock81 locked-owner"></span>{0}', value);
		}
		else if (record.get('canUnlock') == 'true')
		{
			return Ext.String.format('<span class="a-grid-glyph ametysicon-lock81 locked"></span>{0}', value);
		}
		else
		{
			return Ext.String.format('<span class="a-grid-glyph ametysicon-lock81 locked-disable"></span>{0}', value);
		}
	},
	
	/**
	 * Renderer method to transform time left duration records
	 * @param {Object} value The data value
	 * @param {Object} metaData A collection of metadata about the current cell
	 * @param {Ext.data.Model} record The record for the current row
	 * @protected
	 */
	_renderTimeLeft: function (value, metaData, record)
	{
        if (value != null)
        {
            return Ext.util.Format.duration(value);
        }
		else
		{
			return "<i>" + "{{i18n PLUGINS_CMS_CONFIG_UNLOCKTIMER_DESACTIVATE}}" + "</i>";
		}
	},
	
	/**
	 * Renderer method to transform records' "since" properties
	 * @param {Object} value The data value
	 * @param {Object} metaData A collection of metadata about the current cell
	 * @param {Ext.data.Model} record The record for the current row
	 * @protected
	 */
	_renderSince: function(value, metaData, record)
	{
        return Ext.util.Format.duration(value);
	},
    
	/**
	 * Renderer method to transform records' "since" properties
	 * @param {Object} value The data value
	 * @param {Object} metaData A collection of metadata about the current cell
	 * @param {Ext.data.Model} record The record for the current row
	 * @protected
	 */
	_renderSinceHours: function(value, metaData, record)
	{
		if (value != null)
		{
			if (value == '0')
			{
				return "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_LESS_AN_HOUR}}";
			}
			else
			{
				return value + " "  + "{{i18n PLUGINS_CMS_REPOSITORY_LOCK_HOURS}}";
			}
		}
	},
	
	/**
	 * Fires a event of selection on message bus, from the selected contents in the grid.
	 */
	_selectContent: function ()
	{
		var contentIds = [];
		
		var selection = this.grid.getSelectionModel().getSelection();
		for (var i=0; i < selection.length; i++)
		{
			contentIds.push(selection[i].get('id'));
		}
		
		Ext.create("Ametys.message.Message", {
			type: Ametys.message.Message.SELECTION_CHANGED,
			
			targets: {
				id: Ametys.message.MessageTarget.CONTENT,
				parameters: { ids: contentIds }
			}
		});
	},
	
	/**
	 * Listener when the lock has changed.
	 * Will update the lock state of the buttons effectively upon the current selection.
	 * @param {Ametys.message.Message} message The lock changed message.
	 * @protected
	 */
	_onLockChanged: function (message)
	{
		if (message.getTargets(Ametys.message.MessageTarget.CONTENT))
		{
			this.showOutOfDate();
		}
	},
	
	sendCurrentSelection: function()
	{
		this._selectContent();
	}
});

/**
 * This class is the model for entries in the grid of the unlock contents tool
 * @private
 */
Ext.define("Ametys.plugins.cms.content.tool.UnlockTool.LockedContentEntry", {
	extend: 'Ext.data.Model',
	
    fields: [
		{name: 'id', mapping: '@id'},    
		{name: 'title', mapping: '@title', type: 'string'},
		{name: 'unlockTimeLeft', mapping: '@unlockTime'},
		{name: 'since', mapping: '@since'},
		{name: 'sinceHours', calculate: function(data) {
            return Math.floor(data.since / 1000 / 3600);
        }},
		{name: 'lockBy', mapping: '@lockBy', type: 'string'},
		{name: 'canUnlock', mapping: '@canUnlock'},
		{name: 'isLockOwner', mapping: '@isLockOwner'}
    ]
});