/* sunone-add-permission-dialog.c
 *
 * Copyright (C) 2002-2004 Sun Microsystems, Inc
 *
 * AUTHORS
 *     Jack Jia <jack.jia@sun.com>
 *     Harry Lu <harry.lu@sun.com>
 *     Alfred Peng <alfred.peng@sun.com>
 *     Rodrigo Moya <rodrigo@ximian.com>
 *
 */

#include <gtk/gtk.h>
#include <glib/gi18n.h>

#include "sunone-add-permission-dialog.h"

struct _SunOneAddPermissionDialogPrivate {
	GladeXML *xml;
	SunOnePermissionsDialog *perm_dialog;
	SunOneACE *ace;
	gboolean displaying_more_options;

	GtkWidget *user_name;
	GtkWidget *perms_avail;
	GtkWidget *perms_invite;
	GtkWidget *perms_read;
	GtkWidget *perms_delete;
	GtkWidget *perms_modify;
};

static void sunone_add_permission_dialog_class_init (SunOneAddPermissionDialogClass *klass);
static void sunone_add_permission_dialog_init (SunOneAddPermissionDialog *object);
static void sunone_add_permission_dialog_dispose (GObject *object);
static void sunone_add_permission_dialog_finalize (GObject *object);

static GObjectClass *parent_class = NULL;

static const int accesstype_map[] = {
	SUNONE_ACE_ACCESSTYPE_GRANT,
	SUNONE_ACE_ACCESSTYPE_DENY,
	-1
};
static const int usertype_map[] = {
	SUNONE_ACE_USERTYPE_USER,
	SUNONE_ACE_USERTYPE_DOMAIN,
	SUNONE_ACE_USERTYPE_ALL_USERS,
	SUNONE_ACE_USERTYPE_PRIMARY_OWNERS,
	SUNONE_ACE_USERTYPE_OWNERS,
	SUNONE_ACE_USERTYPE_NONOWNERS,
	-1
};
static const int context_map[] = {
	SUNONE_ACE_CONTEXT_ENTIRE_CALENDAR,
	SUNONE_ACE_CONTEXT_CALENDAR_COMPONENTS,
	SUNONE_ACE_CONTEXT_CALENDAR_PROPERTIES,
	-1
};

static void
dialog_button_clicked_cb (GtkDialog *gdialog, gint response, gpointer user_data)
{
	SunOneAddPermissionDialog *dialog = SUNONE_ADD_PERMISSION_DIALOG (gdialog);
	SunOneAddPermissionDialogPrivate *priv = dialog->priv;
	gboolean added = FALSE;

	if (response == GTK_RESPONSE_OK) {
		SunOneACEPermission perms;
		const gchar *uname;

		if (!priv->ace) {
			priv->ace = sunone_ace_new ();
			sunone_ace_set_user_type (priv->ace, SUNONE_ACE_USERTYPE_USER);
			added = TRUE;
		}

		uname = gtk_entry_get_text (GTK_ENTRY (priv->user_name));
		if (sunone_ace_get_user_type (priv->ace) == SUNONE_ACE_USERTYPE_USER)
			sunone_ace_set_user_name (priv->ace, uname);
		sunone_ace_set_access_type (priv->ace, SUNONE_ACE_ACCESSTYPE_GRANT);
		sunone_ace_set_context (priv->ace, SUNONE_ACE_CONTEXT_ENTIRE_CALENDAR);

		perms = SUNONE_ACE_PERMISSION_NONE;
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->perms_avail)))
			perms |= SUNONE_ACE_PERMISSION_FREEBUSY;
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->perms_invite)))
			perms |= SUNONE_ACE_PERMISSION_SCHEDULE;
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->perms_read)))
			perms |= SUNONE_ACE_PERMISSION_READ;
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->perms_delete)))
			perms |= SUNONE_ACE_PERMISSION_DELETE;
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->perms_modify)))
			perms |= SUNONE_ACE_PERMISSION_WRITE;
		sunone_ace_set_permissions (priv->ace, perms);

               /* refresh the list of permissions */
		if (added) {
			GtkTreeIter iter;
			GtkTreeModel *model =
				gtk_tree_view_get_model (sunone_permissions_dialog_get_permissions_tree_view (priv->perm_dialog));

			priv->perm_dialog->merged_acls = g_list_append (priv->perm_dialog->merged_acls, priv->ace);
			gtk_list_store_append(GTK_LIST_STORE (model), &iter);
			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				PERM_NAME_COLUMN,
				uname,
				PERM_AVAILABILITY_COLUMN,
				perms & SUNONE_ACE_PERMISSION_FREEBUSY,
				PERM_INVITE_COLUMN,
				perms & SUNONE_ACE_PERMISSION_SCHEDULE,
				PERM_READ_COLUMN,
				perms & SUNONE_ACE_PERMISSION_READ,
				PERM_DELETE_COLUMN,
				perms & SUNONE_ACE_PERMISSION_DELETE,
				PERM_MODIFY_COLUMN,
				perms & SUNONE_ACE_PERMISSION_WRITE,
				-1);

		} else {
			GtkTreeSelection *selection;
			GtkTreeModel *model;
			GtkTreeIter iter;

			selection =
				gtk_tree_view_get_selection (sunone_permissions_dialog_get_permissions_tree_view (priv->perm_dialog));
			gtk_tree_selection_get_selected (selection, &model, &iter);
			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				PERM_NAME_COLUMN,
				uname,
				PERM_AVAILABILITY_COLUMN,
				perms & SUNONE_ACE_PERMISSION_FREEBUSY,
				PERM_INVITE_COLUMN,
				perms & SUNONE_ACE_PERMISSION_SCHEDULE,
				PERM_READ_COLUMN,
				perms & SUNONE_ACE_PERMISSION_READ,
				PERM_DELETE_COLUMN,
				perms & SUNONE_ACE_PERMISSION_DELETE,
				PERM_MODIFY_COLUMN,
				perms & SUNONE_ACE_PERMISSION_WRITE,
				-1);
		}
		 gtk_dialog_set_response_sensitive (GTK_DIALOG (priv->perm_dialog), GTK_RESPONSE_OK, TRUE);

	}
	gtk_widget_destroy (GTK_WIDGET (gdialog));
}

static void
permission_toggled_cb (GtkToggleButton *button, gpointer user_data)
{
	SunOneAddPermissionDialog *dialog = SUNONE_ADD_PERMISSION_DIALOG (user_data);
	SunOneAddPermissionDialogPrivate *priv = dialog->priv;
	const char *text;

	text = gtk_entry_get_text (GTK_ENTRY (priv->user_name));
	if (text && *text)	
		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, TRUE);
}

static void
user_name_changed_cb (GtkEditable *editable, gpointer user_data)
{
	SunOneAddPermissionDialog *dialog = SUNONE_ADD_PERMISSION_DIALOG (user_data);
	SunOneAddPermissionDialogPrivate *priv = dialog->priv;

	const char *text;

	text = gtk_entry_get_text (GTK_ENTRY (priv->user_name));
	if (text && *text)
		 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, TRUE);
	else
		 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
}

static void
user_name_insert_cb (GtkEditable *editable, gchar *new_text,
		     gint new_text_length, gint *position, gpointer data)
{
	gboolean ok = TRUE;
	int i;
	
	for (i = 0; i < new_text_length; i++) {
		char c = new_text[i];
		
		if (!((c >= 'a' && c <= 'z')
		      || (c >= 'A' && c <= 'Z')
		      || (c >= '0' && c <= '9')
		      || c == '.' || c == '_'
		      || c == '-' || c == '&'
		      || c == '!' || c == '@'))
			ok = FALSE;
	}

	if (!ok)
		g_signal_stop_emission_by_name (editable, "insert_text");
}

static void
sunone_add_permission_dialog_class_init (SunOneAddPermissionDialogClass *klass)
{
	GObjectClass *object_class = G_OBJECT_CLASS (klass);

	parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
	object_class->dispose  = sunone_add_permission_dialog_dispose;
	object_class->finalize = sunone_add_permission_dialog_finalize;
}

static void
sunone_add_permission_dialog_init (SunOneAddPermissionDialog *object)
{
	SunOneAddPermissionDialog *dialog = SUNONE_ADD_PERMISSION_DIALOG (object);
	SunOneAddPermissionDialogPrivate *priv;
	GtkWidget *container;
	GtkWidget *err_dialog;

	dialog->priv = g_new0 (SunOneAddPermissionDialogPrivate, 1);
	priv = dialog->priv;

	priv->perm_dialog = NULL;
	priv->ace = NULL;
	priv->displaying_more_options = FALSE;

	/* load UI from Glade file */
	priv->xml = glade_xml_new (SUNONE_GLADEDIR "/sunone-add-permission-dialog.glade",
				     "add-permission-container", NULL);
	if (!priv->xml) {
		err_dialog = gtk_message_dialog_new (GTK_WINDOW(dialog), GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", _("Could not load UI for dialog"));
		gtk_dialog_run (GTK_DIALOG (err_dialog));
		gtk_widget_destroy (err_dialog);
		return;
	}

	gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);

	container = glade_xml_get_widget (priv->xml, "add-permission-container");
	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), container, TRUE, TRUE, 3);

	priv->user_name = glade_xml_get_widget (priv->xml, "add-user-name");
	priv->perms_avail = glade_xml_get_widget (priv->xml, "avail-perm");
	priv->perms_invite = glade_xml_get_widget (priv->xml, "invite-perm");
	priv->perms_read = glade_xml_get_widget (priv->xml, "read-perm");
	priv->perms_delete = glade_xml_get_widget (priv->xml, "delete-perm");
	priv->perms_modify = glade_xml_get_widget (priv->xml, "modify-perm");
}

static void
sunone_add_permission_dialog_dispose (GObject *object)
{
	SunOneAddPermissionDialog *dialog = SUNONE_ADD_PERMISSION_DIALOG (object);
	SunOneAddPermissionDialogPrivate *priv = dialog->priv;

	if (priv) {
		if (priv->xml) {
			g_object_unref (G_OBJECT (priv->xml));
			priv->xml = NULL;
		}

		g_free (priv);
		dialog->priv = NULL;
	}

    if (G_OBJECT_CLASS (parent_class)->dispose)
		(* G_OBJECT_CLASS (parent_class)->dispose) (object);
	
}

static void
sunone_add_permission_dialog_finalize(GObject *object)
{
	if (G_OBJECT_CLASS (parent_class)->finalize)
		(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}

G_DEFINE_TYPE (SunOneAddPermissionDialog, sunone_add_permission_dialog, GTK_TYPE_DIALOG)

GtkWidget *
sunone_add_permission_dialog_new (SunOnePermissionsDialog *perm_dialog, SunOneACE *ace)
{
	SunOneAddPermissionDialog *dialog;
	SunOneAddPermissionDialogPrivate *priv;

	g_return_val_if_fail (IS_SUNONE_PERMISSIONS_DIALOG (perm_dialog), NULL);

	dialog = g_object_new (SUNONE_ADD_PERMISSION_DIALOG_TYPE, NULL);
	priv = dialog->priv;
	priv->perm_dialog = perm_dialog;
	priv->ace = ace;

	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);

	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);

	/* update the dialog with the passed in ACE */
	if (IS_SUNONE_ACE (ace)) {
		SunOneACEPermission perms;

		if (sunone_ace_get_user_type (ace) == SUNONE_ACE_USERTYPE_USER) {
			gtk_entry_set_text (GTK_ENTRY (priv->user_name), sunone_ace_get_user_name (ace));
		} else {
			gtk_entry_set_text (GTK_ENTRY (priv->user_name), _("Everybody"));
			gtk_widget_set_sensitive (GTK_WIDGET (priv->user_name), FALSE);
		}
		
		perms = sunone_ace_get_permissions (ace);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->perms_avail),
					      perms & SUNONE_ACE_PERMISSION_FREEBUSY);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->perms_invite),
					      perms & SUNONE_ACE_PERMISSION_SCHEDULE);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->perms_read),
					      perms & SUNONE_ACE_PERMISSION_READ);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->perms_delete),
					      perms & SUNONE_ACE_PERMISSION_DELETE);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->perms_modify),
					      perms & SUNONE_ACE_PERMISSION_WRITE);

		gtk_window_set_title (GTK_WINDOW (dialog), _("Edit permission"));
	} else
		gtk_window_set_title (GTK_WINDOW (dialog), _("Add permission"));

	/* connect to signals, which must be done after setting the widgets' contents */
	g_signal_connect (G_OBJECT (priv->user_name), "insert_text", G_CALLBACK (user_name_insert_cb), dialog);
	g_signal_connect_after (G_OBJECT (priv->user_name), "changed", G_CALLBACK (user_name_changed_cb), dialog);
	g_signal_connect (G_OBJECT (priv->perms_avail), "toggled", G_CALLBACK (permission_toggled_cb), dialog);
	g_signal_connect (G_OBJECT (priv->perms_invite), "toggled", G_CALLBACK (permission_toggled_cb), dialog);
	g_signal_connect (G_OBJECT (priv->perms_read), "toggled", G_CALLBACK (permission_toggled_cb), dialog);
	g_signal_connect (G_OBJECT (priv->perms_delete), "toggled", G_CALLBACK (permission_toggled_cb), dialog);
	g_signal_connect (G_OBJECT (priv->perms_modify), "toggled", G_CALLBACK (permission_toggled_cb), dialog);

	g_signal_connect (dialog, "response", 
			G_CALLBACK (dialog_button_clicked_cb), NULL);

	gtk_widget_show (GTK_WIDGET (dialog));

	return GTK_WIDGET (dialog);
}

