/*
 *  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 is an abstract tool to handle attachments resources of an object.
 * It is derived from the default explorer tool.
 * 
 * You have to implements the following methods: #getNoSelectionMessage, #getOwnerMessageTargetConfiguration, #getRootNodeConfiguration, #getOwnerMessageInfo, #getRightId, #getTargetFilter
 */
Ext.define('Ametys.cms.attach.AttachmentsTool', {
	extend: 'Ametys.plugins.explorer.tool.ExplorerTool',
	
	/**
	 * @private
	 * @property {String} _ownerId The id of attachments' owner
	 */
	
	createPanel: function()
	{
		this._tree = this.callParent(arguments);
		
        return Ext.create('Ext.Panel', {
            border: false,
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            items: [{
                        xtype: 'component',
                        itemId: 'no-selection',
                        style: {
				            textAlign: 'center'
				        },
                        ui: 'tool-hintmessage',
                        html: this.getNoSelectionMessage(),
                        hidden: true
                    },
                    this._tree
            ]
        });
	},
	
	_createTree: function()
	{
		return Ext.create('Ametys.cms.attach.AttachmentsExplorerTree', {
			inlineEditionEnable: true,
			border: false,
			flex: 1,
			
			ignoreFiles: this._treeIgnoreFiles,
			ownerMessageTargetFilter: this.getTargetFilter(),
			rightId: this.getRightId(),
			
			dockedItems: [{
                dock: 'top',
                itemId: 'attach-info',
                ui: 'tool-hintmessage',
                xtype: 'component',
                style: {
                    textAlign: 'center'
                },
                html: ''
            }]
		});
	},
    
    _onBeforeRender: function()
    {
        // Do nothing  
    },
	
	/**
	 * @protected
	 * Get the message when selection is empty
	 * @return {String} the no selection message
	 */
	getNoSelectionMessage: function ()
	{
		throw new Error("The method #getNoSelectionMessage is not implemented in " + this.self.getName());
	},
	
	sendCurrentSelection: function()
	{
		if (this._ownerId != null)
		{
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.SELECTION_CHANGED,
				targets: Ext.apply (this.getOwnerMessageTargetConfiguration(), {subtargets: this._tree.getMessageTargetConfiguration(this._currentNode)})
			});
		}
	},
	
	/**
	 * Get the message target configuration for the attachments' owner
	 * @protected
	 */
	getOwnerMessageTargetConfiguration: function ()
	{
		throw new Error("The method #getOwnerMessageTargetConfiguration is not implemented in " + this.self.getName());
	},
	
	/**
	 * Listener when the selection has changed.
	 * Updates the state of the tool given the incoming message.
	 * @param {Ametys.message.Message} message The selection message
	 */
	_onSelectionChanged: function(message)
	{
		var target = message.getTarget(this.getTargetFilter());
		if (target == null)
		{
			// No selection
			this._setInNoSelectionState();
		}
		else if (!this._isSameOwner(target))
		{
			// Set in out-of-date mode
			this.showOutOfDate(true);
		}
	},
	
	/**
	 * @private
	 * Determines if the current selection target is the same has current owner
	 * @param {Ametys.message.MessageTarget} target The message target to compare with
	 * @return true if the selection is the current owner tree.
	 */
	_isSameOwner: function (target)
	{
		return this._ownerId == target.getParameters().id;
	},
	
    setParams: function (params)
    {
        this.callParent(arguments);
        this.refresh();
    },
    
	refresh: function()
	{
		this.showRefreshing();
		
		var target = Ametys.message.MessageBus.getCurrentSelectionMessage().getTarget(this.getTargetFilter());
		if (target != null)
		{
			this.updateTreeOwner(target);
		}
		else
		{
			this._setInNoSelectionState();
			this.showUpToDate();
		}
	},
	
	/**
	 * Update tree attachments.
	 * @param {Ametys.message.MessageTarget} target The tree owner message target
	 */
	updateTreeOwner: function (target)
	{
		// Show tree
		this._tree.show();
        this.getContentPanel().down("#no-selection").hide();
		
		this._ownerId = target.getParameters().id;
		
		// Update info message
		this._tree.down("#attach-info").update (this.getOwnerMessageInfo(target));
		 
		// Update root node
		this.getRootNodeConfiguration (this._ownerId, Ext.bind(this._getRootNodeCb, this));
	},
	
	/**
	 * @protected
	 * Get the tree root node configuration
	 * @param {String} id The owner tree id
	 * @param {Function} callback Callback function to call after getting root node. Expected parameters are:
	 * @param {Object} callback.rootConfig The root node configuration
	 * @
	 */
	getRootNodeConfiguration: function (id, callback)
	{
		throw new Error("The method #getRootNodeConfiguration is not implemented in " + this.self.getName());
	},
	
	/**
	 * Function called after retrieving root node configuration.
	 * Updates the tree root node.
	 * @param {Object} rootConfig the root configuration
	 * @private
	 */
	_getRootNodeCb: function (rootConfig)
	{
		var rootConfig = Ext.applyIf (rootConfig,
		{
			iconCls: 'ametysicon-clip26',
			allowDrag: false,
			allowDrop: false,
			path: '/dummy/attachments',
			type: 'collection',
			name: 'attachments',
			isModifiable: false,
			canCreateChild: false,
			hasChildNodes: false,
			hasResources: false
		});
		
		this._tree.setRootNodes([rootConfig]);
		this.showUpToDate();
	},
	
	/**
	 * @protected
	 * Get the message information to be displayed on top of the tool
	 * @param {Ametys.message.MessageTarget} target the owner tree target.
	 * @return {String} the info message.
	 */
	getOwnerMessageInfo: function (target)
	{
		throw new Error("The method #getOwnerMessageInfo is not implemented in " + this.self.getName());
	},
	
	/**
	 * @protected
	 * Get the id of right to check before tree edition
	 * @return {String} the right's id
	 */
	getRightId: function ()
	{
		throw new Error("The method #getRightId is not implemented in " + this.self.getName());
	},
	
	/**
	 * Return the target filter to be used on selection message to find the tree owner.
	 * This filter will be used to retrieve target via the {@link Ametys.message.Message#getTarget} method.
	 * @return {String/RegExp/Function} The filter to be used.
	 * See {@link Ametys.message.Message#getTarget} for more details on the possible values to return.
	 * @protected
	 */
	getTargetFilter: function()
	{
		throw new Error("The method #getTargetFilter is not implemented in " + this.self.getName());
	},
	
	/**
	 * @private
	 * Update the status of the tool to the no selection state.
     * @param {String} [message] the message to display in tool. Default to {@link getNoSelectionMessage}
	 */
	_setInNoSelectionState: function(message)
	{
        message = message || this.getNoSelectionMessage();
		this._ownerId = null;
		this._tree.setRootNodes();
        this._tree.hide();
        this.getContentPanel().down("#no-selection").update(message);
		this.getContentPanel().down("#no-selection").show();
        this.showUpToDate();
	}
});