#include "gtweakui.h"

GladeXML *ws;
static gboolean oldcheck[3];
static gboolean icheck[3];
GConfClient* gc;

void doquit() {
	GSList *infos = NULL;
	int x;
	char *messages[3] = {N_("Detachable menubars"), N_("Menus can be torn-off"), N_("Can change menu accelerators")};

	for (x = 0; x < 3; x ++)
		if (icheck[x] != oldcheck[x])
			infos = g_slist_prepend(infos, messages[x]);
	
	if (infos != NULL) {
		gtk_widget_hide(xmlg(ws, "menus"));
		notice(_("You may need to restart some applications for the following settings to take effect"), infos);
		g_slist_free(infos);
	} else {
		gtk_main_quit();
	}
}

void on_close_clicked(GtkWidget *widget, gpointer data) {
	doquit();
}

gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
	doquit();
	return TRUE;
}

static gint nullevent (GtkWidget *w, GdkEvent *e, gpointer data) {
	return TRUE;
}

void showtear(gboolean state) {
	static GtkWidget *menus[2] = {NULL,NULL}, *tearoff[2];

	if (menus[0] == NULL) {
		menus[0] = xmlg(ws, "mfile_menu");
		menus[1] = xmlg(ws, "medit_menu");
		tearoff[0] = gtk_tearoff_menu_item_new();
		gtk_menu_shell_prepend(GTK_MENU_SHELL(menus[0]), tearoff[0]);
		tearoff[1] = gtk_tearoff_menu_item_new();
		gtk_menu_shell_prepend(GTK_MENU_SHELL(menus[1]), tearoff[1]);
	}

	if (state) {
		gtk_widget_show(tearoff[0]);
		gtk_widget_show(tearoff[1]);
	} else {
		gtk_widget_hide(tearoff[0]);
		gtk_widget_hide(tearoff[1]);
	}
}

void showhandle(char group, gboolean state) {
	GtkWidget *align, *handle, *bar;
	static char alignname[]="xalignment", handlename[]="xhandle", barname[]="xbar";

	alignname[0] = group;
	handlename[0] = group;
	barname[0] = group;

	align=xmlg(ws, alignname);
	handle=xmlg(ws, handlename);
	bar=xmlg(ws, barname);

	g_object_ref(bar);
	
	if (state) {
		if (GTK_BIN (align)->child) {
			gtk_container_remove (GTK_CONTAINER (align), GTK_BIN (align)->child);

			gtk_container_add(GTK_CONTAINER(align), handle);
			gtk_container_add(GTK_CONTAINER(handle), bar);
		}
		g_object_unref(handle);
	} else {
		g_object_ref(handle);

		if (GTK_BIN (align)->child && GTK_BIN (handle)->child) {
			gtk_container_remove (GTK_CONTAINER (align), GTK_BIN (align)->child);
			gtk_container_remove (GTK_CONTAINER (handle), GTK_BIN (handle)->child);
			
			gtk_container_add(GTK_CONTAINER(align), bar);
		}
	}
	g_object_unref(bar);
}
/*
void toolbarStyle(const char *style) {
	static const char *senum[] = {"both", "both-horiz", "icons", "text"};
	static const GtkToolbarStyle styles[]= {GTK_TOOLBAR_BOTH, GTK_TOOLBAR_BOTH_HORIZ, GTK_TOOLBAR_ICONS, GTK_TOOLBAR_TEXT};
	unsigned char val = 0;
	while (val < 5 && (g_ascii_strcasecmp(senum[val], style) != 0)) {
		val ++;
	}
	if (val == 5)
		val = 0;

//	gtk_toolbar_set_style(GTK_TOOLBAR(xmlg(ws, "tbar")), styles[val]);
}

static void toolbarStyleCallback (GConfClient* client, guint cnxn_id, GConfEntry* entry, gpointer data) {
	if ((gconf_entry_get_value (entry) != NULL) && gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING)
		toolbarStyle(gconf_value_get_string(gconf_entry_get_value(entry)));
}

*/
static void toolbarCallback (GConfClient* client, guint cnxn_id, GConfEntry* entry, gpointer data) {
	if ((gconf_entry_get_value (entry) != NULL) && gconf_entry_get_value (entry)->type == GCONF_VALUE_BOOL)
		showhandle('t', gconf_value_get_bool(gconf_entry_get_value(entry)));
}

static void gconfChangedCallback (GConfClient* client, guint cnxn_id, GConfEntry* entry, gpointer data) {
	char *str = (char *)data;
	static GtkWidget *t[3]={NULL,NULL,NULL};
	int index;

	index = str[0] - '1';
	
	if (t[0] == NULL) {
		t[0] = glade_xml_get_widget(ws, "detachable_menubar");
		t[1] = glade_xml_get_widget(ws, "tearoff_menus");
		t[2] = glade_xml_get_widget(ws, "change_accels");
	}
	
	if ((gconf_entry_get_value (entry) != NULL) &&
			gconf_entry_get_value (entry)->type == GCONF_VALUE_BOOL) {
		gboolean new = gconf_value_get_bool(gconf_entry_get_value(entry));
		if (oldcheck[index] != new) {
			oldcheck[index] = new;
			gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t[index]), new);
			if (str[0] == '1')
				showhandle('m', new);
			if (str[0] == '2')
				showtear(new);
		}
	}
}

static void checkboxCallback(GtkWidget *widget, gpointer data) {
	char *str = (char *)data;
	static char *keys[3] = {"/desktop/gnome/interface/menubar_detachable", "/desktop/gnome/interface/menus_have_tearoff", "/desktop/gnome/interface/can_change_accels"};
	int index = str[0] - '1';
	gboolean state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));

	if (state != oldcheck[index]) {
		oldcheck[index] = state;
		gconf_client_set_bool(gc, keys[index], state, NULL);
		if (str[0] == '1')
			showhandle('m', state);
		if (str[0] == '2')
			showtear(state);
	}
}

void hookupcallbacks() {
	GtkWidget *w;
	char *val;

	gc = gconf_client_get_default();
	gconf_client_add_dir(gc, "/desktop/gnome/interface", GCONF_CLIENT_PRELOAD_NONE, NULL);

	w = glade_xml_get_widget(ws, "close_button");
	g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(on_close_clicked), NULL);
	
	w = glade_xml_get_widget(ws, "about_button");
	g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(about), glade_xml_get_widget(ws, "menus"));
	
	w = glade_xml_get_widget(ws, "menus");
	g_signal_connect(G_OBJECT(w), "delete_event", G_CALLBACK(delete_event), NULL);

	w = glade_xml_get_widget(ws, "detachable_menubar");
	g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(checkboxCallback), "1");
	gconf_client_notify_add(gc, "/desktop/gnome/interface/menubar_detachable", gconfChangedCallback, "1", NULL, NULL);
	icheck[0] = oldcheck[0] = gconf_client_get_bool (gc, "/desktop/gnome/interface/menubar_detachable", NULL);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), oldcheck[0]);
	if (!oldcheck[0])
		showhandle('m', FALSE);

	w = glade_xml_get_widget(ws, "tearoff_menus");
	g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(checkboxCallback), "2");
	gconf_client_notify_add(gc, "/desktop/gnome/interface/menus_have_tearoff", gconfChangedCallback, "2", NULL, NULL);
	icheck[1] = oldcheck[1] = gconf_client_get_bool (gc, "/desktop/gnome/interface/menus_have_tearoff", NULL);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), oldcheck[1]);
	if (oldcheck[1])
		showtear(TRUE);
	
	w = glade_xml_get_widget(ws, "change_accels");
	g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(checkboxCallback), "3");
	gconf_client_notify_add(gc, "/desktop/gnome/interface/can_change_accels", gconfChangedCallback, "3", NULL, NULL);
	icheck[2] = oldcheck[2] = gconf_client_get_bool (gc, "/desktop/gnome/interface/can_change_accels", NULL);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), oldcheck[2]);

	xsc(ws, "thandle", "button_press_event", nullevent, NULL);
	xsc(ws, "mhandle", "button_press_event", nullevent, NULL);

	gconf_client_notify_add(gc, "/desktop/gnome/interface/toolbar_detachable", toolbarCallback, NULL, NULL, NULL);
	if (!gconf_client_get_bool (gc, "/desktop/gnome/interface/toolbar_detachable", NULL))
		showhandle('t', FALSE);
/*
	gconf_client_notify_add(gc, "/desktop/gnome/interface/toolbar_style", toolbarStyleCallback, NULL, NULL, NULL);

	
	val = gconf_client_get_string (gc, "/desktop/gnome/interface/toolbar_style", NULL);
	if (val) {
		toolbarStyle(val);
		g_free(val);
	}
*/
	w = xmlg(ws, "tbar");
	gtk_toolbar_insert(GTK_TOOLBAR(w), gtk_tool_button_new_from_stock(GTK_STOCK_NEW), -1);
	gtk_toolbar_insert(GTK_TOOLBAR(w), gtk_tool_button_new_from_stock(GTK_STOCK_OPEN), -1);
	gtk_toolbar_insert(GTK_TOOLBAR(w), gtk_tool_button_new_from_stock(GTK_STOCK_SAVE), -1);

	gtk_toolbar_unset_style(GTK_TOOLBAR(xmlg(ws, "tbar")));

	gtk_widget_show_all(xmlg(ws, "menus"));
}

int main(int argc, char *argv[]) {
	gtweakui = gnome_program_init(PACKAGE_NAME, PACKAGE_VERSION, LIBGNOMEUI_MODULE, argc, argv, GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR, NULL);
	gconf_init(argc, argv, NULL);
	
	bindtextdomain (GETTEXT_PACKAGE, GTWEAKUILOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	ws = glade_xml_new(gnome_program_locate_file(gtweakui, GNOME_FILE_DOMAIN_APP_DATADIR, "menus.glade", FALSE, NULL), NULL, NULL);

	hookupcallbacks();

	gtk_main();

	return 0;
}
