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

/**
 * SECTION:prefs
 * @title: GtexPrefs
 * @short_description: For the preferences dialog
 *
 * Functions for the preferences dialog.
 */

#include "gtex-prefs.h"
#include <gspell/gspell.h>
#include <glib/gi18n.h>
#include "gtex-settings.h"

/* Returns: (transfer floating): the #GtkWidget for the Font and Colors tab. */
static GtkWidget *
create_font_and_colors_component (void)
{
	GtexSettings *settings;
	GSettings *editor_settings;
	GtkWidget *vgrid;
	TeplStyleSchemeChooserSimple *style_scheme_chooser;
	GtkWidget *style_scheme_component;

	settings = gtex_settings_get_singleton ();
	editor_settings = gtex_settings_peek_editor_settings (settings);

	vgrid = gtk_grid_new ();
	gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL);
	gtk_grid_set_row_spacing (GTK_GRID (vgrid), 18);
	g_object_set (vgrid,
		      "margin", 8,
		      NULL);

	gtk_container_add (GTK_CONTAINER (vgrid),
			   tepl_prefs_create_font_component (editor_settings,
							     "use-default-font",
							     "editor-font"));

	style_scheme_chooser = tepl_style_scheme_chooser_simple_new (FALSE);
	g_settings_bind (editor_settings, "style-scheme-for-light-theme-variant",
			 style_scheme_chooser, "style-scheme-id",
			 G_SETTINGS_BIND_DEFAULT);

	style_scheme_component = tepl_utils_get_titled_component (_("Color Scheme"),
								  GTK_WIDGET (style_scheme_chooser));
	gtk_container_add (GTK_CONTAINER (vgrid), style_scheme_component);

	return vgrid;
}

/* Returns: (transfer floating): the #GtkWidget for the Editor tab. */
static GtkWidget *
create_editor_component (void)
{
	GtexSettings *settings;
	GSettings *editor_settings;
	GtkContainer *vgrid;
	GtkWidget *widget;

	settings = gtex_settings_get_singleton ();
	editor_settings = gtex_settings_peek_editor_settings (settings);

	vgrid = GTK_CONTAINER (gtk_grid_new ());
	gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL);
	g_object_set (vgrid,
		      "margin", 8,
		      NULL);

	widget = tepl_prefs_create_display_line_numbers_checkbutton (editor_settings,
								     "display-line-numbers");
	gtk_container_add (vgrid, widget);

	widget = tepl_prefs_create_tab_width_spinbutton (editor_settings,
							 "tabs-size");
	gtk_widget_set_margin_top (widget, 6);
	gtk_container_add (vgrid, widget);

	widget = tepl_prefs_create_insert_spaces_component (editor_settings,
							    "insert-spaces",
							    "forget-no-tabs");
	gtk_widget_set_margin_top (widget, 6);
	gtk_container_add (vgrid, widget);

	widget = tepl_prefs_create_highlighting_component (editor_settings,
							   "highlight-current-line",
							   "bracket-matching");
	gtk_widget_set_margin_top (widget, 18);
	gtk_container_add (vgrid, widget);

	widget = tepl_prefs_create_files_component (editor_settings,
						    "create-backup-copy",
						    "auto-save",
						    "auto-save-interval");
	gtk_widget_set_margin_top (widget, 18);
	gtk_container_add (vgrid, widget);

	// Extra item to the Files component.
	widget = tepl_prefs_create_checkbutton_simple (editor_settings,
						       "reopen-files",
						       _("Re_open files on startup"));
	gtk_widget_set_margin_top (widget, 6);
	gtk_widget_set_margin_start (widget, 12);
	gtk_container_add (vgrid, widget);

	return GTK_WIDGET (vgrid);
}

static GtkWidget *
create_interactive_completion_component (void)
{
	GtexSettings *settings;
	GSettings *latex_settings;
	guint32 min = 0;
	guint32 max = 0;
	gboolean success;
	GtkWidget *checkbutton;
	GtkWidget *label;
	GtkWidget *spinbutton;
	GtkWidget *vgrid;
	GtkWidget *hgrid;

	settings = gtex_settings_get_singleton ();
	latex_settings = gtex_settings_peek_latex_settings (settings);

	success = tepl_settings_get_range_uint (latex_settings, "interactive-completion-num", &min, &max);
	g_return_val_if_fail (success, NULL);

	/* Widgets */

	checkbutton = tepl_prefs_create_checkbutton_simple (latex_settings,
							    "interactive-completion",
							    _("_Interactive completion"));

	label = gtk_label_new_with_mnemonic (_("_Number of characters after “\\” to trigger the interactive completion:"));
	spinbutton = gtk_spin_button_new_with_range (min, max, 1.0);
	gtk_label_set_mnemonic_widget (GTK_LABEL (label), spinbutton);

	g_settings_bind (latex_settings, "interactive-completion-num",
			 spinbutton, "value",
			 G_SETTINGS_BIND_DEFAULT);

	/* Packing */

	vgrid = gtk_grid_new ();
	gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL);
	gtk_grid_set_row_spacing (GTK_GRID (vgrid), 7);
	gtk_container_add (GTK_CONTAINER (vgrid), checkbutton);

	hgrid = gtk_grid_new ();
	gtk_grid_set_column_spacing (GTK_GRID (hgrid), 6);
	gtk_widget_set_margin_start (hgrid, 12);
	gtk_container_add (GTK_CONTAINER (hgrid), label);
	gtk_container_add (GTK_CONTAINER (hgrid), spinbutton);
	gtk_container_add (GTK_CONTAINER (vgrid), hgrid);

	/* Sensitivity */

	g_object_bind_property (checkbutton, "active",
				hgrid, "sensitive",
				G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);

	return vgrid;
}

static GtkWidget *
create_spell_checking_component (void)
{
	GtexSettings *settings;
	GSettings *editor_settings;
	gchar *markup;
	GtkWidget *label_title;
	GtkWidget *label_language;
	GtkWidget *language_chooser_button;
	GtkWidget *checkbutton;
	GtkWidget *vgrid;
	GtkWidget *hgrid;

	settings = gtex_settings_get_singleton ();
	editor_settings = gtex_settings_peek_editor_settings (settings);

	markup = g_strdup_printf ("<b>%s</b>", _("Default Spell-Checking Settings"));
	label_title = gtk_label_new (NULL);
	gtk_label_set_markup (GTK_LABEL (label_title), markup);
	gtk_widget_set_halign (label_title, GTK_ALIGN_START);
	gtk_widget_set_tooltip_text (label_title,
				     _("The spell-checking settings can also be changed "
				       "on a file-by-file basis via the Tools menu."));
	g_free (markup);

	label_language = gtk_label_new_with_mnemonic (_("_Language:"));
	language_chooser_button = gspell_language_chooser_button_new (NULL);
	gtk_label_set_mnemonic_widget (GTK_LABEL (label_language), language_chooser_button);

	g_settings_bind (editor_settings, "spell-checking-language",
			 language_chooser_button, "language-code",
			 G_SETTINGS_BIND_DEFAULT);

	checkbutton = tepl_prefs_create_checkbutton_simple (editor_settings,
							    "highlight-misspelled-words",
							    _("_Highlight misspelled words"));

	/* Packing */

	vgrid = gtk_grid_new ();
	gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL);
	gtk_grid_set_row_spacing (GTK_GRID (vgrid), 6);
	gtk_container_add (GTK_CONTAINER (vgrid), label_title);

	hgrid = gtk_grid_new ();
	gtk_grid_set_column_spacing (GTK_GRID (hgrid), 12);
	gtk_widget_set_margin_start (hgrid, 12);
	gtk_container_add (GTK_CONTAINER (hgrid), label_language);
	gtk_container_add (GTK_CONTAINER (hgrid), language_chooser_button);
	gtk_container_add (GTK_CONTAINER (vgrid), hgrid);

	gtk_widget_set_margin_start (checkbutton, 12);
	gtk_container_add (GTK_CONTAINER (vgrid), checkbutton);

	return vgrid;
}

static GtkWidget *
create_file_cleanup_component (void)
{
	GtexSettings *settings;
	GSettings *latex_settings;
	GtkWidget *no_confirm_checkbutton;
	GtkWidget *auto_clean_checkbutton;
	GtkWidget *entry;
	GtkWidget *vgrid;

	settings = gtex_settings_get_singleton ();
	latex_settings = gtex_settings_peek_latex_settings (settings);

	no_confirm_checkbutton = tepl_prefs_create_checkbutton_simple (latex_settings,
								       "no-confirm-clean",
								       _("N_o confirmation when cleaning-up"));
	auto_clean_checkbutton = tepl_prefs_create_checkbutton_simple (latex_settings,
								       "automatic-clean",
								       _("_Automatically clean-up files after close"));

	entry = gtk_entry_new ();
	gtk_widget_set_hexpand (entry, TRUE);
	g_settings_bind (latex_settings, "clean-extensions",
			 entry, "text",
			 G_SETTINGS_BIND_DEFAULT);

	/* Sensitivity */

	g_object_bind_property (no_confirm_checkbutton, "active",
				auto_clean_checkbutton, "sensitive",
				G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);

	/* Packing */

	vgrid = gtk_grid_new ();
	gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL);
	gtk_grid_set_row_spacing (GTK_GRID (vgrid), 6);
	gtk_container_add (GTK_CONTAINER (vgrid), no_confirm_checkbutton);
	gtk_widget_set_margin_start (auto_clean_checkbutton, 12);
	gtk_container_add (GTK_CONTAINER (vgrid), auto_clean_checkbutton);
	gtk_container_add (GTK_CONTAINER (vgrid), entry);

	return tepl_utils_get_titled_component (_("File Clean-Up"), vgrid);
}

/* Returns: (transfer floating): the #GtkWidget for the Other tab. */
static GtkWidget *
create_other_component (void)
{
	GtkWidget *vgrid;

	vgrid = gtk_grid_new ();
	gtk_orientable_set_orientation (GTK_ORIENTABLE (vgrid), GTK_ORIENTATION_VERTICAL);
	gtk_grid_set_row_spacing (GTK_GRID (vgrid), 18);
	g_object_set (vgrid,
		      "margin", 8,
		      NULL);

	gtk_container_add (GTK_CONTAINER (vgrid),
			   create_interactive_completion_component ());

	gtk_container_add (GTK_CONTAINER (vgrid),
			   create_spell_checking_component ());

	gtk_container_add (GTK_CONTAINER (vgrid),
			   create_file_cleanup_component ());

	return vgrid;
}

/* Returns: (transfer floating): the #GtkNotebook for the preferences dialog. */
static GtkNotebook *
create_notebook (void)
{
	GtkNotebook *notebook;

	notebook = GTK_NOTEBOOK (gtk_notebook_new ());
	gtk_notebook_set_scrollable (notebook, TRUE);
	gtk_notebook_set_show_border (notebook, FALSE);

	gtk_notebook_append_page (notebook,
				  create_editor_component (),
				  gtk_label_new (_("Editor")));

	gtk_notebook_append_page (notebook,
				  create_font_and_colors_component (),
				  gtk_label_new (_("Font & Colors")));

	gtk_notebook_append_page (notebook,
				  create_other_component (),
				  gtk_label_new (_("Other")));

	gtk_widget_show_all (GTK_WIDGET (notebook));
	gtk_notebook_set_current_page (notebook, 0);
	return notebook;
}

static void
reset_all_cb (TeplPrefsDialog *prefs_dialog,
	      gpointer         user_data)
{
	tepl_settings_reset_all ("org.gnome.enter_tex.preferences.editor");
	tepl_settings_reset_all ("org.gnome.enter_tex.preferences.latex");
}

/**
 * gtex_prefs_fill_dialog:
 * @dialog: a #TeplPrefsDialog.
 *
 * Fills @dialog with the preferences widgets for this app.
 */
void
gtex_prefs_fill_dialog (TeplPrefsDialog *dialog)
{
	GtkBox *content_area;

	g_return_if_fail (TEPL_IS_PREFS_DIALOG (dialog));

	tepl_prefs_dialog_add_reset_all_button (dialog);
	g_signal_connect (dialog,
			  "reset-all",
			  G_CALLBACK (reset_all_cb),
			  NULL);

	content_area = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
	gtk_box_pack_start (content_area,
			    GTK_WIDGET (create_notebook ()),
			    TRUE, TRUE, 0);
}
