/*
 * This file is part of GNOME LaTeX.
 *
 * Copyright (C) 2022 - Sébastien Wilmet <swilmet@gnome.org>
 *
 * GNOME LaTeX is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * GNOME LaTeX is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNOME LaTeX.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * SECTION:prefs
 * @title: LatexilaPrefs
 * @short_description: Widgets for the preferences dialog
 *
 * Functions to create widgets for the GNOME LaTeX preferences dialog.
 */

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

static GtkWidget *
create_checkbutton_simple (GSettings   *settings,
			   const gchar *key,
			   const gchar *mnemonic_text)
{
	GtkWidget *checkbutton;

	g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
	g_return_val_if_fail (key != NULL, NULL);

	checkbutton = gtk_check_button_new_with_mnemonic (mnemonic_text);

	g_settings_bind (settings, key,
			 checkbutton, "active",
			 G_SETTINGS_BIND_DEFAULT);

	return checkbutton;
}

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

	settings = latexila_settings_get_singleton ();
	editor_settings = latexila_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"));
	gtk_container_add (GTK_CONTAINER (vgrid),
			   tepl_prefs_create_color_scheme_component (editor_settings,
								     "scheme"));

	return vgrid;
}

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

	settings = latexila_settings_get_singleton ();
	editor_settings = latexila_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 = 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)
{
	LatexilaSettings *settings;
	GSettings *latex_settings;
	guint32 min = 0;
	guint32 max = 0;
	gboolean success;
	GtkWidget *checkbutton;
	GtkWidget *label;
	GtkWidget *spinbutton;
	GtkWidget *vgrid;
	GtkWidget *hgrid;

	settings = latexila_settings_get_singleton ();
	latex_settings = latexila_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 = 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)
{
	LatexilaSettings *settings;
	GSettings *editor_settings;
	gchar *markup;
	GtkWidget *label_title;
	GtkWidget *label_language;
	GtkWidget *language_chooser_button;
	GtkWidget *checkbutton;
	GtkWidget *vgrid;
	GtkWidget *hgrid;

	settings = latexila_settings_get_singleton ();
	editor_settings = latexila_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 = 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)
{
	LatexilaSettings *settings;
	GSettings *latex_settings;
	GtkWidget *no_confirm_checkbutton;
	GtkWidget *auto_clean_checkbutton;
	GtkWidget *entry;
	GtkWidget *vgrid;

	settings = latexila_settings_get_singleton ();
	latex_settings = latexila_settings_peek_latex_settings (settings);

	no_confirm_checkbutton = create_checkbutton_simple (latex_settings,
							    "no-confirm-clean",
							    _("N_o confirmation when cleaning-up"));
	auto_clean_checkbutton = 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;
}

/**
 * latexila_prefs_create_notebook:
 *
 * Returns: (transfer floating): the #GtkNotebook for the preferences dialog.
 */
GtkNotebook *
latexila_prefs_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;
}
