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

/**
 * CRUD actions on carts
 * @private
 */
Ext.define('Ametys.plugins.cart.actions.CartsActions', {
	singleton: true,
	
	/**
	 * This action creates a new cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	newCart: function(controller)
	{
		Ametys.plugins.cart.helper.CreateOrEditCart.act('new', {}, function (cartId) {Ametys.tool.ToolsManager.openTool('uitool-cart', {id: cartId})});
	},
	
	/**
	 * This action edits the selected cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	editCart: function(controller)
	{		
		var targets = controller.getMatchingTargets();
		
		if (targets.length > 0)
		{
			Ametys.plugins.cart.helper.CreateOrEditCart.act("edit", targets[0].getParameters());
		}	
	},
	
	/**
	 * Delete the selected carts
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	deleteCart: function(controller)
	{
		var targets = controller.getMatchingTargets();
		
		if (targets.length > 0)
		{
			Ametys.Msg.confirm("{{i18n PLUGINS_CART_DELETE_CART_TITLE}}", 
					"{{i18n PLUGINS_CART_DELETE_CART_CONFIRM}}", 
					function(btn) {
						if(btn == 'yes')
						{
							this._doDelete(targets);
						}
						
					},
					this);
		}
		
	},
	
	/**
	 * Callback function invoked after the #deleteCart confirm box is validated
	 * @param {Ametys.message.MessageTarget[]} targets The carts targets
	 * @private
	 */
	_doDelete: function (targets)
	{
		var ids = [];
		
		for (var i=0; i < targets.length; i++)
		{
			ids.push(targets[i].getParameters().id);
		}

		Ametys.plugins.cart.CartsDAO.deleteCarts([ids]);
	},
	
	/**
	 * Export selected cart to CSV format
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	exportCsv: function(controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets && targets.length > 0)
		{
			var args = {
                'cartId': targets[0].getParameters().id
            };
            Ametys.openWindow(Ametys.getPluginDirectPrefix('cart') + '/cart/export.csv', args);
		}
	},
	
	/**
	 * Export selected cart to XML format
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	exportXml: function(controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets && targets.length > 0)
		{
			var args = {
                'cartId': targets[0].getParameters().id
            };
            Ametys.openWindow(Ametys.getPluginDirectPrefix('cart') + '/cart/export.xml', args);
		}
	},
	
	/**
	 * Print the selected cart (mode list)
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	printList: function(controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets && targets.length > 0)
		{
			Ametys.openWindow (Ametys.getPluginDirectPrefix('cart') + '/cart/print', {cartId: targets[0].getParameters().id}, 'GET');
		}
	},
	
	/**
	 * Print the selected cart (mode details)
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	printDetails: function(controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets && targets.length > 0)
		{
			Ametys.openWindow (Ametys.getPluginDirectPrefix('cart') + '/cart/print/details', {cartId: targets[0].getParameters().id}, 'GET');
		}
	},
	
	/**
	 * Add contents to an existing cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	addContents: function (controller)
	{
		var targets = controller.getMatchingTargets();
		
		var contentIds = [];
		for (var i = 0; i < targets.length; i++)
		{
	   		contentIds.push(targets[i].getParameters().id);
		}
		
		Ametys.plugins.cart.helper.ChooseCart.act({
			icon: Ametys.getPluginResourcesPrefix('cart') + '/img/actions/add-items_16.png',
			title: "{{i18n PLUGINS_CART_ADD_TO_CART_TITLE}}",
			helpMessage: "{{i18n PLUGINS_CART_ADD_CONTENTS_TO_CART_HINT}}",
			callback: Ext.bind (this.addElementsToCart, this, ['content', {ids: contentIds}], true)
		});
	},
	
	/**
	 * Add contents to a new cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	addContentsToNewCart: function(controller)
	{
		var targets = controller.getMatchingTargets();
		
		var contentIds = [];
		for (var i = 0; i < targets.length; i++)
		{
	   		contentIds.push(targets[i].getParameters().id);
		}
		
		Ametys.plugins.cart.helper.CreateOrEditCart.act('new', {}, Ext.bind (this.addElementsToCart, this, ['content', {ids: contentIds}], true));
	},
	
	/**
	 * Add resources to an existing cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	addResources: function (controller)
	{
		var targets = controller.getMatchingTargets();
		
		var resourcesId = [];
		for (var i = 0; i < targets.length; i++)
		{
			resourcesId.push(targets[i].getParameters().id);
		}
		
		Ametys.plugins.cart.helper.ChooseCart.act({
			icon: Ametys.getPluginResourcesPrefix('cart') + '/img/actions/add-items_16.png',
			title: "{{i18n PLUGINS_CART_ADD_TO_CART_TITLE}}",
			helpMessage: "{{i18n PLUGINS_CART_ADD_RESOURCES_TO_CART_HINT}}",
			callback: Ext.bind (this.addElementsToCart, this, ['resource', {ids: resourcesId}], true)
		});
	},
	
	/**
	 * Add resources to an existing cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	addResourcesToNewCart: function (controller)
	{
		var targets = controller.getMatchingTargets();
		
		var resourcesId = [];
		for (var i = 0; i < targets.length; i++)
		{
			resourcesId.push(targets[i].getParameters().id);
		}
		
		Ametys.plugins.cart.helper.CreateOrEditCart.act('new', {}, Ext.bind (this.addElementsToCart, this, ['resource', {ids: resourcesId}], true));
	},
	
    /**
     * Add query from directory to an existing cart
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    addQueryFromDirectory: function (controller)
    {
        var queryIds = this._getQueryIds(controller);
        Ametys.plugins.cart.helper.ChooseCart.act({
            title: "{{i18n PLUGINS_CART_ADD_TO_CART_TITLE}}",
            helpMessage: "{{i18n PLUGINS_CART_ADD_QUERY_FROM_DIRECTORY_TO_CART_HINT}}",
            callback: Ext.bind (this._addQueryFromDirectoryCB, this, [queryIds], true)
        });
    },
    
    /**
     * Add query from directory to an existing cart
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    addQueryFromDirectoryToNewCart: function (controller)
    {
        var queryIds = this._getQueryIds(controller);
        Ametys.plugins.cart.helper.CreateOrEditCart.act('new', {}, Ext.bind (this._addQueryFromDirectoryCB, this, [queryIds], true));
    },
    
    /**
     * Get query ids from the controller
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @private
     */
    _getQueryIds: function(controller)
    {
        var targets = controller.getMatchingTargets();
        
        var queryIds = [];
        for (var i = 0; i < targets.length; i++)
        {
            var type = targets[i].getParameters().type
            if (type == "simple" || type == "solr" || type == "script" || type == "advanced")
            {
                queryIds.push(targets[i].getParameters().id);
            }
        }
        
        return queryIds;
    },
    
    /**
     * Callback function called after choosing a cart
     * @param {String} cartId The cart id
     * @param {Object} queryIds The query ids
     * @private
     */
    _addQueryFromDirectoryCB: function (cartId, queryIds)
    {
        this.addElementsToCart(cartId, 'cartQueryFromDirectory', {
            queryIds: queryIds
        });
    },
    
	/**
	 * Add query to an existing cart
	 */
	addQuery: function (button)
	{
		var tool = Ametys.tool.ToolsManager.getFocusedTool();
		if (tool.getCurrentSearchParameters)
		{
			Ametys.plugins.cart.helper.ChooseCart.act({
				title: "{{i18n PLUGINS_CART_ADD_TO_CART_TITLE}}",
				helpMessage: "{{i18n PLUGINS_CART_ADD_QUERY_TO_CART_HINT}}",
				callback: Ext.bind (this._chooseCartCb, this, [tool], true)
			});
		}
	},
	
	/**
	 * Add query to an existing cart
	 */
	addQueryToNewCart: function (button)
	{
        var tool = Ametys.tool.ToolsManager.getFocusedTool();
        if (tool.getCurrentSearchParameters)
		{
			Ametys.plugins.cart.helper.CreateOrEditCart.act('new', {}, Ext.bind (this._chooseCartCb, this, [tool], true));
		}
	},
	
	/**
	 * Callback function called after choosing a cart
	 * @param {String} cartId The cart id
	 * @param {Object} tool The search tool
	 * @private
	 */
	_chooseCartCb: function (cartId, tool)
	{
		Ametys.Msg.prompt ("{{i18n PLUGINS_CART_ADD_QUERY_TO_CART_LABEL}}", "{{i18n PLUGINS_CART_ADD_QUERY_TO_CART_QUERY_TITLE}}", Ext.bind(this._enterTitleCb, this, [cartId, tool], true));
	},
	
	/**
	 * Callback function called after entering title
	 * @param {String} buttonId The id of the button pressed
	 * @param {String} text The text
	 * @param {Object} opts The config object passed to prompt dialog.
	 * @param {String} cartId The cart id
	 * @param {Object} tool The search tool
	 * @private
	 */
	_enterTitleCb: function (buttonId, text, opts, cartId, tool)
	{
		if (buttonId == 'ok')
		{
			var toolId = tool.getFactory().getId();
			
			var query = Ext.JSON.encode({
				toolId: tool.getFactory().getId(),
				toolParams: tool.getCurrentSearchParameters(),
				exportParams: tool.getSearchParametersForExport(),
				printUrlPlugin: tool.getPrintUrlPlugin(),
				printUrl: tool.getPrintUrl()
			});
			
			this.addElementsToCart(cartId, 'cartQuery', {
				title: text,
				description: query
			});
		}
	},

	/**
	 * Add elements to the cart
	 * @param cartId The cart id
	 * @param type The type of elements to add
	 * @param elmtParams The parameters of elements to add
	 * @param {Function} callback A extra optional callback function
	 * @param {Boolean} callback.success True if the modification was a success
	 */
	addElementsToCart: function (cartId, type, elmtParams, callback)
	{
		var params = [cartId, type, elmtParams, callback];
		
		Ametys.plugins.cart.CartsDAO.addElements(params, this._addElementsToCartCb, {scope: this});
	},
	
	/**
	 * Function called after adding elements to a cart.
	 * @param {Object} response The response object.
	 * @param {Array} args The callback arguments.
	 * @param {Array} params The parameters.
	 * @private
	 */
	_addElementsToCartCb: function (response, args, params)
	{
	    var callback = params[3];

		// Open cart
		Ametys.tool.ToolsManager.openTool('uitool-cart', {id: response.id});

		if (typeof(callback) == 'function')
		{
			callback(true);
		}
	},
	
	/**
	 * Remove elements from the cart
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	removeCartElements: function (controller)
	{		
		var targets = controller.getMatchingTargets();
		
		if (targets && targets.length > 0)
		{
			var cartId = targets[0].getParameters().id;
			var stargets = targets[0].getSubtargets(/^(content|resource|cartQuery|cartQueryFromDirectory)$/);
			
			if (stargets.length > 0)
			{
				var elmts = [];
				
				for (var i=0; i < stargets.length; i++)
				{
					elmts.push({
						id: stargets[i].getParameters().id,
						type: stargets[i].getId()
					})
				}
				
				if (elmts.length > 0)
				{
					Ametys.Msg.confirm("{{i18n PLUGINS_CART_REMOVE_CARTELEMENT_TITLE}}", 
							"{{i18n PLUGINS_CART_REMOVE_CARTELEMENT_CONFIRM}}", 
							function(btn) {
								if(btn == 'yes')
								{
									this._doRemoveElements(cartId, elmts);
								}
							},
							this);
				}
			}
		}
	},
	
	/**
	 * Removes elements from cart
	 * @param {String} cartId The id of the cart
	 * @param {Object} cartElements The elements to remove
	 * @private
	 */
	_doRemoveElements: function (cartId, cartElements)
	{
		Ametys.plugins.cart.CartsDAO.deleteElements([cartId, cartElements], this._removeElementsCb, {scope: this});
	}
});