/*
 *  Copyright 2014 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 is a relation handler between:
 * * source : tag
 * * destination : tag or tag provider
 * 
 * E.g. when you drag a tag to another tag
 * @private
 */
Ext.define('Ametys.plugins.cms.relations.DefaultTagsRelationHandler', {
	extend: 'Ametys.relation.RelationHandler',
	
	/**
	 * @protected
	 * @template
	 * Get the tag regexp to match target
	 */
	_getTagRegexp: function()
	{
		return /^tag$/;
	},
	
	/**
	 * @protected
	 * @template
	 * Get the tag root regexp to match target
	 */
	_getTagRootRegexp: function()
	{
		return /^tag(-root)?$/;
	},
	
	/**
	 * @protected
	 * Do the #supportedRelations work but based only on targets array
	 * This method return the list of supported operations between the source and the target points of a relation.
	 * The implementation should only cares about targets and does not have to check upon source and target relations: a later filter is done by the Ametys.relation.RelationManager.
	 * @param {Ametys.message.MessageTarget[]} sourceTargets The source point of the relation operation. Targets are assumed to be ready.
	 * @param {Ametys.message.MessageTarget[]} targetTargets The end point of the relation operation. Targets are assumed to be ready.
	 * @return {Ametys.relation.Relation/Ametys.relation.Relation[]} Returns the supported operations between those two points. The order is important: after filtering that array, the first relation is considered as the default one.
	 */
	_supportedRelations: function(sourceTargets, targetTargets)
	{
		var sourceMatch = Ametys.message.MessageTargetHelper.findTargets(sourceTargets, this._getTagRegexp(), 1);
		if (sourceMatch.length == 0 || sourceMatch.length != sourceTargets.length)
		{
			return [];
		}
		
		var targetMatch = Ametys.message.MessageTargetHelper.findTargets(targetTargets, this._getTagRootRegexp(), 1);
		if (targetMatch.length != 1 || targetTargets.length != 1)
		{
			return [];
		}

		var relations = [ 
		    Ext.create('Ametys.relation.Relation', {
    			type: Ametys.relation.Relation.MOVE,
    			label: "{{i18n PLUGINS_CMS_RELATIONS_DEFAULTTAG_MOVE_LABEL}}",
    			description: "{{i18n PLUGINS_CMS_RELATIONS_DEFAULTTAG_MOVE_DESCRIPTION}}",
    			smallIcon: null,
    			mediumIcon: null,
    			largeIcon: null
    		})
		];
			
		return relations;
	},
	
	supportedRelations: function(source, target)
	{
		return this._supportedRelations(source.targets, target.targets);
	},
	
	/**
	 * @protected
	 * Do the #link work but based only on targets array
	 * The method is called to link source to target using the given relation. 
	 * This operation can be asynchronous and will call callback at the end.
	 * In most cases this implementation will send a Ametys.message.Message to inform the UI that the operation was done.
	 * @param {Ametys.message.MessageTarget[]} sourceTargets The source point of the link operation. Targets are assumed to be ready.
	 * @param {Ametys.message.MessageTarget} target The end point of the link operation. Targets are assumed to be ready.
	 * @param {Function} callback The callback to call when operation has ended. 
	 * @param {Boolean} callback.success True if the operation was successful
	 */
	_link: function(sourceTargets, target, callback)
	{
		var sourceIds = [];
		Ext.Array.forEach(Ametys.message.MessageTargetHelper.findTargets(sourceTargets, this._getTagRegexp(), 1), function(target) {
			sourceIds.push(target.getParameters().id);
		});
		
		Ametys.plugins.cms.tag.TagHelper.move(
				target.getParameters().id, 
				sourceIds,
				"org.ametys.cms.tag.jcr.JCRTagsDAO",
				Ametys.message.MessageTarget.TAG,
				Ext.bind(this._linkCb, this, [callback], true)
		);
	},
	
	link: function(source, target, callback, relationType)
	{
		this._link(source.getTargets(), target.getTarget(), callback);
	},
	
	/**
	 * @private
	 * Callback of the link operation. That will call the initial callback.
	 * @param {String} target The folder id to move into
	 * @param {String[]} movedTags Tags ids moved effectively
	 * @param {String} targetId The target id
     * @param {Function} callback The callback to call when operation has ended. 
	 * @param {boolean} callback.sucess True if the operation was successful
	 */
	_linkCb: function(target, movedTags, targetId, callback)
	{
		if (movedTags.length > 0)
		{
			var targets = [];
			
			Ext.Array.forEach (movedTags, function (tag) {
				targets.push({
					id: targetId,
					parameters: {
						id: tag.id,
						name: tag.name
					}
				})
			});
			Ext.create("Ametys.message.Message", {
				type: Ametys.message.Message.MOVED,
				
				targets: targets,
				
				parameters: {
					major: true
				}
			});
		}
		
		callback(movedTags.length > 0);
	}
});