/*
 *  Copyright (C) 2000 Nate Case 
 *
 *  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, 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 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 "galeon.h"
#include "mozilla_notifiers.h"
#include "prefs_strings.h"
#include "mozilla.h"
#include "prefs.h"
#include "MozRegisterComponents.h"
#include "mozilla_prefs.h"

#include <string.h>
#include <locale.h>
#include <libgnome/gnome-i18n.h>
#include <stdlib.h>

void
mozilla_own_colors_notifier(GConfClient *client,
			    guint cnxn_id,
			    GConfEntry *entry,
			    gpointer user_data);
void
mozilla_own_fonts_notifier(GConfClient *client,
			   guint cnxn_id,
			   GConfEntry *entry,
			   gpointer user_data);

void
mozilla_animate_notifier(GConfClient *client,
			 guint cnxn_id,
			 GConfEntry *entry,
			 gpointer user_data);
void
generic_mozilla_string_notifier(GConfClient *client,
				guint cnxn_id,
				GConfEntry *entry,
				gpointer user_data);
void
generic_mozilla_int_notifier(GConfClient *client,
			     guint cnxn_id,
			     GConfEntry *entry,
			     gpointer user_data);
void
generic_mozilla_bool_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data);
void
mozilla_http_version_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data);

void
mozilla_allow_popups_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data);

void
mozilla_language_notifier(GConfClient *client,
			  guint cnxn_id,
			  GConfEntry *entry,
			  gpointer user_data);

void
mozilla_autodetect_charset_notifier(GConfClient *client,
				    guint cnxn_id,
				    GConfEntry *entry,
				    gpointer user_data);

void
mozilla_default_font_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data);

void
mozilla_ftp_notifier(GConfClient *client,
		     guint cnxn_id,
		     GConfEntry *entry,
		     gpointer user_data);


void
mozilla_ghelp_notifier(GConfClient *client,
		       guint cnxn_id,
		       GConfEntry *entry,
		       gpointer user_data);

void
mozilla_user_agent_notifier(GConfClient *client,
			    guint cnxn_id,
			    GConfEntry *entry,
			    gpointer user_data);

static char * 
get_bracketed_string (char *str);

/* Keeps the list of the notifiers we installed for mozilla prefs */
/* to be able to remove them when exiting */
GList *mozilla_notifiers = NULL;

static const struct 
{
	char *gconf_key;
	GConfClientNotifyFunc func;
	gpointer user_data;
}
notifiers [] =
{
	{ CONF_FILTERING_JAVA_ENABLED, generic_mozilla_bool_notifier,
	  "security.enable_java"},
	{ CONF_FILTERING_JAVASCRIPT_ENABLED, generic_mozilla_bool_notifier,
	  "javascript.enabled"},
	{ CONF_RENDERING_USE_OWN_COLORS, mozilla_own_colors_notifier,
	  NULL},
	{ CONF_RENDERING_USE_OWN_FONTS, mozilla_own_fonts_notifier,
	  NULL},
	{ CONF_FILTERING_IMAGE_LOADING_TYPE, generic_mozilla_int_notifier,
	  "network.image.imageBehavior"},
	{ CONF_FILTERING_ANIMATE_TYPE, mozilla_animate_notifier,
	  NULL},
	{ CONF_NETWORK_PROXY_MODE, generic_mozilla_int_notifier,
	  "network.proxy.type"},
	{ CONF_RENDERING_BG_COLOR, generic_mozilla_string_notifier,
	  "browser.display.background_color"},
	{ CONF_RENDERING_TEXT_COLOR, generic_mozilla_string_notifier,
	  "browser.display.foreground_color"},
	{ CONF_RENDERING_UNVISITED_LINKS, generic_mozilla_string_notifier,
	  "browser.anchor_color"},
	{ CONF_RENDERING_VISITED_LINKS, generic_mozilla_string_notifier,
	  "browser.visited_color"},
	{ CONF_RENDERING_UNDERLINE_LINKS, generic_mozilla_bool_notifier,
	  "browser.underline_anchors"},
	{ CONF_NETWORK_PROXY_AUTO_URL, generic_mozilla_string_notifier,
	  "network.proxy.autoconfig_url"},
	{ CONF_NETWORK_HTTP_PROXY, generic_mozilla_string_notifier,
	  "network.proxy.http"},
	{ CONF_NETWORK_FTP_PROXY, generic_mozilla_string_notifier,
	  "network.proxy.ftp"},
	{ CONF_NETWORK_SSL_PROXY, generic_mozilla_string_notifier,
	  "network.proxy.ssl"},
	{ CONF_NETWORK_HTTP_PROXY_PORT, generic_mozilla_int_notifier,
	  "network.proxy.http_port"},
	{ CONF_NETWORK_FTP_PROXY_PORT, generic_mozilla_int_notifier,
	  "network.proxy.ftp_port"},
	{ CONF_NETWORK_SSL_PROXY_PORT, generic_mozilla_int_notifier,
	  "network.proxy.ssl_port"},
	{ CONF_NETWORK_NO_PROXIES_FOR, generic_mozilla_string_notifier,
	  "network.proxy.no_proxies_on"},
	{ CONF_NETWORK_PROXY_KA, generic_mozilla_bool_notifier,
	  "network.http.proxy.keep-alive"},
	{ CONF_NETWORK_USER_AGENT, mozilla_user_agent_notifier,
	  "general.useragent.override"},
	{ CONF_NETWORK_MEMORY_CACHE, generic_mozilla_int_notifier,
	  "browser.cache.memory.capacity"},
	{ CONF_NETWORK_DISK_CACHE, generic_mozilla_int_notifier,
	  "browser.cache.disk.capacity"},
	{ CONF_NETWORK_CACHE_COMPARE, generic_mozilla_int_notifier,
	  "browser.cache.check_doc_frequency"},
	{ CONF_MOUSE_WHEEL_NOKEY_ACTION, generic_mozilla_int_notifier,
	"mousewheel.withnokey.action"},
	{ CONF_MOUSE_WHEEL_SHIFT_ACTION, generic_mozilla_int_notifier,
	"mousewheel.withshiftkey.action"},
	{ CONF_MOUSE_WHEEL_ALT_ACTION, generic_mozilla_int_notifier,
	"mousewheel.withaltkey.action"},
	{ CONF_MOUSE_WHEEL_CTRL_ACTION, generic_mozilla_int_notifier,
	"mousewheel.withcontrolkey.action"},
	{ CONF_MOUSE_WHEEL_NOKEY_DEF_STEP, generic_mozilla_int_notifier,
	"mousewheel.withnokey.sysnumlines"},
	{ CONF_MOUSE_WHEEL_CTRL_DEF_STEP, generic_mozilla_int_notifier,
	"mousewheel.withcontrolkey.sysnumlines"},
	{ CONF_MOUSE_WHEEL_ALT_DEF_STEP, generic_mozilla_int_notifier,
	"mousewheel.withaltkey.sysnumlines"},
	{ CONF_MOUSE_WHEEL_SHIFT_DEF_STEP, generic_mozilla_int_notifier,
	"mousewheel.withshiftkey.sysnumlines"},
	{ CONF_MOUSE_WHEEL_NOKEY_STEP, generic_mozilla_int_notifier,
	"mousewheel.withnokey.numlines"},
	{ CONF_MOUSE_WHEEL_CTRL_STEP, generic_mozilla_int_notifier,
	"mousewheel.withcontrolkey.numlines"},
	{ CONF_MOUSE_WHEEL_ALT_STEP, generic_mozilla_int_notifier,
	"mousewheel.withaltkey.numlines"},
	{ CONF_MOUSE_WHEEL_SHIFT_STEP, generic_mozilla_int_notifier,
	"mousewheel.withshiftkey.numlines"},
	{ CONF_PERSISTENT_COOKIE_WARN, generic_mozilla_bool_notifier,
	"network.cookie.warnAboutCookies"},
	{ CONF_PERSISTENT_COOKIES_BEHAVIOR, generic_mozilla_int_notifier,
	"network.cookie.cookieBehavior"},
	{ CONF_PERSISTENT_PASSWORDS_SAVE, generic_mozilla_bool_notifier,
	"signon.rememberSignons"},
	{ CONF_NETWORK_HTTP_VERSION, mozilla_http_version_notifier,
	NULL},
	{ CONF_FILTERING_ALLOW_POPUPS, mozilla_allow_popups_notifier,
	NULL},
	{ CONF_DOWNLOADING_DIR, generic_mozilla_string_notifier,
	"browser.download.dir"},
	{ CONF_LANGUAGE_DEFAULT_CHARSET, generic_mozilla_string_notifier,
	"intl.charset.default"},
	{ CONF_RENDERING_LANGUAGE, mozilla_language_notifier,
	NULL},
	{ CONF_LANGUAGE_AUTODETECT_CHARSET, mozilla_autodetect_charset_notifier,
	NULL},
	{ CONF_RENDERING_DEFAULT_FONT, mozilla_default_font_notifier,
	NULL},
	{ CONF_DOWNLOADING_EXTERNAL_FTP, mozilla_ftp_notifier,
	NULL},
	{ CONF_GHELP_USE_GALEON, mozilla_ghelp_notifier,
	NULL},
	{NULL, NULL, NULL}
};

void mozilla_notifiers_init() 
{
	int i;

	for (i = 0; notifiers[i].gconf_key != NULL; i++)
	{
		galeon_notification_add(
			notifiers[i].gconf_key,
			(GConfClientNotifyFunc)notifiers[i].func,
			notifiers[i].user_data,
			&mozilla_notifiers);
	}
}

void mozilla_notifiers_set_defaults() 
{
	GConfClient* client = eel_gconf_client_get_global();
	GConfValue* value;
	int i;

	for (i = 0; notifiers[i].gconf_key != NULL; i++)
	{
		value = gconf_client_get 
			(client, notifiers[i].gconf_key, NULL);
		if (value)
		{
			gconf_client_set (client, notifiers[i].gconf_key,
					  value, NULL);
			gconf_value_free (value);
		}
	}
}
	
/**
 * generic_mozilla_string_notify: update mozilla pref to match galeon prefs.
 * 	user_data should match the mozilla key
 */
void
generic_mozilla_string_notifier(GConfClient *client,
				guint cnxn_id,
				GConfEntry *entry,
				gpointer user_data)
{
	const gchar *value;
	g_assert(user_data != NULL);
	/* determine type of gconf key, in order of likelyhood */
	switch (entry->value->type)
	{
		case GCONF_VALUE_STRING:
			value = gconf_value_get_string(entry->value);
			if (value)
			{
				mozilla_preference_set
					(user_data,
					 gconf_value_get_string(entry->value));
			}
			break;

		default:	
			g_warning("Unsupported variable type");
	} 
}


/**
 * generic_mozilla_int_notify: update mozilla pref to match galeon prefs.
 * 	user_data should match the mozilla key
 */
void
generic_mozilla_int_notifier(GConfClient *client,
			     guint cnxn_id,
			     GConfEntry *entry,
			     gpointer user_data)
{
	g_assert(user_data != NULL);

	/* determine type of gconf key, in order of likelyhood */
	switch (entry->value->type)
	{
		case GCONF_VALUE_INT:	mozilla_preference_set_int(user_data,
						gconf_value_get_int(entry->value));
					break;
		case GCONF_VALUE_BOOL:	mozilla_preference_set_int(user_data,
						gconf_value_get_bool(entry->value));
					break;
		case GCONF_VALUE_STRING:	mozilla_preference_set(user_data,
						gconf_value_get_string(entry->value));
					break;
		default:	g_warning("Unsupported variable type");
	}
}


/**
 * generic_mozilla_bool_notify: update mozilla pref to match galeon prefs.
 * 	user_data should match the mozilla key
 */
void
generic_mozilla_bool_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data)
{
	g_assert(user_data != NULL);
	/* determine type of gconf key, in order of likelyhood */
	switch (entry->value->type)
	{
		case GCONF_VALUE_BOOL:	mozilla_preference_set_boolean(user_data,
						gconf_value_get_bool(entry->value));
					break;
		case GCONF_VALUE_INT:	mozilla_preference_set_int(user_data,
						gconf_value_get_int(entry->value));
					break;
		default:	g_warning("Unsupported variable type");
	}
}


void
mozilla_own_colors_notifier(GConfClient *client,
			    guint cnxn_id,
			    GConfEntry *entry,
			    gpointer user_data)
{
	mozilla_preference_set_boolean("browser.display.use_document_colors",
				       !gconf_value_get_bool(entry->value));
}

void
mozilla_own_fonts_notifier(GConfClient *client,
			   guint cnxn_id,
			   GConfEntry *entry,
			   gpointer user_data)
{
	mozilla_preference_set_int("browser.display.use_document_fonts",
				   !gconf_value_get_bool(entry->value));
}

void
mozilla_animate_notifier(GConfClient *client,
			 guint cnxn_id,
			 GConfEntry *entry,
			 gpointer user_data)
{
	static const gchar *type[] =
	{
		"normal",
		"once",
		"none"
	};

	mozilla_preference_set ("image.animation_mode",
				type[gconf_value_get_int(entry->value)]);
}

void
mozilla_http_version_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data)
{
	gchar *http_version = NULL;

	switch (eel_gconf_get_integer (CONF_NETWORK_HTTP_VERSION))
	{
		case 0: http_version = g_strdup ("1.0");
			break;
		case 1: http_version = g_strdup ("1.1");
			break;
	}

	mozilla_preference_set ("network.http.version", http_version);

	g_free (http_version);
}

void
mozilla_allow_popups_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data)
{
#ifndef ENABLE_EXPERIMENTAL_FILTERS
	gboolean new_val = eel_gconf_get_boolean(CONF_FILTERING_ALLOW_POPUPS);
	mozilla_preference_set_boolean ("dom.disable_open_during_load", 
					!new_val);
#endif //ENABLE_EXPERIMENTAL_FILTERS
}

void
mozilla_language_notifier(GConfClient *client,
			  guint cnxn_id,
			  GConfEntry *entry,
			  gpointer user_data)
{
	gchar *languages;
	GSList *language_list ,*cur_lang_list;

	language_list = eel_gconf_get_string_list (CONF_RENDERING_LANGUAGE);

	languages = NULL;
	cur_lang_list = language_list;
	while (cur_lang_list != NULL) {
		char *lang, *tmp;

		lang = get_bracketed_string (cur_lang_list->data);
		if (lang == NULL)
			lang = g_strdup(cur_lang_list->data);
		if (languages == NULL)
			languages = lang;
		else {
			tmp = languages;
			languages = g_strconcat(languages, ",", lang, NULL);
			g_free(lang);
			g_free(tmp);
		}
		g_free(cur_lang_list->data);
		cur_lang_list = cur_lang_list->next;
	}

	if (languages == NULL)
	{
		languages = g_strdup ("");
	}
	mozilla_preference_set ("intl.accept_languages", languages);
	g_free (languages);

	g_slist_free(language_list);
}

/**
 * get_bracketed_string: get the string between brackets. ex: language (string)
 */
static char * 
get_bracketed_string (char *str)
{
	char *begin;
	char *end;

	begin = strchr (str,'(');
	end = strchr (str,')');

	if (begin && end)
	{
		begin ++;
		return g_strndup(begin, end - begin);
	}
	else 
	{
		return NULL;
	}
}

static char *autodetect_charset_prefs[] =
{
        "",
        "zh_parallel_state_machine",
        "cjk_parallel_state_machine",
        "ja_parallel_state_machine",
        "ko_parallel_state_machine",
        "ruprob",
        "zhcn_parallel_state_machine",
        "zhtw_parallel_state_machine",
        "ukprob"
};

void
mozilla_autodetect_charset_notifier(GConfClient *client,
				    guint cnxn_id,
				    GConfEntry *entry,
				    gpointer user_data)
{
	int charset = eel_gconf_get_integer (CONF_LANGUAGE_AUTODETECT_CHARSET);
	mozilla_preference_set ("intl.charset.detector", 
				autodetect_charset_prefs[charset]);
}

void
mozilla_default_font_notifier(GConfClient *client,
			      guint cnxn_id,
			      GConfEntry *entry,
			      gpointer user_data)
{
	const gchar *font_types [] = {"serif","sans-serif"};
	int default_font;

	default_font = eel_gconf_get_integer (CONF_RENDERING_DEFAULT_FONT);
	mozilla_preference_set ("font.default", font_types[default_font]);
}

void
mozilla_ftp_notifier(GConfClient *client,
		     guint cnxn_id,
		     GConfEntry *entry,
		     gpointer user_data)
{
	/* Register/Unregister the FTP Handler as appropriate */
	if ((eel_gconf_get_integer(CONF_DOWNLOADING_EXTERNAL_FTP) == 1) &&
	    !preferences_galeon_used_by_gnome_for_protocol ("ftp"))
	{
		mozilla_register_FtpProtocolHandler ();
	}
	else
	{
		mozilla_unregister_FtpProtocolHandler ();
	}
}

void
mozilla_ghelp_notifier(GConfClient *client,
		       guint cnxn_id,
		       GConfEntry *entry,
		       gpointer user_data)
{
	/* Register/Unregister the gHelp Handlers as appropriate */
	if (eel_gconf_get_boolean(CONF_GHELP_USE_GALEON) == TRUE ||
	    preferences_galeon_used_by_gnome_for_protocol ("man") ||
	    preferences_galeon_used_by_gnome_for_protocol ("info") ||
	    preferences_galeon_used_by_gnome_for_protocol ("ghelp") ||
	    preferences_galeon_used_by_gnome_for_protocol ("gnome-help"))
	{
		mozilla_register_gHelpProtocolHandlers ();
	}
	else
	{
		mozilla_unregister_gHelpProtocolHandlers ();
	}
}

void
mozilla_user_agent_notifier (GConfClient *client,
			     guint cnxn_id,
			     GConfEntry *entry,
			     gpointer user_data)
{
	switch (entry->value->type)
	{
		case GCONF_VALUE_STRING:
			mozilla_prefs_set_user_agent ();
			break;

		default:	
			g_warning ("Unsupported variable type");
			break;
	}
}
