/*
 *  Copyright 2010 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 does display the versions history of a resource in a timeline
 * @private
 */
Ext.define('Ametys.plugins.explorer.applications.resources.ResourceHistoryTool', {
	extend: "Ametys.tool.SelectionTool",
	
    /**
     * @private
     * @readonly
     * @property {Number} MIN_WIDTH The min width
     */
    MIN_WIDTH: 350,
    
	/**
	 * @private
	 * @property {Ext.Template} _resourceHintTpl The template used for hint description
	 */
	_resourceHintTpl: new Ext.XTemplate("{{i18n PLUGINS_EXPLORER_FILE_HISTORY_HINT_1}}<strong>{[Ext.String.escapeHtml(values.name)]}</strong>{{i18n PLUGINS_EXPLORER_FILE_HISTORY_HINT_2}}"),
	
	constructor: function(config)
	{
		this.callParent(arguments);
		
		Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
		Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onDeleted, this);
	},
	
	createPanel: function()
	{
		this._timeline = Ext.create('Ametys.timeline.Timeline', {
			scrollable: true,
			
            minInsideWidth: this.MIN_WIDTH,
            
			dockedItems: {
				dock: 'top',
				ui: 'tool-hintmessage',
				xtype: 'component',
				html: ''
			},
			
			cls: ['a-timeline', 'uitool-resource-history'],
			
			timelineItemHTML: ['<div class="timeline-item {type}">',
		                  		'<div class="profile-img-wrap">',
		                  			'<img src="{profileImg}" alt="">',
		                  			'<div>{hour}</div>',
		                  		'</div>',
		                  		'<div class="contents-wrap">',
		                  			'<span class="vertical-line"></span>',
		                  			'<tpl if="topText">',
		                  				'<div class="top">{topText}</div>',
		                  			'</tpl>',
		                  			'<div class="text">{text}</div>',
		                  			'{download}',
		                  			'{restore}',
		                  		'</div>',
		                  	'</div>']
		});
		
		return Ext.create('Ext.panel.Panel', {
			scrollable: false, 
			border: false,
			layout: 'card',
			activeItem: 0,
			
			items: [{
					xtype: 'component',
					cls: 'a-panel-text-empty',
					border: false,
					html: ''
				}, 
				this._timeline
			]
		});
	},
	
	refresh: function (manual)
	{
		this.showRefreshing();
		
		var resourceTarget = this.getCurrentSelectionTargets()[0];
		this._resourceId = resourceTarget.getParameters().id;
		this._allowRestore = Ext.Array.contains(resourceTarget.getParameters().rights, 'Plugin_Explorer_File_Add');
		
		this.getContentPanel().items.get(1).down("*[dock='top']").update(this._resourceHintTpl.applyTemplate({'name': resourceTarget.getParameters().name}));
		
		Ametys.data.ServerComm.callMethod({
			role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO', 
			methodName: 'resourceHistory',
			parameters: [this._resourceId],
			callback: {
				handler: this._getHistoryVersionsCb,
				scope: this
			},
			waitMessage: true,
			errorMessage: "{{i18n PLUGINS_EXPLORER_FILE_HISTORY_ERROR}}"
		});
	},
	
	/**
	 * @private
	 * Callback function invoked after retrieving the history versions
	 * @param {Object[]} versions The resource's versions
     * @param {Object[]} [args] Unused.
	 */
	_getHistoryVersionsCb: function (versions, args)
	{
		var me = this;
		var data = [];
		Ext.Array.each (versions, function (version) {
			
			var item = {
				id: Ext.id(),
				date: Ext.Date.parse(version.createdAt, Ext.Date.patterns.ISO8601DateTime),
				version: version.rawName,
				topText: "{{i18n PLUGINS_EXPLORER_FILE_HISTORY_VERSION}}" + version.name,
				restore: ''
			};
			
			if (version.author)
			{
				item.username = version.author.fullname;
				item.profileImg = Ametys.helper.Users.getUserImage(version.author.login, version.author.populationId, 46);
				item.text = Ext.String.format("{{i18n PLUGINS_EXPLORER_FILE_HISTORY_AUTHOR_ACTION}}", version.author.fullname)
			}
			else
			{
				item.profileImg = Ametys.getPluginResourcesPrefix('core-ui') + '/img/user-profiles/default.png';
				item.text = '{{i18n PLUGINS_EXPLORER_FILE_HISTORY_UNKNOWN_AUTHOR}}';
			}
			
			item.download = '<div class="action action-download ametysicon-arrow88" title="{{i18n PLUGINS_EXPLORER_FILE_HISTORY_VERSION_DOWNLOAD}}" onclick="Ametys.tool.ToolsManager.getTool(\'' + me.getId() + '\').downloadVersion(\'' + version.rawName + '\')"></div>';
			if (me._allowRestore)
			{
				item.restore = '<div class="action action-restore ametysicon-curve4" title="{{i18n PLUGINS_EXPLORER_FILE_HISTORY_VERSION_RESTORE}}" onclick="Ametys.tool.ToolsManager.getTool(\'' + me.getId() + '\').restoreVersion(\'' + version.rawName + '\')"></div>';
			}
			data.push(item);
		});
		
		this._timeline.getStore().loadData(data);
		this.getContentPanel().getLayout().setActiveItem(1);
		
		this.showRefreshed();
	},
	
	setNoSelectionMatchState: function (message)
	{
		this.callParent(arguments);
		
		var panel = this.getContentPanel().items.get(0);
		panel.update(message);
		this.getContentPanel().getLayout().setActiveItem(0);
		
		this._resourceId = null;
	},
	
	/**
	 * Listener on {@link Ametys.message.Message#DELETED} message. If the current resource is concerned, the tool will be set in no selection mode.
	 * @param {Ametys.message.Message}  message The deleted message.
	 * @protected
	 */
	_onDeleted: function (message)
	{
		if (this.getTargetsInCurrentSelectionTargets(message).length > 0)
		{
			this.setNoSelectionMatchState();
		}
	},
	
	/**
	 * Listener on {@link Ametys.message.Message#MODIFIED} message. If the current
	 * resource is concerned, the tool will be out-of-date.
	 * @param {Ametys.message.Message} message The modified message.
	 * @protected
	 */
	_onModified: function (message)
	{
		if (this.getTargetsInCurrentSelectionTargets(message).length > 0)
		{
			this.showOutOfDate();
		}
	},
	
	/**
	 * Download a version of the current resource
	 * @param {String} version The version name to download
	 */
	downloadVersion: function(version)
	{
		var args = {
            'id': this._resourceId,
		    'version': version,
		    'download': "true"
        }
		
        Ametys.openWindow(Ametys.getPluginDirectPrefix('explorer') + '/resource', args);
	},
	
	/**
	 * Perform a restoration of a version of the current resource.
	 * @param {String} version The version name to restore
	 */
	restoreVersion: function(version)
	{
		var me = this;
		var id = this._resourceId;
		
		Ametys.Msg.confirm("{{i18n PLUGINS_EXPLORER_FILE_HISTORY_RESTORE_REVISION}}",
			"{{i18n PLUGINS_EXPLORER_FILE_HISTORY_RESTORE_REVISION_CONFIRM}}",
			function (btn) {
				if (btn == 'yes')
				{
					Ametys.data.ServerComm.callMethod({
						role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO', 
						methodName: 'restoreResource',
						parameters: [id, version],
						callback: {
							handler: me._restoreVersionCb,
							scope: me,
						},
						waitMessage: true,
						errorMessage: "{{i18n PLUGINS_EXPLORER_FILE_HISTORY_RESTORE_REVISION_ERROR}}"
					});
				}
			}, 
			this);
	},
	
	/**
	 * @private
	 * Callback function invoked after restore
	 * @param {Object} response The server response
	 */
	_restoreVersionCb: function (response)
	{
		Ext.create("Ametys.message.Message", {
			type: Ametys.message.Message.MODIFIED,
			
			targets: {
				id: Ametys.message.MessageTarget.RESOURCE,
				parameters: { ids: [this._resourceId] }
			}
		});
	}
});