/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
 *
 *  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

#include "galeon-automation.h"
#include "galeon-shell.h"
#include "GaleonAutomation.h"
#include "galeon-embed.h"
#include "galeon-window.h"

#include <string.h>
#include <bonobo/bonobo-generic-factory.h>
#include <bonobo/bonobo-main.h>
#include <bonobo/bonobo-context.h>

static CORBA_boolean 
impl_galeon_automation_add_bookmark (PortableServer_Servant _servant,
				     const CORBA_char * url,
				     CORBA_Environment * ev);
static CORBA_boolean
impl_galeon_automation_quit (PortableServer_Servant _servant,
                             const CORBA_boolean disableServer,
                             CORBA_Environment * ev);
static CORBA_boolean 
impl_galeon_automation_load_session (PortableServer_Servant _servant,
				     const CORBA_char * filename,
				     CORBA_Environment * ev);
static void
galeon_automation_class_init (GaleonAutomationClass *klass);
static BonoboObject *
galeon_automation_factory (BonoboGenericFactory *this_factory,
			   const char *iid,
			   gpointer user_data);

static GObjectClass *galeon_automation_parent_class;

#define GALEON_FACTORY_OAFIID "OAFIID:GNOME_Galeon_Automation_Factory"

typedef struct {
	char *url;
	guint open_in_existing_tab : 1;
	guint open_in_new_window : 1;
	guint open_in_new_tab : 1;
	guint fullscreen : 1;
	guint raise : 1;
} GaleonAutomationLoadurlData;

static GSList *postponed_loadurls = NULL;
static gboolean initialized = FALSE;

static BonoboObject *
galeon_automation_factory (BonoboGenericFactory *this_factory,
			   const char *iid,
			   gpointer user_data)
{
        GaleonAutomation *a;
        
        a  = g_object_new (GALEON_AUTOMATION_TYPE, NULL);

        return BONOBO_OBJECT(a);
}

BonoboGenericFactory *
galeon_automation_factory_new (void)
{
	BonoboGenericFactory   *factory;

	factory = bonobo_generic_factory_new (GALEON_FACTORY_OAFIID,
					      galeon_automation_factory,
					      NULL);

	if (factory == NULL)
	{
		g_warning ("Could not initialize GaleonAutomation factory");
	}
	
	return factory;
}

static void
galeon_automation_loadurl (const char *url,
			   gboolean fullscreen,
			   gboolean open_in_existing_tab,
			   gboolean open_in_new_window,
			   gboolean open_in_new_tab,
			   gboolean raise)
{
	GaleonNewTabFlags flags = 0;
	const char *load_page = NULL;
	GaleonWindow *window;
	
	window = galeon_shell_get_active_window (galeon_shell);
	
	if (open_in_existing_tab && window != NULL)
	{
		galeon_window_load_url (window, url);
		return;
	}
	
	if (*url == '\0')
	{
		flags = GALEON_NEW_TAB_HOMEPAGE;
	}
	else
	{
		load_page = url;
	}

	if (open_in_new_window)
	{
		flags |= GALEON_NEW_TAB_IN_NEW_WINDOW;
	}
	
	if (open_in_new_tab)
	{
		flags |= GALEON_NEW_TAB_IN_EXISTING_WINDOW;
	}

	if (fullscreen)
	{
		flags |= GALEON_NEW_TAB_FULLSCREEN;
	}
	
	if (raise)
	{
		flags |= GALEON_NEW_TAB_RAISE_WINDOW;
	}
	
	galeon_shell_new_tab (galeon_shell, window, NULL, load_page, 
			      flags);
}

static CORBA_boolean 
impl_galeon_automation_loadurl (PortableServer_Servant _servant,
				const CORBA_char * url,
				const CORBA_char * geometry,
				const CORBA_boolean fullscreen,
				const CORBA_boolean open_in_existing_tab,
				const CORBA_boolean open_in_new_window,
				const CORBA_boolean open_in_new_tab,
				const CORBA_boolean raise,
                                CORBA_Environment * ev)
{
	if (initialized) {
		galeon_automation_loadurl (url, fullscreen, open_in_existing_tab,
					   open_in_new_window, 
					   open_in_new_tab, raise );
	} else {
		GaleonAutomationLoadurlData *data = g_new (GaleonAutomationLoadurlData, 1);

		data->url                  = g_strdup (url);
		data->open_in_existing_tab = open_in_existing_tab;
		data->open_in_new_window   = open_in_new_window;
		data->open_in_new_tab      = open_in_new_tab;
		data->fullscreen           = fullscreen;
		data->raise                = raise;

		postponed_loadurls = g_slist_prepend (postponed_loadurls, data);
	}
	return TRUE;
}

void
galeon_automation_complete_initialization (void)
{
	Session *session;

	session = galeon_shell_get_session (galeon_shell);

	/* no window open, let's try to autoresume */
	if (session_get_windows (session) == NULL)
	{
		SessionResumeType res;
		res = session_autoresume (session);

		/* Don't load any windows, the user wants to abort this
		 * instance */
		if ( res == SESSION_ABORT ) {
			GSList * iterator;
			for( iterator = postponed_loadurls ; iterator ; iterator = iterator->next) {
				GaleonAutomationLoadurlData *data = iterator->data;
				g_free (data->url);
				g_free (data);
			}
			g_slist_free (postponed_loadurls);
			galeon_shell_set_server_mode (galeon_shell, FALSE);
			return;
		}
		
		/* no need to open the homepage,
		 * we did already open session windows */
		if (res == SESSION_RESUMED && postponed_loadurls) {
			GSList *last = g_slist_last (postponed_loadurls);
			GaleonAutomationLoadurlData *data = last->data;
			if (data->url == NULL || *data->url == 0) {
				postponed_loadurls = g_slist_delete_link (postponed_loadurls, last);
				g_free (data->url);
				g_free (data);
			}
		}
	}
	while (postponed_loadurls) {
		GSList *internal_postponed, *iterator;

		internal_postponed = g_slist_reverse (postponed_loadurls);
		postponed_loadurls = NULL;

		for (iterator = internal_postponed; iterator; iterator = iterator->next) {
			GaleonAutomationLoadurlData *data = iterator->data;
			galeon_automation_loadurl (data->url,
						   data->fullscreen,
						   data->open_in_existing_tab,
						   data->open_in_new_window,
						   data->open_in_new_tab,
						   data->raise);
			g_free (data->url);
			g_free (data);
		}
		g_slist_free (internal_postponed);
	}
	initialized = TRUE;
}
       
static CORBA_boolean 
impl_galeon_automation_add_bookmark (PortableServer_Servant _servant,
				     const CORBA_char * url,
				     CORBA_Environment * ev)
{
	CORBA_boolean retval = TRUE;
	GbBookmarkSet *set;
	GbSite *b;

	g_return_val_if_fail (galeon_shell != NULL, FALSE);

	set = galeon_shell_get_bookmark_set (galeon_shell);
	g_return_val_if_fail (set, FALSE);

	b = gb_site_new (set, NULL, url);
	gb_bookmark_set_add_default (set, GB_BOOKMARK (b));

	return retval;
}

static CORBA_boolean
impl_galeon_automation_quit (PortableServer_Servant _servant,
                             const CORBA_boolean disableServer,
                             CORBA_Environment * ev)
{
	CORBA_boolean retval = TRUE;

	Session *session;

	g_object_ref (galeon_shell);

	session = galeon_shell_get_session (galeon_shell);
	
	session_close (session);

	if (disableServer)
	{
		galeon_shell_set_server_mode (galeon_shell, FALSE);
	}

	g_object_unref (galeon_shell);

	return retval;
}

static CORBA_boolean 
impl_galeon_automation_load_session (PortableServer_Servant _servant,
				     const CORBA_char * filename,
				     CORBA_Environment * ev)
{
	CORBA_boolean retval = TRUE;
	Session *session;

	session = galeon_shell_get_session (galeon_shell);
	session_load (session, filename);

	return retval;
}


static CORBA_boolean 
impl_galeon_automation_set_server_mode (PortableServer_Servant _servant,
					const CORBA_boolean mode,
					CORBA_Environment * ev)
{
	CORBA_boolean retval = TRUE;

	galeon_shell_set_server_mode (galeon_shell, mode ? TRUE : FALSE);

	return retval;
}

static void
galeon_automation_class_init (GaleonAutomationClass *klass)
{
        POA_GNOME_GaleonAutomation__epv *epv = &klass->epv;

        galeon_automation_parent_class = g_type_class_peek_parent (klass);

        /* connect implementation callbacks */
        epv->loadurl = impl_galeon_automation_loadurl;
	epv->addBookmark = impl_galeon_automation_add_bookmark;
	epv->quit = impl_galeon_automation_quit;
	epv->loadSession = impl_galeon_automation_load_session;
	epv->setServerMode = impl_galeon_automation_set_server_mode;
}

static void
galeon_automation_init (GaleonAutomation *c) 
{
}

BONOBO_TYPE_FUNC_FULL (
        GaleonAutomation,                    
        GNOME_GaleonAutomation, 
        BONOBO_TYPE_OBJECT,           
        galeon_automation);
