/*
 *  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.
 */

if (!Ametys.getObjectByName('Ametys.plugins.cart.relations.AddToCartRelationHandler'))
{	// If statement is important to protect against undesired double define
	
	/**
	 * This is a relation handler between:
	 * * source : content or ressource
	 * * destination : cart
	 *
	 * It will add the contents and resources to the cart
	 * @private
	 */
	Ext.define('Ametys.plugins.cart.relations.AddToCartRelationHandler', {
		extend: 'Ametys.relation.RelationHandler',
		
	    statics: {
	        /**
	         * Add an allowed target id.
	         * @param {String} targetId The target id to allow
	         */
	        addAllowedTargetId: function(targetId)
	        {
	            if (!Ext.Array.contains(this._allowedTargetIds, targetId))
	            {
	                this._allowedTargetIds.push(targetId);
	            }
	        },
	        
	        /**
	         * @protected
	         * @property {String[]} allowedTargetIds The array of allowed target ids.
	         * @static
	         */
	        _allowedTargetIds: []
	    },
	    
		/**
		 * @private
		 * True if the target is matching one of the allowed type.
		 * @param {Object/Ametys.message.MessageTarget} target The target to test
		 * @return {Boolean} True if the target is matching one of the #allowedTargetTypes
		 */
		_matching: function(target)
		{
			return Ext.Array.findBy(this.statics()._allowedTargetIds, function(id) {
				var targetId = target.isMessageTarget ? target.getId() : target.id;
				return targetId === id;
			}) != null;
		},
		
		/**
		 * @private
		 * True if the target is not matching one of the allowed type.
		 * @param {Object/Ametys.message.MessageTarget} target The target to test
		 * @return {Boolean} True if the target type does not match #targetId
		 */
		_nonMatching: function(target)
		{
			return !this._matching(target);
		},
		
		supportedRelations: function(source, target)
		{
			// Are source contents/resources and only contents/resources ?
			var sourceTargets = Ametys.message.MessageTargetHelper.findTargets(source.targets, Ext.bind(this._matching, this), 1);
			if (sourceTargets.length == 0 || Ametys.message.MessageTargetHelper.findTargets(source.targets, Ext.bind(this._nonMatching, this)).length > 0)
			{
				return [];
			}
	
			// Are target a single content ?
			var destTargets = Ametys.message.MessageTargetHelper.findTargets(target.targets, "cart", 1);
			if (destTargets.length != 1 || Ametys.message.MessageTargetHelper.findTargets(target.targets, /.*/).length != 1)
			{
				return [];
			}
			
			return [
			        Ext.create('Ametys.relation.Relation', {
						type: Ametys.relation.Relation.REFERENCE,
						label: "{{i18n PLUGINS_CART_RELATIONS_ADDTOCART_REFERENCE_LABEL}}",
						description: "{{i18n PLUGINS_CART_RELATIONS_ADDTOCART_REFERENCE_DESCRIPTION}}",
						smallIcon: null,
						mediumIcon: null,
						largeIcon: null
			        })
			];
		},
	
		link: function(source, target, callback, relationType)
		{
			var cartId = target.getTarget().getParameters()['id']; 	
			
			var contentIds = [];
			var contentTitles = [];
			var resourceIds = [];
			var resourceNames = [];
	
			var sourceTargets = Ametys.message.MessageTargetHelper.findTargets(source.targets, Ext.bind(this._matching, this), 1);
			for (var i = 0; i < sourceTargets.length; i++)
			{
				var sourceTarget = sourceTargets[i];
				
				switch (sourceTarget.getId())
				{
					case 'content':
						contentIds.push(sourceTarget.getParameters()['id']);
						contentTitles.push(sourceTarget.getParameters()['title']);
						break;
					case 'resource':
						resourceIds.push(sourceTarget.getParameters()['id']);
						resourceNames.push(sourceTarget.getParameters()['name']);
						break;
					default:
				}
			}
			
			if (contentIds.length > 0 || resourceIds.length > 0)
			{
				Ametys.Msg.confirm("{{i18n PLUGINS_CART_RELATIONS_ADDTOCART_REFERENCE_CONFIRM_TITLE}}",
						"{{i18n PLUGINS_CART_RELATIONS_ADDTOCART_REFERENCE_CONFIRM_TEXT1}}" + contentTitles.concat(resourceNames).join(", ") + "{{i18n PLUGINS_CART_RELATIONS_ADDTOCART_REFERENCE_CONFIRM_TEXT2}}",
						Ext.bind(this._confirmLinkCb, this, [cartId, contentIds, resourceIds, callback], 1));
			}
		},
		
		/**
		 * @private
		 * Callback function invoked after the confirm box is closed
		 * @param {String} buttonId The id of the button pressed. If 'yes' the drag and drop will be effective.
		 * @param {String} cartId The id of cart
		 * @param {String[]} contentIds The ids of contents to add
		 * @param {String[]} resourceIds The ids of resources to add
		 * @param {Function} callback The callback function to call after adding
		 */
		_confirmLinkCb: function (buttonId, cartId, contentIds, resourceIds, callback)
		{
			if (buttonId == 'yes')
			{
				if (contentIds.length > 0)
				{
					Ametys.plugins.cart.actions.CartsActions.addElementsToCart(cartId, 'content', {ids: contentIds}, callback);
				}
				if (resourceIds.length > 0)
				{
					Ametys.plugins.cart.actions.CartsActions.addElementsToCart(cartId, 'resource', {ids: resourceIds}, callback);
				}
			}
		}
	});
}