// -*- 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>
#include <nsBuildID.h>
#include <xpcom/nsCOMPtr.h>
#include <pref/nsIPrefService.h>
#include <uconv/nsICharsetConverterManager.h>
#if MOZILLA_SNAPSHOT < 10
#	include <uconv/nsICharsetConverterManager2.h>
#endif
#include <xpcom/nsISupportsPrimitives.h>
#include <gfx/nsIFontList.h>
#include <necko/nsNetUtil.h>

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


extern "C" gboolean
mozilla_prefs_init (void)
{
	const char *home_path;
	char full_path[256];

     	home_path = g_get_home_dir();
	if (!home_path) {
		g_error("Failed to get HOME");
		return FALSE;
	}

	g_snprintf(full_path, G_N_ELEMENTS(full_path),
		   "%s/%s", home_path, ".kazehakase/mozilla");
	gtk_moz_embed_set_profile_path(full_path, "kazehakase");

	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 (void)
{
	char *value;
	gchar user_agent[1024];
	gboolean override = FALSE, typeahead = FALSE;
	gchar proxy_name[1024];
	gboolean conf_exist = FALSE;
	KzProxyItem *item = NULL;

	// set user agent name
	KZ_CONF_GET("Global", "override_user_agent", override, BOOL);
	if (override)
		override = KZ_CONF_GET("Global", "user_agent",
				       user_agent, STRING);
	if (!override)
		build_user_agent(user_agent, G_N_ELEMENTS(user_agent));
	mozilla_prefs_set_string ("general.useragent.override", user_agent);

	// set typeahead or not
	KZ_CONF_GET("Mozilla", "typeahead", typeahead, BOOL);
	mozilla_prefs_set_boolean ("accessibility.typeaheadfind",
				   typeahead);	
	if (!mozilla_prefs_get_string("kazehakase.font.language", &value))
	{
		mozilla_prefs_set_string("kazehakase.font.language",
					 "x-western");
	}
	else
	{
		g_free(value);
	}

	conf_exist = KZ_CONF_GET("Global", "proxy_name", proxy_name, STRING);
	if (conf_exist)
		item = kz_proxy_find(proxy_name);
	if (item)
	{
		mozilla_prefs_set_proxy(item);
		g_object_unref(G_OBJECT(item));
	}
}


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,
			     char **default_font)
{
	nsresult rv;

	nsCOMPtr<nsIFontList> mozFontList;
	mozFontList = do_CreateInstance("@mozilla.org/gfx/fontlist;1", &rv);
	if(NS_FAILED(rv)) return FALSE;

	nsCOMPtr<nsISimpleEnumerator> fontEnum;
	mozFontList->AvailableFonts(NS_ConvertUTF8toUCS2(lang_group).get(),
				    NS_ConvertUTF8toUCS2(font_type).get(),
				    getter_AddRefs(fontEnum));
	if(NS_FAILED(rv)) return FALSE;

	if (font_list)
	{
		GList *list = NULL;
		PRBool enumResult;

		for(fontEnum->HasMoreElements(&enumResult) ;
		    enumResult == PR_TRUE;
		    fontEnum->HasMoreElements(&enumResult))
		{
			nsCOMPtr<nsISupportsString> fontName;
			fontEnum->GetNext(getter_AddRefs(fontName));
			if(NS_FAILED(rv)) return FALSE;

			nsString fontString;
			fontName->GetData(fontString);

			char *gFontString;
			gFontString = g_strdup(NS_ConvertUCS2toUTF8(fontString).get());
			list = g_list_prepend(list, gFontString);
		}
		*font_list = g_list_reverse(list);
	}

	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_proxy (KzProxyItem *item)
{
	gboolean use_proxy, use_same_proxy;
	gchar *name, *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),
		     "name", &name,
		     "use_proxy", &use_proxy,
		     "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);

	if (!use_proxy)
	{
		mozilla_prefs_set_int("network.proxy.type", 0);
		return;
	}

	mozilla_prefs_set_int   ("network.proxy.type",          1);
	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)
	{
		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);
}
