// -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-

//
//  Copyright (C) 2002-2003 Hiroyuki Ikezoe
//  Copyright (C) 2003 Takuro Ashie
//
//  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 "mozilla-prefs.h"

#include <sys/utsname.h>
#include <gtkmozembed.h>
#define MOZILLA_STRICT_API
#include <nsEmbedString.h>
#undef MOZILLA_STRICT_API
#include <nsBuildID.h>
#include <nsCOMPtr.h>
#include <nsIPrefService.h>
#include <nsISupportsPrimitives.h>
#define MOZILLA_INTERNAL_API
#include <nsIServiceManager.h>
#undef MOZILLA_INTERNAL_API
#if 1
#include <nsIFontEnumerator.h>
#endif
#include <nsISimpleEnumerator.h>
#include <nsIFontList.h>
#include <nsMemory.h>

#include "kazehakase.h"
#include "kz-profile.h"
#include "kz-proxy-item.h"


extern "C" gboolean
mozilla_prefs_init (void)
{
	gchar *full_path;

	full_path = g_build_filename(g_get_home_dir(), 
		   		     "."PACKAGE,
				     "mozilla",
				     NULL);
	gtk_moz_embed_set_profile_path(full_path, "kazehakase");

	g_free(full_path);

	return TRUE;
}


static void
build_user_agent (gchar *user_agent, gint size)
{
	struct utsname name;
	gchar *system;

	if (uname (&name) >= 0)
	{
		system = g_strdup_printf ("%s %s",
					  name.sysname, 
					  name.machine);
	}
	else
	{
		system = g_strdup ("Unknown");
	}
		
	g_snprintf(user_agent, size,
		   "Mozilla/5.0 (X11; %s; U;) Gecko/%d Kazehakase/"  VERSION,
		   system,
		   NS_BUILD_ID/100);
	g_free (system);
}


extern "C" void 
mozilla_prefs_set (KzProfile *profile)
{
	char *value;
	gchar user_agent[1024];
	gboolean override = FALSE, use_proxy = FALSE;
	gchar proxy_name[1024];
	gboolean conf_exist = FALSE, use_proxy_exist = FALSE;
	KzProxyItem *item = NULL;

	// set user agent name
	kz_profile_get_value(profile, "Global", "override_user_agent", 
			     &override, sizeof(gboolean),
			     KZ_PROFILE_VALUE_TYPE_BOOL);
	if (override)
	{
		override = kz_profile_get_value(profile, "Global", "user_agent", 
			   			&user_agent, sizeof(user_agent),
						KZ_PROFILE_VALUE_TYPE_STRING);
	}
	if (!override)
		build_user_agent(user_agent, G_N_ELEMENTS(user_agent));
	mozilla_prefs_set_string ("general.useragent.override", user_agent);

	if (!mozilla_prefs_get_string("kazehakase.font.language", &value))
	{
		mozilla_prefs_set_string("kazehakase.font.language",
					 "x-western");
	}
	else
	{
		g_free(value);
	}

	// set default charset to ISO-8859-1
	if (!mozilla_prefs_get_string("intl.charset.default", &value))
	{
		mozilla_prefs_set_string("intl.charset.default",
					 "ISO-8859-1");
	}
	else
	{
		if (!strcmp(value, "chrome://global-platform/locale/intl.properties"))
		{
			mozilla_prefs_set_string("intl.charset.default",
						 "ISO-8859-1");
		}
		g_free(value);
	}
	
	use_proxy_exist = kz_profile_get_value(profile, "Global", "use_proxy", 
					       &use_proxy, sizeof(gboolean),
					       KZ_PROFILE_VALUE_TYPE_BOOL);
	conf_exist = kz_profile_get_value(profile, "Global" , "proxy_name",
					  &proxy_name, sizeof(proxy_name),
					  KZ_PROFILE_VALUE_TYPE_STRING);

	if (!use_proxy_exist && conf_exist)
		use_proxy = TRUE;
	if (use_proxy)
	{
		mozilla_prefs_set_use_proxy(TRUE);
		if (conf_exist)
			item = kz_proxy_find(proxy_name);
		if (item)
		{
			mozilla_prefs_set_proxy(item);
			g_object_unref(G_OBJECT(item));
		}
	}
	else
	{
		mozilla_prefs_set_use_proxy(FALSE);
	}
}


extern "C" gboolean
mozilla_prefs_get_string(const char *preference_name, char **value)
{
	g_return_val_if_fail(preference_name != NULL, FALSE);

	g_return_val_if_fail(value, FALSE);

	nsCOMPtr<nsIPrefService> prefService = 
				do_GetService (NS_PREFSERVICE_CONTRACTID);
	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));

	if (pref)
	{
		nsresult rv = pref->GetCharPref(preference_name, value);
		return NS_SUCCEEDED(rv) ? TRUE : FALSE;
	}

	return FALSE;
}


extern "C" gboolean
mozilla_prefs_get_int(const char *preference_name, int *value)
{
	g_return_val_if_fail(preference_name != NULL, FALSE);

	g_return_val_if_fail(value, FALSE);

	nsCOMPtr<nsIPrefService> prefService = 
				do_GetService(NS_PREFSERVICE_CONTRACTID);
	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));

	if (pref)
	{
		nsresult rv = pref->GetIntPref(preference_name, value);
		return NS_SUCCEEDED(rv) ? TRUE : FALSE;
	}

	return FALSE;
}


extern "C" gboolean
mozilla_prefs_get_boolean(const char *preference_name, gboolean *value)
{
	g_return_val_if_fail(preference_name != NULL, FALSE);

	g_return_val_if_fail(value, FALSE);

	nsCOMPtr<nsIPrefService> prefService = 
				do_GetService(NS_PREFSERVICE_CONTRACTID);
	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));

	if (pref)
	{
		nsresult rv = pref->GetBoolPref(preference_name, value);
		return NS_SUCCEEDED(rv) ? TRUE : FALSE;
	}

	return FALSE;
}


//
// this function is picked from galeon-1.2.7
// mozilla_preference_set: set a string mozilla preference
//
extern "C" gboolean
mozilla_prefs_set_string(const char *preference_name, const char *new_value)
{
	g_return_val_if_fail(preference_name != NULL, FALSE);

	// It is legitimate to pass in a NULL value sometimes. So let's not
	// assert and just check and return.
	if (!new_value) return FALSE;

	nsCOMPtr<nsIPrefService> prefService = 
				do_GetService(NS_PREFSERVICE_CONTRACTID);
	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));

	if (pref)
	{
		nsresult rv = pref->SetCharPref(preference_name, new_value);
		return NS_SUCCEEDED(rv) ? TRUE : FALSE;
	}

	return FALSE;
}


//
// this function is picked from galeon-1.2.7
// mozilla_preference_set_boolean: set a boolean mozilla preference
//
extern "C" gboolean
mozilla_prefs_set_boolean (const char *preference_name,
			   gboolean new_boolean_value)
{
	g_return_val_if_fail(preference_name != NULL, FALSE);
  
	nsCOMPtr<nsIPrefService> prefService = 
				do_GetService(NS_PREFSERVICE_CONTRACTID);
	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));
  
	if (pref)
	{
		nsresult rv = pref->SetBoolPref(preference_name,
				new_boolean_value ? PR_TRUE : PR_FALSE);
		return NS_SUCCEEDED(rv) ? TRUE : FALSE;
	}

	return FALSE;
}


//
// this function is picked from galeon-1.2.7
// mozilla_preference_set_int: set an integer mozilla preference
//
extern "C" gboolean
mozilla_prefs_set_int (const char *preference_name, int new_int_value)
{
	g_return_val_if_fail(preference_name != NULL, FALSE);

	nsCOMPtr<nsIPrefService> prefService = 
				do_GetService(NS_PREFSERVICE_CONTRACTID);
	nsCOMPtr<nsIPrefBranch> pref;
	prefService->GetBranch("", getter_AddRefs(pref));

	if (pref)
	{
		nsresult rv = pref->SetIntPref(preference_name, new_int_value);
		return NS_SUCCEEDED(rv) ? TRUE : FALSE;
	}

	return FALSE;
}


//
//  Picked from Epiphany-0.7.0 (embed/mozilla/mozilla-embed-single.cpp).
//  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
//
gboolean
mozilla_prefs_get_font_list (const char *lang_group,
			     const char *font_type,
			     GList **font_list,
			     GList **all_font_list,
			     char **default_font)
{
	nsresult rv;
	PRUint32 count;
	PRUnichar **fontArray;

	nsCOMPtr<nsIFontEnumerator> mozFontEnumerator;
	mozFontEnumerator = do_CreateInstance("@mozilla.org/gfx/fontenumerator;1");
	NS_ENSURE_TRUE (mozFontEnumerator, FALSE);

	// get the language proper fonts
	rv = mozFontEnumerator->EnumerateFonts(lang_group, font_type,
					       &count, &fontArray);
	NS_ENSURE_SUCCESS (rv, FALSE);

	if (font_list)
	{
		GList *list = NULL;
		for (PRUint32 i = 0; i < count; i++)
		{
			char *gFontString;

			nsEmbedCString tmp;
			NS_UTF16ToCString(nsEmbedString(fontArray[i]),
					  NS_CSTRING_ENCODING_UTF8, tmp);
			gFontString = g_strdup(tmp.get());
			list = g_list_prepend(list, gFontString);
			nsMemory::Free (fontArray[i]);
		}
		*font_list = g_list_reverse(list);
	}
	nsMemory::Free (fontArray);

	// get all fonts
	rv = mozFontEnumerator->EnumerateAllFonts(&count, &fontArray);
	NS_ENSURE_SUCCESS (rv, FALSE);

	if (font_list)
	{
		GList *list = NULL;
		for (PRUint32 i = 0; i < count; i++)
		{
			char *gFontString;

			nsEmbedCString tmp;
			NS_UTF16ToCString(nsEmbedString(fontArray[i]),
					  NS_CSTRING_ENCODING_UTF8, tmp);
			if (!g_list_find_custom(*font_list, tmp.get(),
					        (GCompareFunc)strcmp))
			{
				gFontString = g_strdup(tmp.get());
				list = g_list_prepend(list, gFontString);
				nsMemory::Free (fontArray[i]);
			}
		}
		*all_font_list = g_list_reverse(list);
	}
	nsMemory::Free (fontArray);

	if (default_font != NULL)
	{
		char key[255];
		char *value = NULL;
		nsCOMPtr<nsIPrefService> prefService;

	        prefService = do_GetService(NS_PREFSERVICE_CONTRACTID);
		g_return_val_if_fail(prefService != NULL, FALSE);
	
	        nsCOMPtr<nsIPrefBranch> pref;
	        prefService->GetBranch("", getter_AddRefs(pref));
		g_return_val_if_fail(pref != NULL, FALSE);

		g_snprintf(key, sizeof(key), "font.name.%s.%s",
			   font_type, lang_group);
		
		pref->GetCharPref(key, &value);
		*default_font = g_strdup(value);
		nsMemory::Free(value);
	}

	return TRUE;
}


extern "C" void
mozilla_prefs_set_use_proxy (gboolean use)
{
	if (use)
		mozilla_prefs_set_int("network.proxy.type", 1);
	else
		mozilla_prefs_set_int("network.proxy.type", 0);
}


extern "C" void
mozilla_prefs_set_proxy (KzProxyItem *item)
{
	gboolean use_same_proxy;
	gchar *http_host, *https_host, *ftp_host, *no_proxies_on;
	guint http_port, https_port, ftp_port;

	g_return_if_fail(KZ_IS_PROXY_ITEM(item));

	g_object_get(G_OBJECT(item),
		     "use_same_proxy", &use_same_proxy,
		     "http_host", &http_host,
		     "http_port", &http_port,
		     "https_host", &https_host,
		     "https_port", &https_port,
		     "ftp_host", &ftp_host,
		     "ftp_port", &ftp_port,
		     "no_proxies_on", &no_proxies_on,
		     NULL);

	mozilla_prefs_set_use_proxy(TRUE);
	mozilla_prefs_set_string("network.proxy.http",          http_host);
	mozilla_prefs_set_int   ("network.proxy.http_port",     http_port);
	mozilla_prefs_set_string("network.proxy.no_proxies_on", no_proxies_on);

	if (use_same_proxy)
	{
		if (https_host)
			g_free(https_host);
		if (ftp_host)
			g_free(ftp_host);

		https_host = ftp_host = http_host;
		http_port = ftp_port = http_port;
	}
	else
	{
		if (!https_host)
		{
			https_host = "";
			https_port = 0;
		}
		if (!ftp_host)
		{
			ftp_host = "";
			ftp_port = 0;
		}
	}
	mozilla_prefs_set_string("network.proxy.ssl",      https_host);
	mozilla_prefs_set_int   ("network.proxy.ssl_port", https_port);
	mozilla_prefs_set_string("network.proxy.ftp",      ftp_host);
	mozilla_prefs_set_int   ("network.proxy.ftp_port", ftp_port);

	if (http_host)
		g_free(http_host);
	if (no_proxies_on)
		g_free(no_proxies_on);
}

