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

#include "gedit-code-comment-view-activatable.h"
#include <glib/gi18n.h>
#include <gedit/gedit-view.h>
#include <gedit/gedit-view-activatable.h>

struct _GeditCodeCommentViewActivatablePrivate
{
	GeditView *view;
};

enum
{
	PROP_0,
	PROP_VIEW
};

static void gedit_view_activatable_iface_init (GeditViewActivatableInterface *iface);

G_DEFINE_DYNAMIC_TYPE_EXTENDED (GeditCodeCommentViewActivatable,
				gedit_code_comment_view_activatable,
				G_TYPE_OBJECT,
				0,
				G_ADD_PRIVATE_DYNAMIC (GeditCodeCommentViewActivatable)
				G_IMPLEMENT_INTERFACE_DYNAMIC (GEDIT_TYPE_VIEW_ACTIVATABLE,
							       gedit_view_activatable_iface_init))

static void
gedit_code_comment_view_activatable_get_property (GObject    *object,
						  guint       prop_id,
						  GValue     *value,
						  GParamSpec *pspec)
{
	GeditCodeCommentViewActivatable *activatable = GEDIT_CODE_COMMENT_VIEW_ACTIVATABLE (object);

	switch (prop_id)
	{
		case PROP_VIEW:
			g_value_set_object (value, activatable->priv->view);
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}

static void
gedit_code_comment_view_activatable_set_property (GObject      *object,
						  guint         prop_id,
						  const GValue *value,
						  GParamSpec   *pspec)
{
	GeditCodeCommentViewActivatable *activatable = GEDIT_CODE_COMMENT_VIEW_ACTIVATABLE (object);

	switch (prop_id)
	{
		case PROP_VIEW:
			g_assert (activatable->priv->view == NULL);
			activatable->priv->view = GEDIT_VIEW (g_value_dup_object (value));
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
			break;
	}
}

static void
gedit_code_comment_view_activatable_dispose (GObject *object)
{
	GeditCodeCommentViewActivatable *activatable = GEDIT_CODE_COMMENT_VIEW_ACTIVATABLE (object);

	g_clear_object (&activatable->priv->view);

	G_OBJECT_CLASS (gedit_code_comment_view_activatable_parent_class)->dispose (object);
}

static void
gedit_code_comment_view_activatable_class_init (GeditCodeCommentViewActivatableClass *klass)
{
	GObjectClass *object_class = G_OBJECT_CLASS (klass);

	object_class->get_property = gedit_code_comment_view_activatable_get_property;
	object_class->set_property = gedit_code_comment_view_activatable_set_property;
	object_class->dispose = gedit_code_comment_view_activatable_dispose;

	g_object_class_override_property (object_class, PROP_VIEW, "view");
}

static void
gedit_code_comment_view_activatable_class_finalize (GeditCodeCommentViewActivatableClass *klass)
{
}

static void
gedit_code_comment_view_activatable_init (GeditCodeCommentViewActivatable *activatable)
{
	activatable->priv = gedit_code_comment_view_activatable_get_instance_private (activatable);
}

static void
populate_popup_cb (GtkTextView                     *text_view,
		   GtkWidget                       *popup,
		   GeditCodeCommentViewActivatable *self)
{
	GtkMenuShell *menu;
	GtkWidget *item;

	if (!GTK_IS_MENU_SHELL (popup))
	{
		return;
	}

	menu = GTK_MENU_SHELL (popup);

	item = gtk_separator_menu_item_new ();
	gtk_widget_show (item);
	gtk_menu_shell_append (menu, item);

	item = gtk_menu_item_new_with_mnemonic (_("Co_mment Code"));
	gtk_actionable_set_action_name (GTK_ACTIONABLE (item), "win.code-comment-plugin-comment");
	gtk_widget_show (item);
	gtk_menu_shell_append (menu, item);

	item = gtk_menu_item_new_with_mnemonic (_("U_ncomment Code"));
	gtk_actionable_set_action_name (GTK_ACTIONABLE (item), "win.code-comment-plugin-uncomment");
	gtk_widget_show (item);
	gtk_menu_shell_append (menu, item);
}

static void
gedit_code_comment_view_activatable_activate (GeditViewActivatable *activatable)
{
	GeditCodeCommentViewActivatable *self = GEDIT_CODE_COMMENT_VIEW_ACTIVATABLE (activatable);

	g_signal_connect_object (self->priv->view,
				 "populate-popup",
				 G_CALLBACK (populate_popup_cb),
				 self,
				 G_CONNECT_DEFAULT);
}

static void
gedit_code_comment_view_activatable_deactivate (GeditViewActivatable *activatable)
{
	GeditCodeCommentViewActivatable *self = GEDIT_CODE_COMMENT_VIEW_ACTIVATABLE (activatable);

	g_signal_handlers_disconnect_by_func (self->priv->view, populate_popup_cb, self);
}

static void
gedit_view_activatable_iface_init (GeditViewActivatableInterface *iface)
{
	iface->activate = gedit_code_comment_view_activatable_activate;
	iface->deactivate = gedit_code_comment_view_activatable_deactivate;
}

void
gedit_code_comment_view_activatable_register (PeasObjectModule *module)
{
	gedit_code_comment_view_activatable_register_type (G_TYPE_MODULE (module));

	peas_object_module_register_extension_type (module,
						    GEDIT_TYPE_VIEW_ACTIVATABLE,
						    GEDIT_TYPE_CODE_COMMENT_VIEW_ACTIVATABLE);
}
