/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/***************************************************************************
 *            e-kolab-backend-sync-conflict.c
 *
 *  Fri Feb 20 22:54:05 2012
 *  Copyright  2012  Christian Hilberg
 *  <hilberg@kernelconcepts.de>
 *
 ****************************************************************************/

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */
/*----------------------------------------------------------------------------*/

#include <config.h>

#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib/gi18n-lib.h>

#include "e-kolab-backend-sync-conflict.h"

/*----------------------------------------------------------------------------*/

typedef struct _KolabBackendSyncConflictUIWidgets KolabBackendSyncConflictUIWidgets;
struct _KolabBackendSyncConflictUIWidgets {
	GtkWidget *container;
	/* sub-widgets of container */
	GtkWidget *lbl_folder_name;
	GtkWidget *lbl_local_subject;
	GtkWidget *lbl_local_modtime;
	GtkWidget *lbl_remote_subject;
	GtkWidget *lbl_remote_modtime;
	GSList *radio_group;
	GtkWidget *radio_btn_this_sync;
	GtkWidget *radio_btn_this_session;
	GtkWidget *radio_btn_permanent;
	GtkWidget *radio_btn_ask_again;
	GtkWidget *btn_strategy_newer;
	GtkWidget *btn_strategy_server;
	GtkWidget *btn_strategy_client;
	GtkWidget *btn_strategy_dupe;
};

typedef struct _KolabBackendSyncConflictUIData KolabBackendSyncConflictUIData;
struct _KolabBackendSyncConflictUIData {
	KolabBackendSyncConflictUIWidgets *widgets;
	/* FIXME add payload "data" part here */
};

/* corresponds to sync strategy,
 * maybe we can unify this
 */
enum {
	KOLAB_SYNC_CONFLICT_RESPONSE_NEWER = 0,
	KOLAB_SYNC_CONFLICT_RESPONSE_SERVER,
	KOLAB_SYNC_CONFLICT_RESPONSE_CLIENT,
	KOLAB_SYNC_CONFLICT_RESPONSE_DUPE,
	KOLAB_SYNC_CONFLICT_LAST_RESPONSE,
	KOLAB_SYNC_CONFLICT_RESPONSE_DEFAULT = KOLAB_SYNC_CONFLICT_RESPONSE_NEWER
};

#define KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH 8

/*----------------------------------------------------------------------------*/
/* internal statics (non-UI) */


/*----------------------------------------------------------------------------*/
/* internal statics (UI) */


/*----------------------------------------------------------------------------*/
/* API functions (non-UI) */

/*----------------------------------------------------------------------------*/
/* API functions (UI) */

static KolabBackendSyncConflictUIData*
kolab_backend_sync_conflict_ui_new (void)
{
	KolabBackendSyncConflictUIData *uidata = g_new0 (KolabBackendSyncConflictUIData, 1);
	GtkWidget *content = NULL;
	GtkWidget *ev_box = NULL;
	GtkWidget *frame_info = NULL;
	GtkWidget *frame_take_dur = NULL;
	GtkWidget *frame_take = NULL;
	GtkGrid *grid = NULL;
	GtkWidget *widget = NULL;
	GtkWidget *label = NULL;
	gchar *tmp_str = NULL;
	const guint state_flags = GTK_STATE_FLAG_NORMAL;
	const GdkRGBA color = { 0.933, 0.965, 1.0, 1.0 };
	gint row = 0;

	uidata->widgets = g_new0 (KolabBackendSyncConflictUIWidgets, 1);
	uidata->widgets->container = gtk_dialog_new ();
	gtk_window_set_modal (GTK_WINDOW (uidata->widgets->container), TRUE);
	gtk_window_set_resizable (GTK_WINDOW (uidata->widgets->container), FALSE);
	content = gtk_dialog_get_content_area (GTK_DIALOG (uidata->widgets->container));
	gtk_container_set_border_width (GTK_CONTAINER (content), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);

	/* sync conflict information */
	frame_info = gtk_frame_new (NULL);
	gtk_container_set_border_width (GTK_CONTAINER (frame_info), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
	gtk_container_add (GTK_CONTAINER (content), frame_info);
	ev_box = gtk_event_box_new ();
	gtk_container_set_border_width (GTK_CONTAINER (ev_box), 1);
	gtk_widget_override_background_color (ev_box, state_flags, &color);
	gtk_container_add (GTK_CONTAINER (frame_info), ev_box);
	widget = gtk_label_new (NULL);
	gtk_label_set_text (GTK_LABEL (widget),
	                    _("A synchronization error occured: \nProbably someone modified an entry remotely (i.e. on the server), \nwhich you have also modified locally (i.e. on your client)."));
	gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT);
	gtk_container_add (GTK_CONTAINER (ev_box), widget);

	/* object detail */

	grid = GTK_GRID (gtk_grid_new ());
	gtk_grid_set_row_homogeneous (grid, TRUE);
	gtk_grid_set_row_spacing (grid, 6);
	gtk_grid_set_column_homogeneous (grid, FALSE);
	gtk_grid_set_column_spacing (grid, 6);
	gtk_container_set_border_width (GTK_CONTAINER (grid), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
	/* gtk_container_set_resize_mode (GTK_CONTAINER (grid), GTK_RESIZE_QUEUE); */
	gtk_container_add (GTK_CONTAINER (content), GTK_WIDGET (grid));

	row = 0;

	/* conflict folder name */
	tmp_str = g_strconcat (_("Conflict in folder"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 0, row, 1, 1);
	label = gtk_label_new (NULL /* FIXME add folder path here */);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	uidata->widgets->lbl_folder_name = label;
	gtk_grid_attach (grid, label, 1, row, 1, 1);

	row++;

	/* local object - subject */
	tmp_str = g_strconcat (_("Local entry"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 0, row, 1, 1);
	label = gtk_label_new (NULL /* FIXME add subject here */);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	uidata->widgets->lbl_local_subject = label;
	gtk_grid_attach (grid, label, 1, row, 1, 1);

	row++;

	/* local object - last modified */
	tmp_str = g_strconcat (_("Last modified"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 0, row, 1, 1);
	label = gtk_label_new (NULL /* FIXME add modtime here */);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	uidata->widgets->lbl_local_modtime = label;
	gtk_grid_attach (grid, label, 1, row, 1, 1);

	row++;

	/* remote object - subject */
	tmp_str = g_strconcat (_("Remote entry"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 0, row, 1, 1);
	label = gtk_label_new (NULL /* FIXME add subject here */);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	uidata->widgets->lbl_remote_subject = label;
	gtk_grid_attach (grid, label, 1, row, 1, 1);

	row++;

	/* remote object - last modified */
	tmp_str = g_strconcat (_("Last modified"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 0, row, 1, 1);
	label = gtk_label_new (NULL /* FIXME add modtime here */);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	uidata->widgets->lbl_remote_modtime = label;
	gtk_grid_attach (grid, label, 1, row, 1, 1);

	row++;

	/* take option duration */

	frame_take_dur = gtk_frame_new (_("Take option duration"));
	gtk_container_set_border_width (GTK_CONTAINER (frame_take_dur), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
	gtk_container_add (GTK_CONTAINER (content), frame_take_dur);

	grid = GTK_GRID (gtk_grid_new ());
	gtk_grid_set_row_homogeneous (grid, TRUE);
	gtk_grid_set_row_spacing (grid, 0);
	gtk_grid_set_column_homogeneous (grid, FALSE);
	gtk_grid_set_column_spacing (grid, 6);
	gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
	/* gtk_container_set_resize_mode (GTK_CONTAINER (grid), GTK_RESIZE_QUEUE); */
	gtk_container_add (GTK_CONTAINER (frame_take_dur), GTK_WIDGET (grid));

	row = 0;

	tmp_str = g_strconcat (_("Please choose how long the \"Take option\" specified below \nshould remain in effect"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 1, row, 1, 1);

	row++;

	widget = gtk_radio_button_new_with_label (NULL, _("Apply to all conflicts occuring during this synchronization"));
	uidata->widgets->radio_btn_this_sync = widget;
	uidata->widgets->radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	row++;

	widget = gtk_radio_button_new_with_label (uidata->widgets->radio_group, _("Apply to all conflicts occuring during this Evolution session"));
	uidata->widgets->radio_btn_this_session = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	row++;

	widget = gtk_radio_button_new_with_label (uidata->widgets->radio_group, _("Apply always and permanently"));
	uidata->widgets->radio_btn_permanent = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	row++;

	widget = gtk_radio_button_new_with_label (uidata->widgets->radio_group, _("Apply only to this conflict (ask each time)"));
	uidata->widgets->radio_btn_permanent = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	/* take options (actions!) */

	frame_take = gtk_frame_new (_("Take options"));
	gtk_container_set_border_width (GTK_CONTAINER (frame_take), KOLAB_SYNC_CONFLICT_WIDGET_BORDER_WIDTH);
	gtk_container_add (GTK_CONTAINER (content), frame_take);

	grid = GTK_GRID (gtk_grid_new ());
	gtk_grid_set_row_homogeneous (grid, TRUE);
	gtk_grid_set_row_spacing (grid, 2);
	gtk_grid_set_column_homogeneous (grid, FALSE);
	gtk_grid_set_column_spacing (grid, 6);
	gtk_container_set_border_width (GTK_CONTAINER (grid), 6);
	/* gtk_container_set_resize_mode (GTK_CONTAINER (grid), GTK_RESIZE_QUEUE); */
	gtk_container_add (GTK_CONTAINER (frame_take), GTK_WIDGET (grid));

	row = 0;

	tmp_str = g_strconcat (_("Please choose which of the two entries should be retained"), ":", NULL);
	label = gtk_label_new (tmp_str);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	g_free (tmp_str);
	gtk_grid_attach (grid, label, 1, row, 2, 1);

	row++;

	widget = gtk_button_new_with_label (_("Take Newer (last modified)"));
	uidata->widgets->btn_strategy_newer = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	row++;

	widget = gtk_button_new_with_label (_("Take Remote (server-side)"));
	uidata->widgets->btn_strategy_server = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	row++;

	widget = gtk_button_new_with_label (_("Take Local (client-side)"));
	uidata->widgets->btn_strategy_client = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	row++;

	widget = gtk_button_new_with_label (_("Take Both (resulting in two different, parallel entries)"));
	uidata->widgets->btn_strategy_dupe = widget;
	gtk_grid_attach (grid, widget, 1, row, 1, 1);

	/* FIXME connect signals */
	g_warning ("%s: FIXME connect signals", __func__);

	gtk_widget_show_all (content);

	return uidata;
}

static void
kolab_backend_sync_conflict_ui_free (KolabBackendSyncConflictUIData *uidata)
{
	if (uidata == NULL)
		return;

	/* the actual widgets will have been deleted already,
	 * so just deleting the struct shell here
	 */
	if (uidata->widgets != NULL)
		g_free (uidata->widgets);

	/* free payload data here */

	g_free (uidata);
}

static void
kolab_backend_sync_conflict_ui_destroy (gpointer ptr)
{
	KolabBackendSyncConflictUIData *uidata = ptr;
	kolab_backend_sync_conflict_ui_free (uidata);
}

static void
e_kolab_backend_sync_ui_conflict_response_cb (GObject *dialog,
                                              gint response_id)
{
	g_return_if_fail (dialog != NULL);

	if (response_id != GTK_RESPONSE_OK) {
		gtk_widget_destroy (GTK_WIDGET (dialog));
		return;
	}

	/* FIXME implement me */
	g_warning ("%s: FIXME implement me", __func__);
}

void
e_kolab_backend_sync_ui_conflict_cb (EShellView *shell_view)
{
	GObject *dialog = NULL;

	KolabBackendSyncConflictUIData *uidata = NULL;

	if (shell_view != NULL)
		g_assert (E_IS_SHELL_VIEW (shell_view));

	uidata = kolab_backend_sync_conflict_ui_new ();
	dialog = G_OBJECT (uidata->widgets->container);
	g_object_set_data_full (dialog, "e-kolab-backend-sync-prop", uidata, kolab_backend_sync_conflict_ui_destroy);

	/* signals */

	gtk_widget_show (GTK_WIDGET (dialog));
}

/*----------------------------------------------------------------------------*/
