/* GNOME INPUT METHOD SWITCHER
 * Copyright 2003 Sun Microsystems Inc.
 *
 * This 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 of the License, or (at your option) any later version.
 *
 * This library 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 library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <config.h>

#include <gtk/gtkmain.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtksignal.h>
#include <panel-applet.h>
#include <panel-applet-gconf.h>
#include <gnome.h>

#include "gnome-im-switcher.h"
#include "language.h"
#include "preference.h"
#include "status-placement.h"
#include "utils.h"
#include "widgets.h"

#include <gconf/gconf-client.h>

static GConfClient *default_client = NULL;

static void
input_language_policy_update (GimletWindow *gimlet)
{
  panel_applet_gconf_set_int (PANEL_APPLET (gimlet->applet),
			      "input_language_policy",
			      gimlet->input_lang_policy,
			      NULL);
}

static void
on_follow_application_toggled (GtkWidget *button,
			       GimletWindow *gimlet)
{
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
    {
      gimlet->input_lang_policy = FOLLOW_APPLICATION;
#ifdef MEANINGLESS_OPTION_PERHAPS
      gtk_widget_set_sensitive (gimlet->input_language_option_menu, FALSE);
#endif
    }

  input_language_policy_update (gimlet);
}

static void
on_follow_quick_access_menu_toggled (GtkWidget *button,
				     GimletWindow *gimlet)
{
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
    {
      gimlet->input_lang_policy = FOLLOW_QUICK_ACCESS_MENU;
#ifdef MEANINGLESS_OPTION_PERHAPS
      gtk_widget_set_sensitive (gimlet->input_language_option_menu, FALSE);
#endif
    }

  input_language_policy_update (gimlet);
}

#ifdef MEANINGLESS_OPTION_PERHAPS
static void
on_follow_current_locale_toggled (GtkWidget *button,
				  GimletWindow *gimlet)
{
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
    {
      gimlet->input_lang_policy = FOLLOW_CURRENT_LOCALE;
      gtk_widget_set_sensitive (gimlet->input_language_option_menu, FALSE);
    }

  input_language_policy_update (gimlet);
}

static void
on_follow_option_menu_toggled (GtkWidget *button,
			       GimletWindow *gimlet)
{
  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
    {
      gimlet->input_lang_policy = FOLLOW_OPTION_MENU;
      gtk_widget_set_sensitive (gimlet->input_language_option_menu, TRUE);
    }

  input_language_policy_update (gimlet);
}
#endif

#define IM_KEY_DIR    "/desktop/gnome/input_methods"
#define ENABLE_IM_KEY IM_KEY_DIR "/support"
#define ENABLE_STATUS_KEY IM_KEY_DIR "/status"
#define ENABLE_LOOKUP_KEY IM_KEY_DIR "/lookup"
#define STATUS_PLACEMENT_KEY IM_KEY_DIR "/status_placement"

/* static const char *enabled = "enabled"; */
static const char *disabled = "disabled";

static void
init_im_settings (GimletWindow *gimlet)
{
  gchar *str;

  str = NULL;
  str = gconf_client_get_string (default_client,
				 ENABLE_IM_KEY, NULL);
  if (str && strcmp (str, disabled) == 0)
    gimlet->im_enabled = FALSE;
  else
    gimlet->im_enabled = TRUE;
  g_free (str);

  str = NULL;
  str = gconf_client_get_string (default_client,
				 ENABLE_STATUS_KEY, NULL);
  if (str && strcmp (str, disabled) == 0)
    gimlet->status_enabled = FALSE;
  else
    gimlet->status_enabled = TRUE;
  g_free (str);

  str = NULL;
  str = gconf_client_get_string (default_client,
				 ENABLE_LOOKUP_KEY, NULL);
  if (str && strcmp (str, disabled) == 0)
    gimlet->lookup_enabled = FALSE;
  else
    gimlet->lookup_enabled = TRUE;
  g_free (str);

  str = NULL;
  str = gconf_client_get_string (default_client,
				 STATUS_PLACEMENT_KEY, NULL);
  gimlet->status_placement = gimlet_status_placement (str);

  g_free (str);

}

static void
im_setting_changed (GConfClient  *client,
		    guint         cnxn_id,
		    GConfEntry   *entry,
		    GimletWindow *gimlet)
{
  gchar *str = NULL;

  if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
    return;

  if (strcmp (entry->key, ENABLE_IM_KEY) == 0)
    {
      str = g_strdup (gconf_value_get_string (entry->value));
      if (strcmp (str, disabled) == 0)
	gimlet->im_enabled = FALSE;
      else
	gimlet->im_enabled = TRUE;
    }
  else if (strcmp (entry->key, ENABLE_STATUS_KEY) == 0)
    {
      str = g_strdup (gconf_value_get_string (entry->value));
      if (strcmp (str, disabled) == 0)
	gimlet->status_enabled = FALSE;
      else
	gimlet->status_enabled = TRUE;
    }
  else if (strcmp (entry->key, ENABLE_LOOKUP_KEY) == 0)
    {
      str = g_strdup (gconf_value_get_string (entry->value));
      if (strcmp (str, disabled) == 0)
	gimlet->lookup_enabled = FALSE;
      else
	gimlet->lookup_enabled = TRUE;
    }
  else if (strcmp (entry->key, STATUS_PLACEMENT_KEY) == 0)
    {
      str = g_strdup (gconf_value_get_string (entry->value));
      gimlet->status_placement = gimlet_status_placement (str);
    }
  gimlet_update_lang (gimlet);
  gimlet_status_show_or_hide (gimlet);
  g_free (str);
}

void
gimlet_preference_init (GimletWindow *gimlet)
{
  int int_value;

  panel_applet_add_preferences (gimlet->applet,
				"/schemas/apps/gimlet/preference",
				NULL);
  if (default_client == NULL)
    {
      default_client = gconf_client_get_default ();
      g_object_ref (G_OBJECT (default_client));
    }

  /* Input Language */
  int_value = panel_applet_gconf_get_int (gimlet->applet,
					  "input_language_policy", NULL);
  gimlet->input_lang_policy = int_value;

  gimlet->conversion_on_start = panel_applet_gconf_get_bool (gimlet->applet,
							     "conversion_on_start", NULL);

  /* input method settings */
  init_im_settings (gimlet);
  gconf_client_notify_add (default_client, ENABLE_IM_KEY,
			   (GConfClientNotifyFunc)im_setting_changed,
			   gimlet, NULL, NULL);
  gconf_client_notify_add (default_client, ENABLE_STATUS_KEY,
			   (GConfClientNotifyFunc)im_setting_changed,
			   gimlet, NULL, NULL);
  gconf_client_notify_add (default_client, STATUS_PLACEMENT_KEY,
			   (GConfClientNotifyFunc)im_setting_changed,
			   gimlet, NULL, NULL);
}

static void
response_callback (GtkWidget *window,
                   int        id,
                   void      *data)
{
  if (id == GTK_RESPONSE_HELP)
    gimlet_util_show_help ("imswitcher-prefs-inputlanguage",
			   GTK_WINDOW (window));
  else
    {
      gtk_widget_destroy (GTK_WIDGET (window));
    }
}

static void
conversion_on_start_checkbutton_toggled (GtkToggleButton *button,
					 GtkWidget *dialog)
{
  GimletWindow *gimlet = g_object_get_data (G_OBJECT (dialog), "gimlet");

  if (gtk_toggle_button_get_active (button))
    gimlet->conversion_on_start = TRUE;
  else
    gimlet->conversion_on_start = FALSE;

  panel_applet_gconf_set_bool (PANEL_APPLET (gimlet->applet),
			       "conversion_on_start",
			       gimlet->conversion_on_start,
			       NULL);
  return;
}

#ifdef MEANINGLESS_OPTION_PERHAPS
static void
activate_cb (GtkWidget *menuitem, GimletWindow *gimlet)
{
  if (GTK_CHECK_MENU_ITEM (menuitem)->active)
    {
      gchar *iiim_lang;
      gchar *name;
      gchar *conversion_mode;

      iiim_lang = g_object_get_data (G_OBJECT (menuitem), "iiim-lang-name");

      if (gimlet->iiim_lang_in_option_menu)
	g_free (gimlet->iiim_lang_in_option_menu);
      gimlet->iiim_lang_in_option_menu = g_strdup (iiim_lang);
    }
}

static void
add_languages_in_option_menu (GimletWindow *gimlet)
{
  GtkWidget *menu;
  GtkWidget *menuitem;
  GSList *group = NULL;
  GSList *active_languages;
  GSList *tmp;

  menu = gtk_menu_new ();
  group = NULL;

  if (gimlet->quick_access_menu == NULL)
    gimlet_quick_access_menu_init (gimlet);

  active_languages = gimlet->quick_access_menu->active_languages;

  tmp = active_languages;
  while (tmp != NULL)
    {
      char *name;
      char *iiim_lang_name;
      name = gimlet_language_get_name (tmp->data);
      iiim_lang_name = gimlet_language_get_iiim_lang_name (tmp->data);

      menuitem = gtk_radio_menu_item_new_with_label (group, name);

      if ((gimlet->iiim_lang_in_option_menu == NULL && group == NULL) ||
          (gimlet->iiim_lang_in_option_menu &&
           strcmp (iiim_lang_name, gimlet->iiim_lang_in_option_menu) == 0))
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
					TRUE);
       
      group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));

      g_object_set_data (G_OBJECT (menuitem), "iiim-lang-name",
			 iiim_lang_name);
      g_object_set_data (G_OBJECT (menuitem), "iiim-display-name",
			 name);
      g_signal_connect (menuitem, "activate",
			G_CALLBACK (activate_cb), gimlet);

      gtk_widget_show (menuitem);
      gtk_menu_shell_append (GTK_MENU_SHELL(menu), menuitem);

      tmp = tmp->next;
    }

  gtk_option_menu_set_menu (GTK_OPTION_MENU (gimlet->input_language_option_menu), menu);

}
#endif

/* public */
GtkWidget*
gimlet_preference_dialog_new (GtkWindow *transient_parent,
			      GimletWindow *gimlet)
{
  GladeXML *xml;
  GtkWidget *w;
  GtkWidget *dialog;

  xml = gimlet_util_load_glade_file (GIMLET_GLADE_FILE,
				     "preference-dialog",
				     transient_parent);
  if (xml == NULL)
    return NULL;

  /* The dialog itself */
  dialog = glade_xml_get_widget (xml, "preference-dialog");
  g_object_set_data (G_OBJECT (dialog), "gimlet", gimlet);

  gimlet_util_set_unique_role (GTK_WINDOW (dialog), "gimlet-preferences");

  g_signal_connect (G_OBJECT (dialog), "response",
                    G_CALLBACK (response_callback),
                    NULL);

  /* Input Language */

#ifdef MEANINGLESS_OPTION_PERHAPS
  w = glade_xml_get_widget (xml, "default-input-language-option");
  gimlet->input_language_option_menu = w;
  gtk_widget_set_sensitive (gimlet->input_language_option_menu, FALSE);

  add_languages_in_option_menu (gimlet);

  w = glade_xml_get_widget (xml, "follow-current-locale");
  g_signal_connect (G_OBJECT (w), "toggled",
		    G_CALLBACK (on_follow_current_locale_toggled), gimlet);
  if (gimlet->input_lang_policy == FOLLOW_CURRENT_LOCALE)
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);

  w = glade_xml_get_widget (xml, "follow-option-menu");
  g_signal_connect (G_OBJECT (w), "toggled",
		    G_CALLBACK (on_follow_option_menu_toggled), gimlet);
  if (gimlet->input_lang_policy == FOLLOW_OPTION_MENU)
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);

#endif

  w = glade_xml_get_widget (xml, "follow-application");
  g_signal_connect (G_OBJECT (w), "toggled",
		    G_CALLBACK (on_follow_application_toggled), gimlet);
  if (gimlet->input_lang_policy == FOLLOW_APPLICATION)
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);

  w = glade_xml_get_widget (xml, "follow-quick-access-menu");
  g_signal_connect (G_OBJECT (w), "toggled",
		    G_CALLBACK (on_follow_quick_access_menu_toggled), gimlet);
  if (gimlet->input_lang_policy == FOLLOW_QUICK_ACCESS_MENU)
    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);

  w = glade_xml_get_widget (xml, "conversion_on_start_checkbutton");
  g_object_set_data (G_OBJECT (dialog),
                     "conversion-on-start-checkbutton",
                     w);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w),
				gimlet->conversion_on_start);

  conversion_on_start_checkbutton_toggled (GTK_TOGGLE_BUTTON (w), dialog);
	
  g_signal_connect (G_OBJECT (w), "toggled", 
		    G_CALLBACK (conversion_on_start_checkbutton_toggled), 
		    dialog);
  return dialog;
}
