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

/**
 * Singleton class to handle actions on skins.
 * @private
 */
Ext.define('Ametys.plugins.web.skin.SkinActions', {
    singleton : true,


    /**
     * Action called by the controller to import a new skin
     */
	'import': function ()
	{
		Ametys.plugins.web.skin.helper.ImportSkinUI.open({
			url: Ametys.getPluginDirectPrefix("web") + '/administrator/skin/upload',
			title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_IMPORT_ZIP}}",
			helpMsg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_IMPORT_DIALOG_HINT}}",
			importFn: Ext.bind (this._doImport, this),
			existFn: Ametys.plugins.web.skin.SkinDAO.skinExists
		});
	},
	
	/**
	 * Import the uploaded skin
	 * @param {Object} result the upload result
	 */
	_doImport: function (result)
	{
		if (result.hasConfig)
        {
			// Open configuration tool
			Ametys.tool.ToolsManager.openTool('uitool-skin-config', {id: result.skinName, tempDir: result.tempDir, skinDir: result.skinDir});
        }
        else
        {
        	var skinPath = result.tempDir + "/" + result.skinDir;
        	Ametys.plugins.web.skin.SkinDAO.importSkin([result.skinName, skinPath, {}, null], null, { waitMessage: true });
        }
			
	},

    /**
     * Action called by the controller to export the selected skin
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the function
     */
	'export': function (controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets.length > 0)
		{
			var url = Ametys.getPluginDirectPrefix('web') + "/administrator/skin/export/" + targets[0].getParameters().name + ".zip";
			window.open(url);
		}
	},
	
	/**
	 * Configure the selected skin
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the function
	 */
	configure: function (controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets.length > 0)
		{
			// Open configuration tool
			Ametys.tool.ToolsManager.openTool('uitool-skin-config', {id: targets[0].getParameters().name});
		}
	},

    /**
     * Action called by the controller to duplicate the selected skin
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the function
     */
	duplicate: function (controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets.length > 0)
		{
			Ametys.plugins.web.skin.helper.CopySkinUI.open(targets[0].getParameters().name);
		}
	},

    /**
     * Action called by the skin menu to duplicate a skin
     */
	menuDuplicate: function ()
	{
        Ametys.plugins.web.skin.helper.CopySkinUI.open();
	},

    /**
     * Action called by the controller to delete the selected skin
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling the function
     */
	'delete': function (controller)
	{
		var targets = controller.getMatchingTargets();
		if (targets.length > 0)
		{
			// Check first if skin is in use
			Ametys.plugins.web.skin.SkinDAO.isInUse([ targets[0].getParameters().name ], this._isInUseCb, {scope: this, arguments: {target: targets[0]}});
		}
	},
	
	/**
	 * @private
	 * Callback function invoked after testing if skin is in use before deleting it
	 * @param {Boolean} isInUse true if the skin is currently in use
	 * @param {Object} args the callback arguments
	 * @param {Ametys.message.MessageTarget} args.target The skin target
	 */
	_isInUseCb: function (isInUse, args)
	{
		if (args.target.getParameters().isExtended)
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_DELETE}}",
                msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_DELETE_SKIN_EXTENDED}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
        else if (!isInUse)
		{
			Ametys.Msg.confirm("{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_DELETE}}",
					"{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_DELETE_WARNING}}",
					Ext.bind(this._confirmDelete, this, [ args.target ], 1),
					this
			);
		}
		else
		{
			// A skin currently in use can not be deleted
			Ametys.Msg.show({
	    		title: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_DELETE}}",
	    		msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_HANDLE_DELETE_SKIN_IN_USE}}",
	    		buttons: Ext.Msg.OK,
	    		icon: Ext.MessageBox.ERROR
	    	});
		}
	},

	/**
	 * The callback function invoked after the confirm box for delete process is closed
	 * @param {String} answer The answer to the {#Ametys.Msg.confirm} dialog
	 * @param {Ametys.message.MessageTarget} target The skin target to delete
	 * @private
	 */
	_confirmDelete: function (answer, target)
	{
		if (answer == 'yes')
		{
			Ametys.plugins.web.skin.SkinDAO.deleteSkin([ target.getParameters().name, target ], null, {});
		}
	},
	
	/**
	 * Leave the skin configuration without saving
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	unsaveConfig: function (controller)
	{
		var tool = Ametys.tool.ToolsManager.getFocusedTool();
		var mode = tool.getMode();
		
		var confirmMsg = tool.getMode() == 'new' ? "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_UNSAVE_CONFIG_IMPORT_CONFIRM_DESC}}" : "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_UNSAVE_CONFIG_CONFIRM_DESC}}"
		Ametys.Msg.confirm("{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_UNSAVE_CONFIG_CONFIRM_TITLE}}",
				confirmMsg,
				Ext.bind(this._unsaveConfirm, this, [tool], 1),
				this
		);
	},
	
	/**
	 * @private
	 * The callback function invoked after the confirm box for leaving configuration
	 * @param {String} answer The ID of the button pressed
	 * @param {Ametys.tool.Tool} tool The tool to close
	 */
	_unsaveConfirm: function (answer, tool)
	{
		if (answer == 'yes')
		{
			tool.close();
		}
	},
	
	/**
	 * Save the skin configuration
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	saveConfig: function (controller)
	{
		var form = Ametys.form.SaveHelper.getForm(controller.getMatchingTargets());
		if (form != null)
		{
			var tool = Ametys.tool.ToolsManager.getFocusedTool();
			var target = controller.getMatchingTargets()[0];
			var skinName = target.getParameters().name || target.getParameters().id;
			
			Ametys.form.SaveHelper.canSave(form, Ext.bind(this._doSave, this, [tool, form, skinName], 1));
		}
	},
	
	/**
	 * @private
	 * Save the site configuration
	 * @param {Boolean} canSave True if the configuration can be saved
	 * @param {Ametys.tool.Tool} tool The content tool
	 * @param {Ametys.form.ConfigurableFormPanel} form The form panel
	 * @param {String} skinName The skin name
 	 */
	_doSave: function (canSave, tool, form, skinName)
	{
        var values = form.getJsonValues();
		if (tool.getMode() == 'new')
		{
			// Import and configure skin
        	Ametys.plugins.web.skin.SkinDAO.importSkin([skinName, tool.getSkinTempPath(), values, form], this._saveCb, { 
        		scope: this, 
        		waitMessage: {
        			target: tool.getContentPanel(),
					msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_SAVING}}"
        		},
        		arguments: {tool: tool}
        	 });
		}
		else
		{
			// Configure skin
			Ametys.plugins.web.skin.SkinDAO.configureSkin([skinName, values, form], this._saveCb, { 
        		scope: this, 
        		waitMessage: {
        			target: tool.getContentPanel(),
					msg: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_SAVING}}"
        		},
        		arguments: {tool: tool}
        	 });
		}
		
	},
	
	/**
	 * Callback function called after #_doSave is processed.
	 * Fires {@link Ametys.message.Message#MODIFIED} message for edited site
	 * @param {Object} response The XML response provided by the {@link Ametys.data.ServerComm}
	 * @param {Object} params The callback parameters passed to the {@link Ametys.data.ServerComm#send} method :
	 * @param {Ametys.form.ConfigurableFormPanel} params.form The form panel
	 * @private
	 */
	_saveCb: function (response, params)
	{
		if (!response.errors)
		{
			// Close tool
			params.tool.close();
		}
        else
        {
            Ametys.form.SaveHelper.handleServerErrors(params.tool._formPanel, null, null, response.errors);
        }
	}
});