/*
 *  This program 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 2 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU 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 "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <X11/keysym.h>

#include <glib/gi18n.h>
#include <gdk/gdkx.h>
#include <libgnome/gnome-program.h>

#include "gswitchit-config.h"
#include "gswitchit-config-private.h"

#include <keyboard-config-registry-client.h>

/**
 * GSwitchItAppletConfig
 */
#define GSWITCHIT_APPLET_CONFIG_KEY_PREFIX  "/apps/gswitchit/Applet"

const gchar GSWITCHIT_APPLET_CONFIG_DIR[] =
    GSWITCHIT_APPLET_CONFIG_KEY_PREFIX;
const gchar GSWITCHIT_APPLET_CONFIG_KEY_SHOW_FLAGS[] =
    GSWITCHIT_APPLET_CONFIG_KEY_PREFIX "/showFlags";
const gchar GSWITCHIT_APPLET_CONFIG_KEY_ENABLED_PLUGINS[] =
    GSWITCHIT_APPLET_CONFIG_KEY_PREFIX "/enabledPlugins";
const gchar GSWITCHIT_APPLET_CONFIG_KEY_SECONDARIES[] =
    GSWITCHIT_APPLET_CONFIG_KEY_PREFIX "/secondary";

/**
 * static applet config functions
 */
static void
gswitchit_applet_config_free_enabled_plugins (GSwitchItAppletConfig *
					      applet_config)
{
	GSList *plugin_node = applet_config->enabled_plugins;
	if (plugin_node != NULL) {
		do {
			if (plugin_node->data != NULL) {
				g_free (plugin_node->data);
				plugin_node->data = NULL;
			}
			plugin_node = g_slist_next (plugin_node);
		} while (plugin_node != NULL);
		g_slist_free (applet_config->enabled_plugins);
		applet_config->enabled_plugins = NULL;
	}
}

/**
 * extern applet kbdConfig functions
 */
void
gswitchit_applet_config_free_images (GSwitchItAppletConfig * applet_config)
{
	GdkPixbuf *pi;
	GSList *img_node;
	while ((img_node = applet_config->images) != NULL) {
		pi = GDK_PIXBUF (img_node->data);
		/* It can be NULL - some images may be missing */
		if (pi != NULL) {
			gdk_pixbuf_unref (pi);
		}
		applet_config->images =
		    g_slist_remove_link (applet_config->images, img_node);
		g_slist_free_1 (img_node);
	}
}

char *
gswitchit_applet_config_get_images_file (GSwitchItAppletConfig *
					 applet_config,
					 GSwitchItKbdConfig *
					 kbd_config, int group)
{
	char *image_file = NULL;
	GtkIconInfo *icon_info = NULL;

	if (!applet_config->show_flags)
		return NULL;

	if ((kbd_config->layouts != NULL) &&
	    (g_slist_length (kbd_config->layouts) > group)) {
		char *full_layout_name =
		    (char *) g_slist_nth_data (kbd_config->layouts, group);

		if (full_layout_name != NULL) {
			char *l, *v;
			gswitchit_kbd_config_split_items (full_layout_name,
							  &l, &v);
			if (l != NULL) {
				// probably there is something in theme?
				icon_info = gtk_icon_theme_lookup_icon
				    (applet_config->icon_theme, l, 48, 0);
			}
		}
	}
	// fallback to the default value
	if (icon_info == NULL) {
		icon_info = gtk_icon_theme_lookup_icon
		    (applet_config->icon_theme, "stock_dialog-error", 48,
		     0);
	}
	if (icon_info != NULL) {
		image_file =
		    g_strdup (gtk_icon_info_get_filename (icon_info));
		gtk_icon_info_free (icon_info);
	}

	return image_file;
}

void
gswitchit_applet_config_load_images (GSwitchItAppletConfig * applet_config,
				     GSwitchItKbdConfig * kbd_config)
{
	int i;
	applet_config->images = NULL;

	if (!applet_config->show_flags)
		return;

	for (i = xkl_engine_get_max_num_groups (applet_config->engine);
	     --i >= 0;) {
		GdkPixbuf *image = NULL;
		char *image_file =
		    gswitchit_applet_config_get_images_file (applet_config,
							     kbd_config,
							     i);

		if (image_file != NULL) {
			GError *gerror = NULL;
			image =
			    gdk_pixbuf_new_from_file (image_file, &gerror);
			if (image == NULL) {
				GtkWidget *dialog =
				    gtk_message_dialog_new (NULL,
							    GTK_DIALOG_DESTROY_WITH_PARENT,
							    GTK_MESSAGE_ERROR,
							    GTK_BUTTONS_OK,
							    _
							    ("There was an error loading an image: %s"),
							    gerror->
							    message);
				g_signal_connect (G_OBJECT (dialog),
						  "response",
						  G_CALLBACK
						  (gtk_widget_destroy),
						  NULL);

				gtk_window_set_resizable (GTK_WINDOW
							  (dialog), FALSE);

				gtk_widget_show (dialog);
				g_error_free (gerror);
			}
			xkl_debug (150,
				   "Image %d[%s] loaded -> %p[%dx%d]\n",
				   i, image_file, image,
				   gdk_pixbuf_get_width (image),
				   gdk_pixbuf_get_height (image));
			g_free (image_file);
		}
		/* We append the image anyway - even if it is NULL! */
		applet_config->images =
		    g_slist_prepend (applet_config->images, image);
	}
}

void
gswitchit_applet_config_init (GSwitchItAppletConfig * applet_config,
			      GConfClient * conf_client,
			      XklEngine * engine)
{
	GError *gerror = NULL;
	gchar *sp, *datadir;

	memset (applet_config, 0, sizeof (*applet_config));
	applet_config->conf_client = conf_client;
	applet_config->engine = engine;
	g_object_ref (applet_config->conf_client);

	gconf_client_add_dir (applet_config->conf_client,
			      GSWITCHIT_APPLET_CONFIG_DIR,
			      GCONF_CLIENT_PRELOAD_NONE, &gerror);
	if (gerror != NULL) {
		g_warning ("err1:%s\n", gerror->message);
		g_error_free (gerror);
		gerror = NULL;
	}

	applet_config->icon_theme = gtk_icon_theme_get_default ();

	datadir =
	    gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_DATADIR,
				       "", FALSE, NULL);
	gtk_icon_theme_append_search_path (applet_config->icon_theme, sp =
					   g_build_filename (g_get_home_dir
							     (),
							     ".icons/flags",
							     NULL));
	g_free (sp);

	gtk_icon_theme_append_search_path (applet_config->icon_theme,
					   sp =
					   g_build_filename (datadir,
							     "pixmaps/flags",
							     NULL));
	g_free (sp);

	gtk_icon_theme_append_search_path (applet_config->icon_theme,
					   sp =
					   g_build_filename (datadir,
							     "icons/flags",
							     NULL));
	g_free (sp);
	g_free (datadir);
}

void
gswitchit_applet_config_term (GSwitchItAppletConfig * applet_config)
{
#if 0
	g_object_unref (G_OBJECT (applet_config->icon_theme));
#endif
	applet_config->icon_theme = NULL;

	gswitchit_applet_config_free_images (applet_config);

	gswitchit_applet_config_free_enabled_plugins (applet_config);
	g_object_unref (applet_config->conf_client);
	applet_config->conf_client = NULL;
}

void
gswitchit_applet_config_update_images (GSwitchItAppletConfig *
				       applet_config,
				       GSwitchItKbdConfig * kbd_config)
{
	gswitchit_applet_config_free_images (applet_config);
	gswitchit_applet_config_load_images (applet_config, kbd_config);
}

void
gswitchit_applet_config_load_from_gconf (GSwitchItAppletConfig *
					 applet_config)
{
	GError *gerror = NULL;

	applet_config->secondary_groups_mask =
	    gconf_client_get_int (applet_config->conf_client,
				  GSWITCHIT_APPLET_CONFIG_KEY_SECONDARIES,
				  &gerror);
	if (gerror != NULL) {
		g_warning ("Error reading configuration:%s\n",
			   gerror->message);
		applet_config->secondary_groups_mask = 0;
		g_error_free (gerror);
		gerror = NULL;
	}

	applet_config->show_flags =
	    gconf_client_get_bool (applet_config->conf_client,
				   GSWITCHIT_APPLET_CONFIG_KEY_SHOW_FLAGS,
				   &gerror);
	if (gerror != NULL) {
		g_warning ("Error reading kbdConfiguration:%s\n",
			   gerror->message);
		applet_config->show_flags = FALSE;
		g_error_free (gerror);
		gerror = NULL;
	}

	gswitchit_applet_config_free_enabled_plugins (applet_config);
	applet_config->enabled_plugins =
	    gconf_client_get_list (applet_config->conf_client,
				   GSWITCHIT_APPLET_CONFIG_KEY_ENABLED_PLUGINS,
				   GCONF_VALUE_STRING, &gerror);

	if (gerror != NULL) {
		g_warning ("Error reading kbd_configuration:%s\n",
			   gerror->message);
		applet_config->enabled_plugins = NULL;
		g_error_free (gerror);
		gerror = NULL;
	}
}

void
gswitchit_applet_config_save_to_gconf (GSwitchItAppletConfig *
				       applet_config)
{
	GConfChangeSet *cs;
	GError *gerror = NULL;

	cs = gconf_change_set_new ();

	gconf_change_set_set_int (cs,
				  GSWITCHIT_APPLET_CONFIG_KEY_SECONDARIES,
				  applet_config->secondary_groups_mask);
	gconf_change_set_set_bool (cs,
				   GSWITCHIT_APPLET_CONFIG_KEY_SHOW_FLAGS,
				   applet_config->show_flags);
	gconf_change_set_set_list (cs,
				   GSWITCHIT_APPLET_CONFIG_KEY_ENABLED_PLUGINS,
				   GCONF_VALUE_STRING,
				   applet_config->enabled_plugins);

	gconf_client_commit_change_set (applet_config->conf_client, cs,
					TRUE, &gerror);
	if (gerror != NULL) {
		g_warning ("Error saving configuration: %s\n",
			   gerror->message);
		g_error_free (gerror);
		gerror = NULL;
	}
	gconf_change_set_unref (cs);
}

void
gswitchit_applet_config_activate (GSwitchItAppletConfig * applet_config)
{
	xkl_engine_set_secondary_groups_mask (applet_config->engine,
					      applet_config->
					      secondary_groups_mask);
}

void
gswitchit_applet_config_start_listen (GSwitchItAppletConfig *
				      applet_config,
				      GConfClientNotifyFunc func,
				      gpointer user_data)
{
	gswitchit_config_add_listener (applet_config->conf_client,
				       GSWITCHIT_APPLET_CONFIG_DIR, func,
				       user_data,
				       &applet_config->config_listener_id);
}

void
gswitchit_applet_config_stop_listen (GSwitchItAppletConfig * applet_config)
{
	gswitchit_config_remove_listener (applet_config->conf_client,
					  &applet_config->
					  config_listener_id);
}
