/*
 * This file is part of GNOME LaTeX.
 *
 * Copyright (C) 2015 - 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/>.
 */

#include "latexila-templates-dialogs.h"
#include <glib/gi18n.h>
#include "latexila-templates-common.h"
#include "latexila-templates-default.h"
#include "latexila-templates-personal.h"
#include "latexila-utils.h"

static void
init_open_dialog (GtkDialog   *dialog,
		  GtkTreeView *default_view,
		  GtkTreeView *personal_view)
{
	GtkContainer *hgrid;
	GtkWidget *scrolled_window;
	GtkWidget *component;
	GtkWidget *content_area;

	hgrid = GTK_CONTAINER (gtk_grid_new ());
	gtk_orientable_set_orientation (GTK_ORIENTABLE (hgrid), GTK_ORIENTATION_HORIZONTAL);
	gtk_grid_set_column_spacing (GTK_GRID (hgrid), 10);

	/* Default templates */

	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
	gtk_widget_set_size_request (scrolled_window, 250, 200);

	gtk_container_add (GTK_CONTAINER (scrolled_window),
			   GTK_WIDGET (default_view));

	component = latexila_utils_get_dialog_component (_ ("Default Templates"), scrolled_window);
	gtk_container_add (hgrid, component);

	/* Personal templates */

	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
	gtk_widget_set_size_request (scrolled_window, 250, 200);

	gtk_container_add (GTK_CONTAINER (scrolled_window),
			   GTK_WIDGET (personal_view));

	component = latexila_utils_get_dialog_component (_ ("Personal Templates"), scrolled_window);
	gtk_container_add (hgrid, component);

	content_area = gtk_dialog_get_content_area (dialog);
	gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (hgrid), TRUE, TRUE, 0);
	gtk_widget_show_all (content_area);
}

static void
selection_changed_cb (GtkTreeSelection *selection,
		      GtkTreeSelection *other_selection)
{
	/* Only one item of the two lists can be selected at once. */

	/* We unselect all the items of the other list only if the current list have
	 * an item selected, because when we unselect all the items the "changed"
	 * signal is emitted for the other list, so for the other list this function
	 * is also called but no item is selected so nothing is done and the item
	 * selected by the user is kept selected.
	 */

	if (gtk_tree_selection_count_selected_rows (selection) > 0)
	{
		gtk_tree_selection_unselect_all (other_selection);
	}
}

static void
row_activated_cb (GtkTreeView       *tree_view,
		  GtkTreePath       *path,
		  GtkTreeViewColumn *column,
		  GtkDialog         *dialog)
{
	gtk_dialog_response (dialog, GTK_RESPONSE_OK);
}

/**
 * latexila_templates_dialogs_open:
 * @parent_window: transient parent window of the dialog.
 *
 * Runs a #GtkDialog to create a new document from a template. Only the
 * template's contents is returned.
 *
 * Returns: the template contents, or %NULL if no templates must be opened.
 */
gchar *
latexila_templates_dialogs_open (GtkWindow *parent_window)
{
	GtkDialog *dialog;
	LatexilaTemplatesDefault *default_store;
	LatexilaTemplatesPersonal *personal_store;
	GtkTreeView *default_view;
	GtkTreeView *personal_view;
	GtkTreeSelection *default_selection;
	GtkTreeSelection *personal_selection;
	gint response;
	gchar *contents = NULL;

	g_return_val_if_fail (GTK_IS_WINDOW (parent_window), NULL);

	dialog = g_object_new (GTK_TYPE_DIALOG,
			       "use-header-bar", TRUE,
			       "title", _ ("New File…"),
			       "destroy-with-parent", TRUE,
			       "transient-for", parent_window,
			       NULL);

	gtk_dialog_add_buttons (dialog,
				_ ("_Cancel"), GTK_RESPONSE_CANCEL,
				_ ("_New"), GTK_RESPONSE_OK,
				NULL);

	gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);

	default_store = latexila_templates_default_get_instance ();
	personal_store = latexila_templates_personal_get_instance ();

	default_view = latexila_templates_get_view (GTK_LIST_STORE (default_store));
	personal_view = latexila_templates_get_view (GTK_LIST_STORE (personal_store));

	init_open_dialog (dialog, default_view, personal_view);

	/* Selection: at most one selected template in both GtkTreeViews. */
	default_selection = gtk_tree_view_get_selection (default_view);
	personal_selection = gtk_tree_view_get_selection (personal_view);

	g_signal_connect_object (default_selection,
				 "changed",
				 G_CALLBACK (selection_changed_cb),
				 personal_selection,
				 0);

	g_signal_connect_object (personal_selection,
				 "changed",
				 G_CALLBACK (selection_changed_cb),
				 default_selection,
				 0);

	/* Double-click */
	g_signal_connect (default_view,
			  "row-activated",
			  G_CALLBACK (row_activated_cb),
			  dialog);

	g_signal_connect (personal_view,
			  "row-activated",
			  G_CALLBACK (row_activated_cb),
			  dialog);

	response = gtk_dialog_run (dialog);

	if (response == GTK_RESPONSE_OK)
	{
		GList *selected_rows = NULL;
		GtkTreePath *path;

		if (gtk_tree_selection_count_selected_rows (default_selection) > 0)
		{
			selected_rows = gtk_tree_selection_get_selected_rows (default_selection, NULL);
			g_assert (g_list_length (selected_rows) == 1);

			path = selected_rows->data;
			contents = latexila_templates_default_get_contents (default_store, path);
		}
		else if (gtk_tree_selection_count_selected_rows (personal_selection) > 0)
		{
			selected_rows = gtk_tree_selection_get_selected_rows (personal_selection, NULL);
			g_assert (g_list_length (selected_rows) == 1);

			path = selected_rows->data;
			contents = latexila_templates_personal_get_contents (personal_store, path);
		}
		/* No templates selected. */
		else
		{
			contents = g_strdup ("");
		}

		g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
	}

	gtk_widget_destroy (GTK_WIDGET (dialog));
	return contents;
}

/**
 * latexila_templates_dialogs_create_template:
 * @parent_window: transient parent window of the dialog.
 * @template_contents: the template's contents.
 *
 * Runs a #GtkDialog to create a new template. The template's contents is given.
 * The #GtkDialog asks the template's name and icon.
 */
void
latexila_templates_dialogs_create_template (GtkWindow   *parent_window,
					    const gchar *template_contents)
{
	GtkDialog *dialog;
	GtkBox *content_area;
	GtkEntry *entry;
	GtkWidget *component;
	LatexilaTemplatesDefault *default_store;
	GtkTreeView *default_view;
	GtkWidget *scrolled_window;

	g_return_if_fail (GTK_IS_WINDOW (parent_window));
	g_return_if_fail (template_contents != NULL);

	dialog = g_object_new (GTK_TYPE_DIALOG,
			       "use-header-bar", TRUE,
			       "title", _ ("New Template…"),
			       "destroy-with-parent", TRUE,
			       "transient-for", parent_window,
			       NULL);

	gtk_dialog_add_buttons (dialog,
				_ ("_Cancel"), GTK_RESPONSE_CANCEL,
				_ ("Crea_te"), GTK_RESPONSE_OK,
				NULL);

	gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);

	content_area = GTK_BOX (gtk_dialog_get_content_area (dialog));

	/* Name */
	entry = GTK_ENTRY (gtk_entry_new ());
	gtk_widget_set_hexpand (GTK_WIDGET (entry), TRUE);
	component = latexila_utils_get_dialog_component (_ ("Name of the new template"),
							 GTK_WIDGET (entry));
	gtk_box_pack_start (content_area, component, FALSE, TRUE, 0);

	/* Icon.
	 * Take the default store because it contains all the icons.
	 */
	default_store = latexila_templates_default_get_instance ();
	default_view = latexila_templates_get_view (GTK_LIST_STORE (default_store));

	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_set_size_request (scrolled_window, 400, 200);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
					     GTK_SHADOW_IN);

	gtk_container_add (GTK_CONTAINER (scrolled_window),
			   GTK_WIDGET (default_view));

	component = latexila_utils_get_dialog_component (_ ("Choose an icon"), scrolled_window);
	gtk_box_pack_start (content_area, component, TRUE, TRUE, 0);

	gtk_widget_show_all (GTK_WIDGET (content_area));

	while (gtk_dialog_run (dialog) == GTK_RESPONSE_OK)
	{
		GtkTreeSelection *selection;
		GList *selected_rows;
		GtkTreePath *path;
		GtkTreeIter iter;
		gchar *config_icon_name = NULL;
		const gchar *name = NULL;
		LatexilaTemplatesPersonal *personal_store;
		GError *error = NULL;

		/* If no name specified. */
		if (gtk_entry_get_text_length (entry) == 0)
		{
			continue;
		}

		selection = gtk_tree_view_get_selection (default_view);

		/* If no icons selected. */
		if (gtk_tree_selection_count_selected_rows (selection) == 0)
		{
			continue;
		}

		/* Get config icon name. */
		selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
		g_assert (g_list_length (selected_rows) == 1);

		path = selected_rows->data;

		if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (default_store), &iter, path))
		{
			g_warning ("Create template dialog: invalid path");
			break;
		}

		gtk_tree_model_get (GTK_TREE_MODEL (default_store), &iter,
				    LATEXILA_TEMPLATES_COLUMN_CONFIG_ICON_NAME, &config_icon_name,
				    -1);

		name = gtk_entry_get_text (entry);

		personal_store = latexila_templates_personal_get_instance ();

		latexila_templates_personal_create (personal_store,
						    name,
						    config_icon_name,
						    template_contents,
						    &error);

		g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free);
		g_free (config_icon_name);

		if (error != NULL)
		{
			GtkWidget *error_dialog;

			error_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
							       GTK_DIALOG_MODAL |
							       GTK_DIALOG_DESTROY_WITH_PARENT |
							       GTK_DIALOG_USE_HEADER_BAR,
							       GTK_MESSAGE_ERROR,
							       GTK_BUTTONS_OK,
							       "%s", _ ("Impossible to create the personal template."));

			gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (error_dialog),
								  "%s", error->message);

			gtk_dialog_run (GTK_DIALOG (error_dialog));
			gtk_widget_destroy (error_dialog);

			g_error_free (error);
			continue;
		}

		break;
	}

	gtk_widget_destroy (GTK_WIDGET (dialog));
}
