/*
 *  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 class provides a view for the file.
 * This is the 'details' view, which is based on a grid panel.
 * @private
 */
Ext.define('Ametys.plugins.explorer.view.DetailsViewer', {
	extend: 'Ext.grid.Panel',
	
	/**
	 * @property {String} _applicationId The application id
	 * @private
	 */
	
	selModel: {
		mode: 'MULTI'
	},
	
	constructor: function(config)
	{
		config.id = config.id || Ext.id();
		
		config.plugins = config.plugins || [];
		config.plugins.push(this._createEditPlugin(config));
		
		config.viewConfig = {};
		config.viewConfig.plugins = [{
			ptype: 'ametysgridviewdragdrop',
			dragTextField: 'name',
			setAmetysDragInfos: Ext.bind(this.getDragInfo, this),
			setAmetysDropZoneInfos: Ext.bind(this.getDropInfo, this)
		}];
		
		this.callParent(arguments);
	},
	
	/**
	 * Set the application id for this view
	 * @param {String} applicationId the application id
	 */
	setApplicationId: function(applicationId)
	{
		this._applicationId = applicationId;
	},
	
	/**
	 * Set the parent id for this view
	 * @param {String} parentId The parent id
	 */
	setParentId: function(parentId)
	{
		this._parentId = parentId;
	},
	
	/**
	 * @private
	 * Create the plugin instance to edit the grid
	 * @param {Object} config The constructor configuration
	 * @return {Ext.grid.plugin.CellEditing} The edit plugin
	 * @fires
	 */
	_createEditPlugin: function(config)
	{
        return Ext.create('Ext.grid.plugin.CellEditing', {
            clicksToEdit: 1,
            editAfterSelect: true,

            silentlyIgnoreInvalid: false,
            
            listeners: {
              'beforeedit': Ext.bind(this._beforeEdit, this),
              'validateedit': Ext.bind(this._beforeComplete, this)
            }
        })
	},
	
	/**
	 * Check right before edition
     * @param {Ext.grid.plugin.CellEditing} editor The editor plugin
     * @param {Object} e An edit event with the following properties:
     * @private
	 */
	_beforeEdit: function(editor, e)
	{
		var record = e.record,
			path = record.get('path');
		
		if (record.get('isModifiable') !== true)
		{
			return false;
		}
		
		// FIXME can rename node could be async...
		if (!Ametys.explorer.ExplorerNodeDAO.canRenameFile(path))
		{
			return false;
		}
	},
	
	/**
	 * Before an edition ends, always cancel the edit and do the rename process manually
	 * @param {Ext.grid.plugin.CellEditing} editor The editor plugin
	 * @param {Object} e An edit event with the following properties:
	 * @private
	 */
	_beforeComplete: function(editor, e)
	{
		if (e.record && e.value && e.originalValue)
		{
			var name = Ext.String.trim(e.value),
				oldName = Ext.String.trim(e.originalValue);
			
			if (name != oldName)
			{
				Ametys.explorer.resources.actions.File.rename(
					e.record.getId(),
					oldName,
					name
				);
			}
		}
		
		// Always cancel the current edit process. Let the file actions handle it.
		return false;
	},
	
	/**
	 * @private
	 * The current edition has to be silently canceled.
	 */
	_doCancelEdition: function()
	{
		this.editingPlugin.suspendEvent('canceledit');
		this.editingPlugin.cancelEdit()
		this.editingPlugin.resumeEvent('canceledit');
	},
	
	/**
	 * @private
	 * This event is thrown by the getDragData to add the 'source' of the drag.
	 * @param {Object} item The default drag data that will be transmitted. You have to add a 'source' item in it: 
	 * @param {Ametys.relation.RelationPoint} item.source The source (in the relation way) of the drag operation. 
	 */
	getDragInfo: function(item)
	{
		var ids = [];
		for (var i = 0; i < item.records.length; i++)
		{
			ids.push(item.records[i].getId());
		}
	
		if (ids.length > 0)
		{
			item.source = {
				relationTypes: [Ametys.relation.Relation.MOVE, Ametys.relation.Relation.COPY, Ametys.relation.Relation.REFERENCE], 
				targets: {
					id: Ametys.message.MessageTarget.RESOURCE,
					parameters: { ids: ids }
				}
			};
		}
	},
	
	/**
	 * @private
	 * This event is thrown before the beforeDrop event and create the target of the drop operation relation.
	 * @param {Ext.data.Model[]} targetRecords The target records of the drop operation.
	 * @param {Object} item The default drag data that will be transmitted. You have to add a 'target' item in it: 
	 * @param {Object} item.target The target (in the relation way) of the drop operation. A Ametys.relation.RelationPoint config. 	 
	 */	
	getDropInfo: function(targetRecords, item)
	{
		if (targetRecords.length == 0)
		{
			item.target = {
				relationTypes: [Ametys.relation.Relation.MOVE], 
				targets: {
					id: Ametys.message.MessageTarget.EXPLORER_COLLECTION,
					parameters: { ids: [this._parentId] }
				}
			};
		}
	}
});