/* This file is part of GQ
 *
 * AUTHORS
 *     Sven Herzberg  <herzi@gnome-de.org>
 *
 * Copyright (C) 2006  Sven Herzberg <herzi@gnome-de.org>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include "gq-login-dialog.h"

#include <string.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkentry.h>
#include <gtk/gtklabel.h>
#include <gtk/gtksizegroup.h>

#include "configfile.h" // token_bindtype
#include "gq-keyring.h"

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <glib/gi18n.h>

struct GqLoginDialogPrivate {
	GqServer* server;

	GtkLabel* label_hostname;
	GtkLabel* label_bind_dn;
	GtkEntry* entry_bind_pw;
	GtkLabel* label_bind_type;
	GtkCheckButton* checkbutton_save_password;
};
#define P(i) (G_TYPE_INSTANCE_GET_PRIVATE((i), GQ_TYPE_LOGIN_DIALOG, struct GqLoginDialogPrivate))

GtkWidget*
gq_login_dialog_new(GqServer* server)
{
	return g_object_new(GQ_TYPE_LOGIN_DIALOG, "server", server, NULL);
}

gchar const*
gq_login_dialog_get_password(GqLoginDialog const* self)
{
	gchar const* retval;

	g_return_val_if_fail(GQ_IS_LOGIN_DIALOG(self), NULL);
	retval = gtk_entry_get_text(P(self)->entry_bind_pw);

	return retval && *retval ? retval : NULL;
}

gboolean
gq_login_dialog_get_save_password(GqLoginDialog const* self)
{
	g_return_val_if_fail(GQ_IS_LOGIN_DIALOG(self), FALSE);

	return gq_keyring_can_save() &&
	       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(P(self)->checkbutton_save_password));
}

static void
login_dialog_update_bind_dn(GqLoginDialog* self)
{
	gtk_label_set_text(P(self)->label_bind_dn,
			   gq_server_get_bind_dn(P(self)->server));
}

static void
login_dialog_update_bind_type(GqLoginDialog* self)
{
	// TRANSLATORS: "(Simple,Kerberos,SASL) Authentication"
	gchar* string = g_strdup_printf(_("%s Authentication"),
					token_bindtype[gq_server_get_bind_type(P(self)->server)].keyword);
#warning "FIXME: get this translatable as a whole text"
	gtk_label_set_text(P(self)->label_bind_type, string);
	g_free(string);
	string = NULL;
}

static void
login_dialog_update_server_name(GqLoginDialog* self)
{
	gchar* string;
	if(gq_server_get_name(P(self)->server) && gq_server_get_host(P(self)->server) &&
	   (!strcmp(gq_server_get_name(P(self)->server), gq_server_get_host(P(self)->server))))
	{
		// Server Name and Hostname are equal, do not print twice
		// TRANSLATORS: "hostname:port"
		string = g_strdup_printf(_("%s:%d"),
		gq_server_get_name(P(self)->server),
		gq_server_get_port(P(self)->server));
	} else {
		// TRANSLATORS: "servername (hostname:port)"
		string = g_strdup_printf(_("%s (%s:%d)"),
		gq_server_get_name(P(self)->server),
		gq_server_get_host(P(self)->server),
		gq_server_get_port(P(self)->server));
	}
	gtk_label_set_text(P(self)->label_hostname, string);
	g_free(string);
}

static void
login_dialog_set_server(GqLoginDialog* self,
			GqServer     * server)
{
	g_return_if_fail(GQ_IS_LOGIN_DIALOG(self));
	g_return_if_fail(!server || GQ_IS_SERVER(server));

	if(server == P(self)->server) {
		return;
	}

	if(P(self)->server) {
		g_signal_handlers_disconnect_by_func(P(self)->server,
						     login_dialog_update_bind_dn,
						     self);
		g_signal_handlers_disconnect_by_func(P(self)->server,
						     login_dialog_update_bind_type,
						     self);
		g_signal_handlers_disconnect_by_func(P(self)->server,
						     login_dialog_update_server_name,
						     self);
		g_object_unref(P(self)->server);
		P(self)->server = NULL;
	}

	if(server) {
		P(self)->server = g_object_ref(server);
		g_signal_connect_swapped(P(self)->server, "notify::bind-dn",
					 G_CALLBACK(login_dialog_update_bind_dn), self);
		g_signal_connect_swapped(P(self)->server, "notify::bind-type",
					 G_CALLBACK(login_dialog_update_bind_type), self);
		g_signal_connect_swapped(P(self)->server, "notify::name",
					 G_CALLBACK(login_dialog_update_server_name), self);
		g_signal_connect_swapped(P(self)->server, "notify::host",
					 G_CALLBACK(login_dialog_update_server_name), self);

		login_dialog_update_bind_dn(self);
		login_dialog_update_bind_type(self);
		login_dialog_update_server_name(self);
	}

	g_object_notify(G_OBJECT(self), "server");
}

/* GType */
G_DEFINE_TYPE(GqLoginDialog, gq_login_dialog, HERZI_TYPE_GLADE_DIALOG);

enum {
	PROP_0,
	PROP_SERVER
};

static void
gq_login_dialog_init(GqLoginDialog* self)
{}

static void
login_dialog_connect_widgets(HerziGladeDialog* dialog,
			     GladeXML        * xml)
{
	GtkSizeGroup* group_left  = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
	GtkSizeGroup* group_right = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);

	gtk_size_group_add_widget(group_left, glade_xml_get_widget(xml, "label_hostname"));
	gtk_size_group_add_widget(group_left, glade_xml_get_widget(xml, "label_bind_dn"));
	gtk_size_group_add_widget(group_left, glade_xml_get_widget(xml, "label_bind_mode"));
	gtk_size_group_add_widget(group_left, glade_xml_get_widget(xml, "label_password"));
	gtk_size_group_add_widget(group_right, glade_xml_get_widget(xml, "input_hostname"));
	gtk_size_group_add_widget(group_right, glade_xml_get_widget(xml, "input_bind_dn"));
	gtk_size_group_add_widget(group_right, glade_xml_get_widget(xml, "input_bind_mode"));
	gtk_size_group_add_widget(group_right, glade_xml_get_widget(xml, "input_password"));

	if(!gq_keyring_can_save()) {
		gtk_widget_set_sensitive(glade_xml_get_widget(xml, "checkbutton_save_password"),
					 FALSE);
	}

	P(dialog)->label_bind_dn   = GTK_LABEL(glade_xml_get_widget(xml, "input_bind_dn"));
	P(dialog)->entry_bind_pw   = GTK_ENTRY(glade_xml_get_widget(xml, "input_password"));
	P(dialog)->label_bind_type = GTK_LABEL(glade_xml_get_widget(xml, "input_bind_mode"));
	P(dialog)->label_hostname  = GTK_LABEL(glade_xml_get_widget(xml, "input_hostname"));
	P(dialog)->checkbutton_save_password =
				GTK_CHECK_BUTTON(glade_xml_get_widget(xml, "checkbutton_save_password"));
}

static void
login_dialog_dispose(GObject* object)
{
	if(P(object)->server) {
		login_dialog_set_server(GQ_LOGIN_DIALOG(object), NULL);
	}

	G_OBJECT_CLASS(gq_login_dialog_parent_class)->dispose(object);
}

static void
login_dialog_get_property(GObject   * object,
			  guint       prop_id,
			  GValue    * value,
			  GParamSpec* pspec)
{
	switch(prop_id) {
	case PROP_SERVER:
		g_value_set_object(value, P(object)->server);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static void
login_dialog_set_property(GObject     * object,
			  guint         prop_id,
			  GValue const* value,
			  GParamSpec  * pspec)
{
	switch(prop_id) {
	case PROP_SERVER:
		login_dialog_set_server(GQ_LOGIN_DIALOG(object), g_value_get_object(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
		break;
	}
}

static void
gq_login_dialog_class_init(GqLoginDialogClass* self_class)
{
	GObjectClass         * object_class = G_OBJECT_CLASS(self_class);
	HerziGladeDialogClass* glade_dialog_class = HERZI_GLADE_DIALOG_CLASS(self_class);

	/* GObjectClass */
	object_class->dispose      = login_dialog_dispose;
	object_class->get_property = login_dialog_get_property;
	object_class->set_property = login_dialog_set_property;
	g_object_class_install_property(object_class,
					PROP_SERVER,
					g_param_spec_object("server",
							    _("Server"),
							    _("The server to be connected to"),
							    GQ_TYPE_SERVER,
							    G_PARAM_READWRITE));

	/* HerziGladeDialogClass */
	glade_dialog_class->connect_widgets = login_dialog_connect_widgets;
	glade_dialog_class->filename        = PACKAGE_PREFIX "/share/gq/gq.glade";
	glade_dialog_class->root_widget     = "password_dialog";

	/* GqLoginDialogClass */
	g_type_class_add_private(self_class, sizeof(struct GqLoginDialogPrivate));
}

