/* SPDX-FileCopyrightText: 2025 - Sébastien Wilmet
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#include "config.h"
#include "gtex-commands-edit.h"
#include <tepl/tepl.h>
#include <glib/gi18n.h>
#include "gtex-buffer.h"

void
_gtex_commands_edit_add_action_infos (GtkApplication *gtk_app)
{
	TeplApplication *tepl_app;
	AmtkActionInfoStore *store;

	const AmtkActionInfoEntry entries[] = {
		/* action, icon, label, accel, tooltip */

		{ "win.edit-comment", NULL, N_("_Comment"), "<Control>m",
		  N_("Comment the selected lines (add the character “%”)") },

		{ "win.edit-uncomment", NULL, N_("_Uncomment"), "<Shift><Control>m",
		  N_("Uncomment the selected lines (remove the character “%”)") },

		{ "win.edit-completion", NULL, N_("_Completion"), "<Control>space",
		  N_("Complete the LaTeX command") },

		{ "app.preferences", "preferences-system", N_("_Preferences"), NULL,
		  N_("Configure the application") },
	};

	g_return_if_fail (GTK_IS_APPLICATION (gtk_app));

	tepl_app = tepl_application_get_from_gtk_application (gtk_app);
	store = tepl_application_get_app_action_info_store (tepl_app);

	amtk_action_info_store_add_entries (store, entries, G_N_ELEMENTS (entries), GETTEXT_PACKAGE);
}

static void
comment_cb (GSimpleAction *action,
	    GVariant      *parameter,
	    gpointer       user_data)
{
	TeplApplicationWindow *tepl_window = TEPL_APPLICATION_WINDOW (user_data);
	TeplView *view;
	TeplCodeCommentView *code_comment_view;

	view = tepl_tab_group_get_active_view (TEPL_TAB_GROUP (tepl_window));
	g_return_if_fail (view != NULL);

	code_comment_view = tepl_code_comment_view_new (GTK_SOURCE_VIEW (view));

	if (tepl_code_comment_view_code_comment_is_supported (code_comment_view))
	{
		tepl_code_comment_view_comment_selected_lines (code_comment_view);
	}

	g_object_unref (code_comment_view);
}

static void
uncomment_cb (GSimpleAction *action,
	      GVariant      *parameter,
	      gpointer       user_data)
{
	TeplApplicationWindow *tepl_window = TEPL_APPLICATION_WINDOW (user_data);
	TeplView *view;
	TeplCodeCommentView *code_comment_view;

	view = tepl_tab_group_get_active_view (TEPL_TAB_GROUP (tepl_window));
	g_return_if_fail (view != NULL);

	code_comment_view = tepl_code_comment_view_new (GTK_SOURCE_VIEW (view));

	if (tepl_code_comment_view_code_comment_is_supported (code_comment_view))
	{
		tepl_code_comment_view_uncomment_selection (code_comment_view);
	}

	g_object_unref (code_comment_view);
}

static void
completion_cb (GSimpleAction *action,
	       GVariant      *parameter,
	       gpointer       user_data)
{
	TeplApplicationWindow *tepl_window = TEPL_APPLICATION_WINDOW (user_data);
	TeplView *view;

	view = tepl_tab_group_get_active_view (TEPL_TAB_GROUP (tepl_window));
	g_return_if_fail (view != NULL);

	g_signal_emit_by_name (view, "show-completion");
}

static const GActionEntry action_entries[] = {
	{ "edit-comment", comment_cb },
	{ "edit-uncomment", uncomment_cb },
	{ "edit-completion", completion_cb },
};

/* TODO: avoid code duplication with gtex-commands-latex.c. */
static void
update_actions_sensitivity (TeplApplicationWindow *tepl_window)
{
	GtkApplicationWindow *gtk_window;
	TeplTab *active_tab;
	gboolean sensitive;
	guint i;

	gtk_window = tepl_application_window_get_application_window (tepl_window);

	active_tab = tepl_tab_group_get_active_tab (TEPL_TAB_GROUP (tepl_window));
	sensitive = active_tab != NULL;

	for (i = 0; i < G_N_ELEMENTS (action_entries); i++)
	{
		const gchar *action_name = action_entries[i].name;
		GAction *action;

		action = g_action_map_lookup_action (G_ACTION_MAP (gtk_window), action_name);
		g_simple_action_set_enabled (G_SIMPLE_ACTION (action), sensitive);
	}
}

static void
active_tab_notify_cb (TeplApplicationWindow *tepl_window,
		      GParamSpec            *pspec,
		      gpointer               user_data)
{
	update_actions_sensitivity (tepl_window);
}

void
_gtex_commands_edit_add_actions (GtkApplicationWindow *gtk_window)
{
	TeplApplicationWindow *tepl_window;

	g_return_if_fail (GTK_IS_APPLICATION_WINDOW (gtk_window));

	tepl_window = tepl_application_window_get_from_gtk_application_window (gtk_window);

	amtk_action_map_add_action_entries_check_dups (G_ACTION_MAP (gtk_window),
						       action_entries,
						       G_N_ELEMENTS (action_entries),
						       tepl_window);

	g_signal_connect (tepl_window,
			  "notify::active-tab",
			  G_CALLBACK (active_tab_notify_cb),
			  NULL);

	update_actions_sensitivity (tepl_window);
}

/**
 * gtex_commands_create_edit_menu:
 * @gtk_window: a #GtkApplicationWindow.
 *
 * Returns: (transfer floating): a new #GtkMenu with the Edit actions.
 */
GtkMenu *
gtex_commands_create_edit_menu (GtkApplicationWindow *gtk_window)
{
	GtkMenuShell *menu;
	AmtkFactory *factory;

	g_return_val_if_fail (GTK_IS_APPLICATION_WINDOW (gtk_window), NULL);

	menu = GTK_MENU_SHELL (gtk_menu_new ());

	factory = amtk_factory_new_with_default_application ();
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "win.tepl-undo"));
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "win.tepl-redo"));
	gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
	tepl_menu_shell_append_edit_actions (menu);
	gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item_full (factory,
									 "win.tepl-indent",
									 AMTK_FACTORY_IGNORE_ACCELS_FOR_APP));
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "win.tepl-unindent"));
	gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "win.edit-comment"));
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "win.edit-uncomment"));
	gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "win.edit-completion"));
	gtk_menu_shell_append (menu, gtk_separator_menu_item_new ());
	gtk_menu_shell_append (menu, amtk_factory_create_menu_item (factory, "app.preferences"));
	g_object_unref (factory);

	return GTK_MENU (menu);
}
