// -*- 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.
//

#ifdef HAVE_CONFIG_H
#	include "config.h"
#endif

#define MOZILLA_CLIENT

#include <mozilla-config.h>
#include <gtkmozembed.h>
#include <nsXPCOM.h>
#include <nsIGenericFactory.h>
#include <nsIComponentRegistrar.h>
#include <nsIComponentManager.h>
#include <nsServiceManagerUtils.h>

#include "mozilla.h"
#include "mozilla-prefs.h"
#include "kz-mozfilepicker.h"
#include "kz-mozlauncher.h"
#include "kz-mozprogresslistener.h"
#include "kz-mozprintingpromptservice.h"
#include "kazehakase.h"
#include "kz-mozhistorysearch.h"
#include "kz-mozselectionlistener.h"
#include "kz-mozcookiepromptservice.h"
#ifdef HAVE_NSIBADCERTLISTENER_H
#  include "GtkNSSDialogs.h"
#endif
#include "GtkPromptService.h"
#ifdef XPCOM_GLUE
#include <gtkmozembed_glue.cpp>
#include <nsGenericFactory.h>
#endif
#ifdef HAVE_GECKO_1_9
#  include <nsComponentManagerUtils.h>
#endif

NS_GENERIC_FACTORY_CONSTRUCTOR(KzFilePicker)
NS_GENERIC_FACTORY_CONSTRUCTOR(KzContentHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(KzMozProgressListener)
NS_GENERIC_FACTORY_CONSTRUCTOR(KzMozHistorySearchProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(KzMozPrintingPromptService)
NS_GENERIC_FACTORY_CONSTRUCTOR(GtkPromptService)
#ifdef HAVE_NSIBADCERTLISTENER_H
NS_GENERIC_FACTORY_CONSTRUCTOR(GtkNSSDialogs)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(KzMozCookiePromptService)

static const nsModuleComponentInfo sAppComps[] = {
	{
		KZ_DOWNLOAD_CLASSNAME,
		KZ_DOWNLOAD_CID,
		NS_TRANSFER_CONTRACTID,
		KzMozProgressListenerConstructor
	},
	{
		KZ_FILEPICKER_CLASSNAME,
		KZ_FILEPICKER_CID,
		KZ_FILEPICKER_CONTRACTID,
		KzFilePickerConstructor
	},
	{
		NS_IHELPERAPPLAUNCHERDLG_CLASSNAME,
		KZ_CONTENTHANDLER_CID,
		NS_IHELPERAPPLAUNCHERDLG_CONTRACTID,
		KzContentHandlerConstructor
	},
	{
		KZ_HISTORY_SEARCH_PROTOCOLHANDLER_CLASSNAME,
		KZ_HISTORY_SEARCH_PROTOCOLHANDLER_CID,
		KZ_HISTORY_SEARCH_PROTOCOLHANDLER_CONTRACTID,
		KzMozHistorySearchProtocolHandlerConstructor
	},
	{
		KZ_PRINTINGPROMPTSERVICE_CLASSNAME,
		KZ_PRINTINGPROMPTSERVICE_CID,
		KZ_PRINTINGPROMPTSERVICE_CONTRACTID,
		KzMozPrintingPromptServiceConstructor
	},
#ifdef HAVE_NSIBADCERTLISTENER_H
	{
		GTK_NSSDIALOGS_CLASSNAME,
		GTK_NSSDIALOGS_CID,
		NS_BADCERTLISTENER_CONTRACTID,
		GtkNSSDialogsConstructor
	},
	{
		GTK_NSSDIALOGS_CLASSNAME,
		GTK_NSSDIALOGS_CID,
		NS_CERTIFICATEDIALOGS_CONTRACTID,
		GtkNSSDialogsConstructor
	},
#endif
  	{
		"Prompt Service",
    		NS_PROMPTSERVICE_CID,
    		"@mozilla.org/embedcomp/prompt-service;1",
    		GtkPromptServiceConstructor
	},
	{
		KZ_COOKIEPROMPTSERVICE_CLASSNAME,
		KZ_COOKIEPROMPTSERVICE_CID,
		KZ_COOKIEPROMPTSERVICE_CONTRACTID,
		KzMozCookiePromptServiceConstructor
	},
};
static const int sNumAppComps = G_N_ELEMENTS(sAppComps);

#ifdef XPCOM_GLUE
gboolean
xulrunner_init (void)
{
	static const GREVersionRange greVersion = {
		"1.9.1", PR_TRUE,
		"2.0", PR_TRUE,
	};

	char xpcomPath[PATH_MAX];

	nsresult rv = GRE_GetGREPathWithProperties(&greVersion, 1, nsnull, 0,
						   xpcomPath, sizeof(xpcomPath));
	if (NS_FAILED(rv))
		return FALSE;

	rv = XPCOMGlueStartup(xpcomPath);
	if (NS_FAILED(rv))
		return FALSE;

	rv = GTKEmbedGlueStartup();
	if (NS_FAILED(rv))
		return FALSE;

	rv = GTKEmbedGlueStartupInternal();
	if (NS_FAILED(rv))
		return FALSE;

	char *lastSlash = strrchr(xpcomPath, '/');
	if (lastSlash)
		*lastSlash = '\0';

	gtk_moz_embed_set_path(xpcomPath);

	return TRUE;
}

static nsresult
NS_NewGenericFactory(nsIGenericFactory* *result,
                     const nsModuleComponentInfo *info)
{
	nsresult rv;
	nsCOMPtr<nsIGenericFactory> fact;
	fact = do_CreateInstance(NS_GENERICFACTORY_CONTRACTID, &rv);
	if (NS_FAILED(rv))
		return rv;
	rv = fact->SetComponentInfo(info);
	if (NS_FAILED(rv))
	{
		NS_RELEASE(fact);
		return rv;
	}

	NS_ADDREF(*result = fact);
	return rv;
}
#endif

gboolean
mozilla_register_components (void)
{
	gboolean ret = TRUE;
	nsresult rv;

	nsCOMPtr<nsIComponentRegistrar> cr;
	rv = NS_GetComponentRegistrar(getter_AddRefs(cr));
	NS_ENSURE_SUCCESS(rv, rv);

	nsCOMPtr<nsIComponentManager> cm;
	NS_GetComponentManager(getter_AddRefs(cm));
	NS_ENSURE_TRUE(cm, FALSE);

	for (int i = 0; i < sNumAppComps; i++)
	{
		nsCOMPtr<nsIGenericFactory> componentFactory;
		rv = NS_NewGenericFactory(getter_AddRefs(componentFactory),
					  &(sAppComps[i]));
		if (NS_FAILED(rv))
		{
			ret = FALSE;
			continue;  // don't abort registering other components
		}

		rv = cr->RegisterFactory(sAppComps[i].mCID,
					 sAppComps[i].mDescription,
					 sAppComps[i].mContractID,
					 componentFactory);
		if (NS_FAILED(rv))
			ret = FALSE;
	}

	return ret;
}

