/*
 *  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-marshal.h"
#include "galeon-window.h"
#include "galeon-sidebar.h"
#include "galeon-dnd.h"
#include "gul-state.h"
#include "gul-gobject-misc.h"
#include "gul-notebook.h"
#include "gul-gui.h"
#include "gul-general.h"
#include "statusbar.h"
#include "ppview-toolbar.h"
#include "window-commands.h"
#include "find-dialog.h"
#include "history-dialog.h"
#include "galeon-shell.h"
#include "bookmarks-gtk-menu.h"
#include "bookmarks-gtk-toolbar-set.h"
#include "eel-gconf-extensions.h"
#include "prefs-strings.h"
#include "galeon-embed-utils.h"
#include "galeon-embed-prefs.h"
#include "bookmarks-editor-dockable.h"
#include "galeon-recent-history-menu.h"
#include "galeon-embed-prefs.h"
#include "galeon-css-menu.h"
#include "galeon-window-menu.h"
#include "galeon-tab-menu.h"
#include "galeon-encoding-menu.h"
#include "hig-alert.h"
#include "galeon-debug.h"

#include <stdlib.h>
#include <string.h>
#include <glib/gi18n.h>
#include "egg-dock.h"
#include "egg-dock-item.h"
#include <libgnomevfs/gnome-vfs-uri.h>
#include <libgnome/gnome-config.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkpaned.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkeditable.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkhpaned.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkuimanager.h>
#include <gtk/gtktoolbar.h>
#include <gtk/gtkmenushell.h>

#include <gtk/gtkmessagedialog.h>
#include <libgnomeui/gnome-stock-icons.h>

#include "pixbuf-cache.h"
#include "egg-editable-toolbar.h"

#include "galeon-action-location.h"
#include "galeon-action-navigation.h"
#include "galeon-action-home.h"
#include "galeon-action-new.h"
#include "galeon-action-refresh.h"
#include "galeon-action-stop.h"
#include "galeon-action-go.h"
#include "galeon-action-zoom.h"
#include "galeon-action-spinner.h"
#include "galeon-action-favicon.h"

/* keys and defaults for state */
#define STATE_SIDEBAR_SIZE         "Main Window/sidebar_size"

#define STATE_SIDEBAR_SIZE_DEFAULT 175

#define STATE_MAIN_WIDTH_DEFAULT   700
#define STATE_MAIN_HEIGHT_DEFAULT  500

#define GCONF_DETACH_TOOLBAR "/desktop/gnome/interface/toolbar_detachable"
#define GCONF_DETACH_MENUBAR "/desktop/gnome/interface/menubar_detachable"

enum GaleonWindowSignalsEnum
{
	ACTIVE_EMBED_CHANGED,
	LAST_SIGNAL
};
static gint GaleonWindowSignals[LAST_SIGNAL];

/* These are the values of in gconf for these items */
#define VIEW_IMAGES_ALWAYS	0
#define VIEW_IMAGES_CURRENT	1
#define VIEW_IMAGES_NEVER	2
#define ACCEPT_COOKIES_ALWAYS	0
#define ACCEPT_COOKIES_CURRENT	1
#define ACCEPT_COOKIES_NEVER	2

struct GaleonWindowPrivate
{
	GList *notifiers;
	PPViewToolbar *ppview_toolbar;
	GbGtkMenu *bookmarks_menu;
	GbGtkToolbarSet *bookmarks_toolbar;
	GaleonCssMenu *css_menu;
	GaleonWindowMenu *window_menu;
	GaleonTabMenu *tab_menu;
	GaleonEncodingMenu *encoding_menu;
	GaleonRecentHistoryMenu *rh_menu;
	GtkNotebook *notebook;
	GtkWidget *hpaned;
	GaleonTab *active_tab;
	GtkWidget *sidebar;
	GaleonPopup *embed_popup;
	GaleonDialog *find_dialog;
	GaleonDialog *history_dialog;
	GaleonDialog *history_sidebar;
	GbEditorDockable *bookmarks_sidebar;
	EmbedChromeMask chrome_mask;
	gboolean ignore_layout_toggles;
	gboolean has_default_size;
	gboolean closing;
	GaleonWindowRecentHistory *recent_history;

	GtkWidget *main_area;
	GtkWidget *menubar;
	GtkWidget *statusbar;
	EggEditableToolbar *egg_toolbar;
	GtkActionGroup *action_group;

	GaleonActionLocation *location_action;
	GaleonActionSpinner *spinner_action;
};

#define ACTION_ITEM(name) gtk_action_group_get_action(window->priv->action_group, name)
#define TOGGLE_ITEM(name) GTK_TOGGLE_ACTION(ACTION_ITEM(name))
#define RADIO_ITEM(name) GTK_RADIO_ACTION(ACTION_ITEM(name))

#define FILE_OFFLINE_ACTION		"FileOfflineAction"

#define VIEW_STOP_ACTION		"ViewStopAction"
#define VIEW_TOOLBAR_ACTION		"ViewToolbarAction"
#define VIEW_BMTOOLBARS_ACTION		"ViewBmToolbarsAction"
#define VIEW_STATUSBAR_ACTION		"ViewStatusbarAction"
#define VIEW_SIDEBAR_ACTION		"ViewSidebarAction"
#define VIEW_FULLSCREEN_ACTION		"Fullscreen" /* for compatability with 1.3.12 toolbar */

#define VIEW_IMAGES_BLOCKSITE_ACTION	"ViewImagesBlockSiteAction"
#define VIEW_IMAGES_ALLOWSITE_ACTION	"ViewImagesAllowSiteAction"
#define WEB_COOKIES_BLOCKSITE_ACTION	"WebCookiesBlockSiteAction"
#define WEB_COOKIES_ALLOWSITE_ACTION	"WebCookiesAllowSiteAction"
#define WEB_POPUPS_ALLOWSITE_ACTION	"WebPopupsAllowSiteAction"

#define WEB_POPUPS_ALWAYS_ACTION	"WebPopupsAlwaysAction"
#define WEB_ALLOW_JAVA_ACTION		"WebAllowJavaAction"
#define WEB_ALLOW_JS_ACTION		"WebAllowJSAction"

#define GO_BACK_ACTION			"GoBackAction"
#define GO_FORWARD_ACTION		"GoForwardAction"
#define GO_UP_ACTION			"GoUpAction"

#define VIEW_SOURCE_ACTION              "FilePageSourceAction"
#define FILE_PRINT_ACTION               "FilePrintAction"

#define BOOKMARK_MENU_PATH		"/menubar/Bookmarks"
#define TAB_POPUP_PATH			"/GaleonTabPopup"

static void
set_offline_action_state(GtkToggleAction *action, gboolean offline)
{
	gtk_toggle_action_set_active (action, offline);
	galeon_embed_shell_set_offline_mode (embed_shell, offline);
}

static void
gtk_cmd_file_offline(GtkToggleAction *action, GaleonWindow *window)
{
	gboolean offline = gtk_toggle_action_get_active (action);

	eel_gconf_set_boolean (CONF_GENERAL_OFFLINE, offline);
	set_offline_action_state (action, offline);
}

static void
gtk_cmd_gconf_toggle_monitor(GConfClient *client,
                             guint cnxn_id,
                             GConfEntry *entry,
			     gpointer user_data)
{
	GtkToggleAction *action = user_data;
	set_offline_action_state (action, eel_gconf_get_boolean (entry->key));
}

static void
gtk_cmd_view_toolbar(GtkAction *action, GaleonWindow *window)
{
	EmbedChromeMask mask;

	if (window->priv->ignore_layout_toggles) return;
	
        mask = galeon_window_get_chrome(window);
        mask ^= EMBED_CHROME_TOOLBARON;
        galeon_window_set_chrome(window, mask);
}

static void
gtk_cmd_view_bmtoolbars(GtkAction *action, GaleonWindow *window)
{
	EmbedChromeMask mask;
	
	if (window->priv->ignore_layout_toggles) return;

        mask = galeon_window_get_chrome(window);
        mask ^= EMBED_CHROME_PERSONALTOOLBARON;
        galeon_window_set_chrome(window, mask);
}

static void
gtk_cmd_view_sidebar(GtkAction *action, GaleonWindow *window)
{
	EmbedChromeMask mask;

	if (window->priv->ignore_layout_toggles) return;
	
        mask = galeon_window_get_chrome(window);
        mask ^= EMBED_CHROME_SIDEBARON;
        galeon_window_set_chrome(window, mask);
}

static void
gtk_cmd_view_statusbar(GtkAction *action, GaleonWindow *window)
{
	EmbedChromeMask mask;

	if (window->priv->ignore_layout_toggles) return;
	
        mask = galeon_window_get_chrome(window);
        mask ^= EMBED_CHROME_STATUSBARON;
        galeon_window_set_chrome(window, mask);
}

static void
gtk_cmd_view_fullscreen(GtkAction *action, GaleonWindow *window)
{	
	if (window->priv->ignore_layout_toggles) return;

	galeon_window_toggle_fullscreen(window);
}

static void
gtk_cmd_allow_java(GtkToggleAction *action, GaleonWindow *window)
{
	eel_gconf_set_boolean(CONF_FILTERING_JAVA_ENABLED,
			      gtk_toggle_action_get_active(action));
}

static void
gtk_cmd_allow_js(GtkToggleAction *action, GaleonWindow *window)
{
	eel_gconf_set_boolean(CONF_FILTERING_JAVASCRIPT_ENABLED,
			      gtk_toggle_action_get_active(action));
}

/* Prototype needed as implemented later */
static void update_permission_control(GaleonWindow *window);

static void
gtk_cmd_allow_popups(GtkToggleAction *action, GaleonWindow *window)
{
	eel_gconf_set_boolean(CONF_FILTERING_ALLOW_POPUPS,
			      gtk_toggle_action_get_active(action));
	update_permission_control(window);
}

static GtkActionEntry entries[] = {
	{ "FileMenuAction", NULL, N_("_File"), NULL, NULL, NULL, },
	{ "EditMenuAction", NULL, N_("_Edit"), NULL, NULL, NULL, },
	{ "ViewMenuAction", NULL, N_("_View"), NULL, NULL, NULL, },
	{ "ViewImagesMenuAction", NULL, N_("I_mages"), NULL, NULL, NULL },
	{ "ViewEncodingMenuAction", NULL, N_("_Encoding"), NULL, NULL, NULL },
	{ "ViewStylesMenuAction", NULL, N_("St_yles"), NULL, NULL, NULL  },
	{ "WebMenuAction", NULL, N_("_Web"), NULL, NULL, NULL },
	{ "WebCookiesMenuAction", NULL, N_("C_ookies"), NULL, NULL, NULL },
	{ "WebPopupsMenuAction", NULL, N_("_Popups"), NULL, NULL, NULL },
	{ "GoMenuAction", NULL, N_("_Go"), NULL, NULL, NULL },
	{ "BookmarksMenuAction", NULL, N_("_Bookmarks"), NULL, NULL, NULL },
	{ "TabsMenuAction", NULL, N_("_Tabs"), NULL, NULL, NULL },
	{ "TabsMoveMenuAction", NULL, N_("_Move Tab to Another Window"), NULL, NULL, NULL },
	{ "HelpMenuAction", NULL, N_("_Help"), NULL, NULL, NULL },

	{ "FileNewWindowAction", GTK_STOCK_NEW, N_("_New Window"), "<control>n",
	  N_("Open another Galeon window"), G_CALLBACK(window_cmd_new_window) },
	{ "FileNewTabAction", STOCK_NEW_TAB, N_("New _Tab"), "<control>t",
	  N_("Open a new tab in this window"), G_CALLBACK(window_cmd_new_tab) },
	{ "FileOpenAction", GTK_STOCK_OPEN, N_("_Open..."), "<control>o",
	  N_("Open a file"), G_CALLBACK(window_cmd_file_open) },
	{ "FileSaveAsAction", GTK_STOCK_SAVE_AS, N_("Save _As..."), "<control><shift>s",
	  N_("Save the current page with a different name"), G_CALLBACK(window_cmd_file_save_as) },
	{ FILE_PRINT_ACTION, GTK_STOCK_PRINT, N_("_Print..."), "<control>p",
	  N_("Print the current page"), G_CALLBACK(window_cmd_file_print) },
	{ "FileSendToAction", STOCK_SEND_MAIL, N_("_Send Link To..."), NULL,
	  N_("Send the address of the current page by Email"), G_CALLBACK(window_cmd_file_send_to) },
	{ "FilePageSourceAction", STOCK_VIEW_SOURCE, N_("_View Source"), "<control>u",
	  N_("Show the source of the current page"), G_CALLBACK(window_cmd_view_page_source) },
	{ "FilePageInfoAction", GTK_STOCK_PROPERTIES, N_("P_roperties"), NULL,
	  N_("See page properties"), G_CALLBACK(window_cmd_view_page_info) },
	{ "FileCloseTabAction", GTK_STOCK_CLOSE, N_("_Close"), "<control>w",
	  N_("Close the current page"), G_CALLBACK(window_cmd_file_close_tab) },
	{ "FileQuitAction", GTK_STOCK_QUIT, N_("_Quit"), "<control>q",
	  N_("Close all windows and quit"), G_CALLBACK(window_cmd_file_quit) },

	{ "EditCutAction", GTK_STOCK_CUT, N_("Cu_t"), "<control>x",
	  N_("Cut the selection to the clipboard"), G_CALLBACK(window_cmd_edit_cut) },
	{ "EditCopyAction", GTK_STOCK_COPY, N_("_Copy"), "<control>c",
	  N_("Copy the selection to the clipboard"), G_CALLBACK(window_cmd_edit_copy) },
	{ "EditPasteAction", GTK_STOCK_PASTE, N_("_Paste"), "<control>v",
	  N_("Paste the selection from the clipboard"), G_CALLBACK(window_cmd_edit_paste) },
	{ "EditSelectAllAction", STOCK_SELECT_ALL, N_("Select _All"), "<control>a",
	  N_("Select the entire page"), G_CALLBACK(window_cmd_edit_select_all) },
	{ "EditFindAction", GTK_STOCK_FIND, N_("_Find..."), "<control>f",
	  N_("Search for a string in the current page"), G_CALLBACK(window_cmd_edit_find) },
	{ "EditFindNextAction", NULL, N_("Find Ne_xt"), "<control>g",
	  N_("Find next occurrence of the same string"), G_CALLBACK(window_cmd_edit_find_next) },
	{ "EditFindPrevAction", NULL, N_("Find Pre_vious"), "<control><shift>g",
	  N_("Find previous occurrence of the same string"), G_CALLBACK(window_cmd_edit_find_prev) },
	{ "EditPDMAction", NULL, N_("P_ersonal Data"), NULL,
	  N_("Edit your personal data"), G_CALLBACK(window_cmd_tools_pdm) },
	{ "EditToolbarAction", NULL, N_("T_oolbar"), NULL,
	  N_("Edit the main toolbar"), G_CALLBACK(window_cmd_settings_toolbar_editor) },
	{ "EditPrefsAction", GTK_STOCK_PREFERENCES, N_("P_references"), NULL,
	  N_("Edit Galeon preferences"), G_CALLBACK(window_cmd_edit_prefs) },

	{ "ViewZoomInAction", GTK_STOCK_ZOOM_IN, N_("Zoom In"), "<control>plus",
	  N_("Show the contents in more detail"), G_CALLBACK(window_cmd_view_zoom_in) },
	{ "ViewZoomOutAction", GTK_STOCK_ZOOM_OUT, N_("Zoom Out"), "<control>minus",
	  N_("Show the contents in less detail"), G_CALLBACK(window_cmd_view_zoom_out) },
	{ "ViewZoomNormalAction", GTK_STOCK_ZOOM_100, N_("Normal Size"), NULL,
	  N_("Show the contents at the normal size"), G_CALLBACK(window_cmd_view_zoom_normal) },
	{ "ViewStopAction", GTK_STOCK_STOP, N_("_Stop"), "Escape",
	  N_("Stop current data transfer"), G_CALLBACK(window_cmd_go_stop) },
	{ "ViewReloadAction", GTK_STOCK_REFRESH, N_("_Reload"), "<control>r",
	  N_("Display the latest content of the current page"), G_CALLBACK(window_cmd_go_reload) },

	{ "ViewImagesBlockSiteAction", NULL, N_("_Block Images From This Site"), NULL,
	  N_("Allow Images from this site to load"), G_CALLBACK(window_cmd_set_permission) },
	{ "ViewImagesAllowSiteAction", NULL, N_("_Allow Images From This Site"), NULL,
	  N_("Block Images from this site from loading"), G_CALLBACK(window_cmd_set_permission) },

	{ "WebJavaConsoleAction", NULL, N_("Java _Console"), NULL,
	  N_("Show Java console window"), G_CALLBACK(window_cmd_show_java_console) },
	{ "WebJSConsoleAction", NULL, N_("J_avaScript Console"), NULL,
	  N_("Show JavaScript console window"), G_CALLBACK(window_cmd_show_js_console) },

	{ "WebCookiesBlockSiteAction", NULL, N_("_Block Cookies From This Site"), NULL,
	  N_("Allow Cookies from this site to accepted"), G_CALLBACK(window_cmd_set_permission) },
	{ "WebCookiesAllowSiteAction", NULL, N_("_Allow Cookies From This Site"), NULL,
	  N_("Block Cookies from this site from being accepted"), G_CALLBACK(window_cmd_set_permission) },

	{ "WebPopupsAllowSiteAction", NULL, N_("_Allow Popups From This Site"), NULL,
	  N_("Allow Popups from this site to be accepted"), G_CALLBACK(window_cmd_set_permission) },

	{ "GoBackAction", GTK_STOCK_GO_BACK, N_("_Back"), "<alt>Left",
	  N_("Go to the previous visited page"), G_CALLBACK(window_cmd_go_back) },
	{ "GoForwardAction", GTK_STOCK_GO_FORWARD, N_("_Forward"), "<alt>Right",
	  N_("Go to the next visited page"), G_CALLBACK(window_cmd_go_forward) },
	{ "GoUpAction",	GTK_STOCK_GO_UP, N_("_Up"), "<alt>Up",
	  N_("Go up one level"), G_CALLBACK(window_cmd_go_up) },
	{ "GoHomeAction", GTK_STOCK_HOME, N_("_Home"), "<alt>Home",
	  N_("Go to the home page"), G_CALLBACK(window_cmd_go_home) },
	{ "GoMyportalAction", NULL, N_("_My Portal"), NULL,
	  N_("Go to the My Portal"), G_CALLBACK(window_cmd_go_myportal) },
	{ "GoLocationAction", NULL, N_("_Location..."), "<control>l",
	  N_("Specify a location to visit"), G_CALLBACK(window_cmd_go_location) },
	{ "GoHistoryAction", GALEON_STOCK_HISTORY, N_("_History"), "<control>h",
	  N_("Show browser history window"), G_CALLBACK(window_cmd_tools_history) },

	{ "BookmarksAddInteractiveAction", STOCK_ADD_BOOKMARK, N_("_Add Bookmark..."), "<control>d",
	  N_("Add a bookmark for the current location"), G_CALLBACK(window_cmd_bookmarks_add_interactive) },
	{ "BookmarksAddTabFolderAction", GTK_STOCK_ADD, N_("_Add Tabs As Folder..."), NULL,
	  N_("Add the current window's tabs as a folder"), G_CALLBACK(window_cmd_bookmarks_add_tab_folder) },
	{ "BookmarksEditAction", STOCK_EDIT_BOOKMARK, N_("_Edit Bookmarks"), "<control>b",
	  N_("Open a bookmarks editor"), G_CALLBACK(window_cmd_bookmarks_edit) },


	{ "TabsPrevAction", NULL, N_("_Previous Tab"), "<control>Page_Up",
	  N_("View previous tab"), G_CALLBACK(window_cmd_tabs_previous) },
	{ "TabsNextAction", NULL, N_("_Next Tab"), "<control>Page_Down",
	  N_("View next tab"), G_CALLBACK(window_cmd_tabs_next) },
	{ "TabsMoveLeftAction", NULL, N_("Move Tab _Left"), "<control><shift>Page_Up",
	  N_("Move this tab left"), G_CALLBACK(window_cmd_tabs_move_left) },
	{ "TabsMoveRightAction", NULL, N_("Move Tab _Right"), "<control><shift>Page_Down",
	  N_("Move this tab right"), G_CALLBACK(window_cmd_tabs_move_right) },
	{ "TabsCloneAction", NULL, N_("_Clone Tab"), "<control><shift>c",
	  N_("Create a copy of this tab"), G_CALLBACK(window_cmd_tabs_clone) },
	{ "TabsDetachAction", NULL, N_("_Detach Tab"), "<control><shift>d",
	  N_("Detach this tab into its own window"), G_CALLBACK(window_cmd_tabs_detach) },
	{ "TabsCloseOtherTabsAction", NULL, N_("Close _Other Tabs in Window"), NULL,
	  N_("Close the other tabs in this window"), G_CALLBACK(window_cmd_tabs_close_other_tabs) },

	{ "HelpContentsAction", GTK_STOCK_HELP, N_("_Contents"), "F1",
	  N_("Open the Galeon manual"), G_CALLBACK(window_cmd_help_manual) },
	{ "HelpAboutPluginsAction", NULL, N_("About _Plugins"), NULL,
	  N_("Show information about the currently installed plugins"), G_CALLBACK(window_cmd_help_plugins) },
	{ "HelpAboutAction", GNOME_STOCK_ABOUT, N_("_About"), NULL,
	  N_("About Galeon"), G_CALLBACK(window_cmd_help_about) },

	{ "TabPopupCloseTabAction", GTK_STOCK_CLOSE, N_("_Close Tab"), NULL,
	  N_("Close the current tab"), G_CALLBACK(window_cmd_file_close_tab) }
};
static guint n_entries = G_N_ELEMENTS(entries);

static GtkToggleActionEntry toggle_entries[] = {
	{ "FileOfflineAction", NULL, N_("_Work Offline"), NULL,
	  N_("Work in offline mode"), 
	  G_CALLBACK(gtk_cmd_file_offline), FALSE },

	{ "ViewToolbarAction", NULL, N_("_Toolbar"), NULL, 
	  N_("Change the visibility of the main toolbar"), 
	  G_CALLBACK(gtk_cmd_view_toolbar), FALSE },

	{ "ViewBmToolbarsAction", NULL, N_("_Bookmark Toolbars"), NULL, 
	  N_("Change the visibility of the bookmarks toolbars"), 
	  G_CALLBACK(gtk_cmd_view_bmtoolbars), FALSE },

	{ "ViewStatusbarAction", NULL, N_("St_atusbar"), NULL, 
	  N_("Change the visibility of the statusbar"), 
	  G_CALLBACK(gtk_cmd_view_statusbar), FALSE },

	{ "ViewSidebarAction", NULL, N_("_Side Pane"), "F9", 
	  N_("Change the visibility of the side pane"),
	  G_CALLBACK(gtk_cmd_view_sidebar), FALSE },

	{ VIEW_FULLSCREEN_ACTION, STOCK_FULLSCREEN, N_("_Fullscreen"), "F11", 
	  N_("Toggle fullscreen mode"), 
	  G_CALLBACK(gtk_cmd_view_fullscreen), FALSE },

	{ "WebAllowJavaAction", NULL, N_("Allow _Java"), NULL,
	  N_("Toggle allowing of java applets to run"),
	  G_CALLBACK(gtk_cmd_allow_java), FALSE },

	{ "WebAllowJSAction", NULL, N_("Allow Java_Script"), NULL,
	  N_("Toggle allowing of javascript code to run"), 
	  G_CALLBACK(gtk_cmd_allow_js), FALSE },

	{ "WebPopupsAlwaysAction", NULL, N_("Allow Popups"), NULL,
	  N_("Always allow popup windows"), 
	  G_CALLBACK(gtk_cmd_allow_popups), FALSE }
};

static guint n_toggle_entries = G_N_ELEMENTS(toggle_entries);

/* Keep this in order, see radio_group_set_from_value */
static GtkRadioActionEntry image_radio_entries[] = {
	{ "ViewImagesAlwaysAction", NULL, N_("_Always"), NULL,
	  N_("View all images"), VIEW_IMAGES_ALWAYS },
	{ "ViewImagesCurrentAction", NULL, N_("_From Current Server Only"), NULL,
	  N_("View images originating from current server only"), VIEW_IMAGES_CURRENT },
	{ "ViewImagesNeverAction", NULL, N_("_Never"),  NULL,
	  N_("Don't view any images"), VIEW_IMAGES_NEVER }
};

static guint n_image_radio_entries = G_N_ELEMENTS (image_radio_entries);

/* Keep this in order, see radio_group_set_from_value */
static GtkRadioActionEntry cookie_radio_entries[] = {
	{ "WebCookiesAlwaysAction", NULL, N_("A_lways Allow"), NULL,
	  N_("Always accept cookies"), ACCEPT_COOKIES_ALWAYS },
	{ "WebCookiesCurrentAction", NULL, N_("Allow _From Current Server Only"), NULL,
	  N_("Only allow cookies from a page's own server"), ACCEPT_COOKIES_CURRENT },
	{ "WebCookiesNeverAction", NULL, N_("_Never Allow"),  NULL,
	  N_("Never accept cookies"), ACCEPT_COOKIES_NEVER }
};

static guint n_cookie_radio_entries = G_N_ELEMENTS (cookie_radio_entries);

static void
galeon_window_class_init (GaleonWindowClass *klass);
static void
galeon_window_gb_location_source_init (GbLocationSourceIface *iface);
static void
galeon_window_init (GaleonWindow *gs);
static void
galeon_window_finalize (GObject *object);
static void
galeon_window_dispose (GObject *object);
static void
galeon_window_show (GtkWidget *widget);
static gboolean
galeon_window_notebook_button_press_cb(GtkNotebook *notebook,
				       GdkEventButton *event,
				       GaleonWindow *window);
static gboolean
galeon_window_notebook_popup_menu_cb(GtkNotebook *notebook,
				     GaleonWindow *window);
static void
galeon_window_notebook_switch_page_cb (GtkNotebook *notebook,
				       GtkNotebookPage *page,
				       guint page_num,
				       GaleonWindow *window);
static void
galeon_window_bookmark_activated_cb (GObject *sender,
				     GbBookmarkEventActivated *ev,
				     GaleonWindow *w);

static void             
galeon_window_tab_detached_cb    (GulNotebook *notebook, gint page,
				  gint x, gint y, GaleonWindow *window);
static void
galeon_window_tabs_reordered_cb (GulNotebook *notebook, GaleonWindow *window);

static void             
galeon_window_tab_drag_data_received_cb (GtkWidget* widget, GdkDragContext *context,
					 gint x, gint y, GtkSelectionData *selection_data,
					 guint info, guint time, GtkWidget *child);

static void             
galeon_window_tab_added_cb  (GulNotebook *notebook, GtkWidget* child, 
			     GaleonWindow *window);

static void             
galeon_window_tab_removed_cb  (GulNotebook *notebook, GtkWidget* child, 
			       GaleonWindow *window);

static gboolean
galeon_window_tab_delete_cb  (GulNotebook *notebook, GtkWidget* child, 
			      GaleonWindow *window);

void /* yes, this is not static */
galeon_window_bookmark_activate (GaleonWindow *w, GbBookmarkEventActivated *ev);

static char *
galeon_window_gb_location_source_get_location (GbLocationSource *src);
static char *
galeon_window_gb_location_source_get_title (GbLocationSource *src);

static void
galeon_window_fullscreen (GaleonWindow *window);
static void
galeon_window_unfullscreen (GaleonWindow *window);

static gboolean 
galeon_window_key_press_event(GtkWidget *widget,
			      GdkEventKey *event);

static gboolean 
galeon_window_delete_event(GtkWidget *widget,
			   GdkEventAny *event);

static void
gtk_key_theme_changed_cb (GtkSettings  *settings,
                          GParamSpec   *pspec,
                          gpointer dummy);

/* static class variables */
static GdkColor _galeon_window_loading_tab_color;
static GdkColor _galeon_window_new_tab_color;
static GdkPixbufAnimation * _galeon_window_loading_animation;
static gboolean key_theme_is_emacs = FALSE;

static GObjectClass *parent_class = NULL;


MAKE_GET_TYPE_IFACE (galeon_window, "GaleonWindow", GaleonWindow,
		     galeon_window_class_init, galeon_window_init, GTK_TYPE_WINDOW,
		     galeon_window_gb_location_source_init, GB_TYPE_LOCATION_SOURCE);

static void
galeon_window_class_init (GaleonWindowClass *klass)
{
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
	char *tmp;
	GtkSettings *settings;
	
        parent_class = g_type_class_peek_parent (klass);

        object_class->finalize = galeon_window_finalize;
        object_class->dispose  = galeon_window_dispose;
	
	widget_class->show = galeon_window_show;
	widget_class->key_press_event = galeon_window_key_press_event;
	widget_class->delete_event = galeon_window_delete_event;

	/* initialize colors */
	tmp = eel_gconf_get_string (CONF_TABS_TABBED_LOADING_COLOR);
	gdk_color_parse (tmp, &_galeon_window_loading_tab_color);
	g_free (tmp);

	tmp = eel_gconf_get_string (CONF_TABS_TABBED_NEW_COLOR);
	gdk_color_parse (tmp, &_galeon_window_new_tab_color);
	g_free (tmp);

	tmp =  gul_general_user_file( "galeon-tab-loading.gif", FALSE );
	_galeon_window_loading_animation = 
		gdk_pixbuf_animation_new_from_file (tmp, NULL);
	g_free (tmp);

	/* initialize the listener for the key theme */
	settings = gtk_settings_get_default();
	g_signal_connect (settings,
			  "notify::gtk-key-theme-name",
			  G_CALLBACK (gtk_key_theme_changed_cb),
			  NULL);
	gtk_key_theme_changed_cb (settings, 0, 0);

	GaleonWindowSignals[ACTIVE_EMBED_CHANGED] = g_signal_new (
		"active-embed-changed", G_OBJECT_CLASS_TYPE (klass),  
		G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
                G_STRUCT_OFFSET (GaleonWindowClass, active_embed_changed), 
		NULL, NULL, 
		galeon_marshal_VOID__OBJECT_OBJECT,
		G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
}

static void
galeon_window_gb_location_source_init (GbLocationSourceIface *iface)
{
	iface->get_location = galeon_window_gb_location_source_get_location;
	iface->get_title = galeon_window_gb_location_source_get_title;
}


static void
gtk_key_theme_changed_cb (GtkSettings  *settings,
                          GParamSpec   *pspec,
                          gpointer dummy)
{
	gchar *key_theme_name;

	g_object_get (settings,
		      "gtk-key-theme-name", &key_theme_name,
		      NULL);
	if (key_theme_name && g_ascii_strcasecmp (key_theme_name, "Emacs") == 0)
	{
		key_theme_is_emacs = TRUE;
	}
	else
	{
		key_theme_is_emacs = FALSE;
	}
	g_free (key_theme_name);
}

/* The extra keybindings that aren't explictly associated with actions.
 * Come Gtk 2.4 there are better ways to do this ... (the <accelerator.../> tag
 * in the gtk_ui_manager xml file  */
struct keybinding {
	guint modifier;
	guint keyval;
	const gchar *action;
} extra_keybindings[] = {
	{ GDK_CONTROL_MASK, GDK_KP_Add,      "ViewZoomInAction"  },
	{ GDK_CONTROL_MASK, GDK_KP_Subtract, "ViewZoomOutAction" },
	{ GDK_CONTROL_MASK, GDK_s,           "FileSaveAsAction"  }
};

static void
menubar_deactivate_cb (GtkWidget *menubar, gulong *handler_id)
{
	GaleonWindow *window;

	g_signal_handler_disconnect (menubar, *handler_id);
	gtk_menu_shell_deselect (GTK_MENU_SHELL(menubar));

	/* we could've switched back to normal mode in the meantime, let's not
	 * hide the menubar in that case, it wouldn't be nice */
	window = GALEON_WINDOW(gtk_widget_get_toplevel (menubar));
	if (!(window->priv->chrome_mask & EMBED_CHROME_MENUBARON))
	{
		gtk_widget_hide (menubar->parent);
	}
}

static gboolean 
galeon_window_key_press_event (GtkWidget *window,
			       GdkEventKey *event)
{
	GaleonWindowPrivate *priv = GALEON_WINDOW(window)->priv;

	/* In an attempt to get the mozembed playing nice with things like emacs keybindings
	 * we are passing important events to the focused child widget before letting the window's
	 * base handler see them. This is *completely against* stated gtk2 policy but the 
	 * 'correct' behaviour is exceptionally useless. We need to keep an eye out for 
	 * unexpected consequences of this decision. IME's should be a high concern, but 
	 * considering that the IME folks complained about the upside-down event propagation
	 * rules, we might be doing them a favour.
	 */

	gboolean shortcircuit = FALSE;
	gboolean force_chain  = FALSE;
	gboolean handled = FALSE;
	guint modifier = event->state & gtk_accelerator_get_default_mod_mask ();
	guint i;

	if (event->keyval == GDK_Escape)
	{
		/* Always pass Escape to both the widget, and the parent */
		shortcircuit = TRUE;
		force_chain = TRUE;
	}
	else if (key_theme_is_emacs && 
		 (modifier == GDK_CONTROL_MASK) && event->length > 0 &&
		 /* But don't pass Ctrl+Enter twice */
		 event->keyval != GDK_Return)
	{
		/* Pass CTRL+letter characters to the widget */
		shortcircuit = TRUE;
	}

	if (shortcircuit)
	{
		GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));

		if (GTK_IS_WIDGET (widget))
		{
			handled = gtk_widget_event (widget, (GdkEvent*)event);
		}

		if (handled && !force_chain)
		{
			return handled;
		}
	}

	/* Handle accelerators that we want bound, but aren't associated with
	 * an action */
	for (i = 0; i < G_N_ELEMENTS (extra_keybindings); i++)
	{
		if (modifier == extra_keybindings[i].modifier &&
		    event->keyval == extra_keybindings[i].keyval)
		{
			GtkAction * action = gtk_action_group_get_action 
				(priv->action_group, 
				 extra_keybindings[i].action);
			gtk_action_activate (action);
			return TRUE;
		}
	}

	if (event->keyval == GDK_F10 && modifier == 0 &&
	    priv->menubar && priv->menubar->parent &&
	    !GTK_WIDGET_VISIBLE(priv->menubar->parent))
	{
		/* When F10 is pressed gtk+ automatically opens the menu if the
		 * menubar is visible, but when the menubar is not visible
		 * (think fullscreen or popup windows) we show it manually and
		 * hide again when the user activates or otherwise dismisses
		 * the menu.
		 */

		gulong *handler_id = g_new(gulong, 1);

		*handler_id = g_signal_connect_data (priv->menubar, "deactivate",
						     G_CALLBACK(menubar_deactivate_cb),
						     handler_id, (GClosureNotify)g_free, 0);
		gtk_widget_show (GTK_WIDGET(priv->menubar->parent));
		gtk_menu_shell_select_first (GTK_MENU_SHELL(priv->menubar),
				             FALSE);
		return TRUE;
	}

	return GTK_WIDGET_CLASS(parent_class)->key_press_event(window, event);
}

static gboolean
galeon_window_delete_event (GtkWidget *widget, GdkEventAny *event)
{
	GaleonWindow *window = GALEON_WINDOW (widget);

	if (!galeon_window_can_close (window))
	{
		return TRUE;
	}

	window->priv->closing = TRUE;
	return gul_gui_widget_hide_now (widget);
}

static gboolean
galeon_window_state_event_cb (GtkWidget *widget,
			      GdkEventWindowState *event,
			      gpointer data)
{
	if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
	{
		GaleonWindow *window = GALEON_WINDOW (widget);
		if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
		{
			galeon_window_fullscreen (window);
		}
		else
		{
			galeon_window_unfullscreen (window);
		}
	}
	return FALSE;
}


static gboolean
confirm_close_with_modified_forms (GaleonWindow *window, GaleonTab *tab)
{
	GtkWidget *dialog;
	int response;

	/* Jump to the modified tab with modified forms */
	gtk_window_present (GTK_WINDOW (window));
	galeon_window_jump_to_tab (window, tab);

	dialog = hig_alert_new (GTK_WINDOW (window),
				GTK_DIALOG_MODAL,
				HIG_ALERT_CONFIRMATION,
				_("Discard changes?"),
				_("This page contains changes that have not been submitted."),
				GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				_("_Discard Changes"), GTK_RESPONSE_OK,
				NULL);

	response = gtk_dialog_run (GTK_DIALOG (dialog));

	gtk_widget_destroy (dialog);

	return response == GTK_RESPONSE_OK;
}


gboolean
galeon_window_can_close (GaleonWindow *window)
{
	GList *tabs, *l;
	gboolean allow_close = TRUE;

	tabs = galeon_window_get_tabs (window);
	for (l = tabs; l != NULL; l = l->next)
	{
		GaleonTab *tab = (GaleonTab *) l->data;
		GaleonEmbed *embed;

		g_return_val_if_fail (IS_GALEON_TAB (tab), FALSE);

		embed = galeon_tab_get_embed (tab);
		g_return_val_if_fail (IS_GALEON_EMBED (embed), FALSE);

		if (galeon_embed_has_modified_forms (embed) == G_OK &&
		    confirm_close_with_modified_forms (window, tab) == FALSE)
		{
			allow_close = FALSE;
			break;
		}
	}
	g_list_free (tabs);

	return allow_close;
}

static gboolean
focus_in_event_cb(GaleonWindow *window, GdkEventFocus *event)
{
	galeon_shell_set_active_window(galeon_shell, window);	
	return FALSE;
}

static void
setup_gtk_window (GaleonWindow *window)
{
	g_signal_connect (G_OBJECT(window), "window_state_event",
			  G_CALLBACK (galeon_window_state_event_cb), NULL);
	
	g_signal_connect (G_OBJECT(window),
			  "focus-in-event",
			  G_CALLBACK (focus_in_event_cb), NULL);
}

static void
tabbed_position_gconf_changed_cb(GConfClient *client,
                             guint cnxn_id,
                             GConfEntry *entry,
                             GtkNotebook *notebook)
{
	GtkPositionType position = eel_gconf_get_integer (CONF_TABS_TABBED_EDGE);    
	gtk_notebook_set_tab_pos (notebook, position);
}


static void
tabbed_always_show_gconf_changed_cb(GConfClient *client,
				    guint cnxn_id,
				    GConfEntry *entry,
				    GtkNotebook *notebook)
{
	GtkPositionType policy = eel_gconf_get_boolean (CONF_TABS_TABBED_ALWAYS_SHOW)
		? GTK_POLICY_ALWAYS
		: GTK_POLICY_AUTOMATIC;
	gul_notebook_set_policy (GUL_NOTEBOOK (notebook), policy);
}

static GtkNotebook *
setup_notebook (GaleonWindow *window)
{
	GtkNotebook *notebook;
	GtkPolicyType policy;
	GtkPositionType position = eel_gconf_get_integer (CONF_TABS_TABBED_EDGE);

	policy = eel_gconf_get_boolean (CONF_TABS_TABBED_ALWAYS_SHOW)
		 ? GTK_POLICY_ALWAYS
		 : GTK_POLICY_AUTOMATIC;
	
	notebook = GTK_NOTEBOOK (gul_notebook_new ());
	gtk_notebook_set_scrollable (notebook, TRUE);
	gtk_notebook_set_show_border (notebook, FALSE);
	gtk_notebook_set_tab_pos (notebook, position);
	gul_notebook_set_policy (GUL_NOTEBOOK (notebook), policy);
	gtk_notebook_popup_disable (notebook);

	g_signal_connect_after(G_OBJECT(notebook), "button-press-event",
			       G_CALLBACK(
				galeon_window_notebook_button_press_cb),
				window);

	g_signal_connect(G_OBJECT(notebook), "popup-menu",
			 G_CALLBACK(
				galeon_window_notebook_popup_menu_cb),
				window);

	g_signal_connect_after (G_OBJECT (notebook), "switch_page",
				G_CALLBACK (
				galeon_window_notebook_switch_page_cb),
				window);

	g_signal_connect (G_OBJECT (notebook), "tab_detached", 
			  G_CALLBACK (galeon_window_tab_detached_cb), 
			  window);
	g_signal_connect (G_OBJECT (notebook), "tabs_reordered", 
			  G_CALLBACK (galeon_window_tabs_reordered_cb), 
			  window);

	g_signal_connect (G_OBJECT (notebook), "tab_added", 
			  G_CALLBACK (galeon_window_tab_added_cb), 
			  window);

	g_signal_connect (G_OBJECT (notebook), "tab_removed", 
			  G_CALLBACK (galeon_window_tab_removed_cb), 
			  window);

	g_signal_connect (G_OBJECT (notebook), "tab_delete", 
			  G_CALLBACK (galeon_window_tab_delete_cb), 
			  window);
 
	galeon_dnd_url_drag_dest_set_with_flags (GTK_WIDGET(notebook),
						 GTK_DEST_DEFAULT_MOTION |
						 GTK_DEST_DEFAULT_DROP);
 
	g_signal_connect (G_OBJECT(notebook), "drag_data_received",
			  G_CALLBACK(galeon_window_tab_drag_data_received_cb),
			  NULL);
 
	galeon_notification_add(CONF_TABS_TABBED_EDGE,
				(GConfClientNotifyFunc)tabbed_position_gconf_changed_cb,
				notebook, &window->priv->notifiers);

	galeon_notification_add(CONF_TABS_TABBED_ALWAYS_SHOW,
				(GConfClientNotifyFunc)tabbed_always_show_gconf_changed_cb,
				notebook, &window->priv->notifiers);
    
	gtk_widget_show (GTK_WIDGET (notebook));

	return notebook;
}

static void
setup_bookmarks_menu (GaleonWindow *window, GbBookmarkSet *bs)
{
	GaleonWindowPrivate *p = window->priv;
	GtkWidget *menu_item;
	GtkWidget *menu_shell;
	
	menu_item = gtk_ui_manager_get_widget (window->merge,
					       BOOKMARK_MENU_PATH);
	menu_shell = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu_item));
	
	p->bookmarks_menu = gb_gtk_menu_new (bs->root, GTK_MENU_SHELL(menu_shell));
	gb_gtk_menu_set_location_source (p->bookmarks_menu, GB_LOCATION_SOURCE (window));
	
	gb_gtk_menu_fill_children_submenus (p->bookmarks_menu);
	
	g_signal_connect (p->bookmarks_menu, "bookmark-activated", 
			  G_CALLBACK (galeon_window_bookmark_activated_cb), window);
}

static void
galeon_window_add_bookmark_toolbar (GbGtkToolbarSet *gts, GbFolder *f, GtkWidget *tb, gpointer data)
{
	GaleonWindow *window = data;
	static guint ihatebonoboui = 0;

	char *name = g_strdup_printf("BookmarksToolbar%d", ihatebonoboui++);
	GtkWidget *item = egg_dock_item_new(name, "Bookmarks Toolbar",
					    EGG_DOCK_ITEM_BEH_NORMAL);
	g_free(name);

	eel_gconf_get_boolean(GCONF_DETACH_TOOLBAR) ?
		egg_dock_item_unlock(EGG_DOCK_ITEM(item)) :
		egg_dock_item_lock(EGG_DOCK_ITEM(item));

	egg_dock_add_item (EGG_DOCK(window->egg_dock),
			      EGG_DOCK_ITEM(item),
			      EGG_DOCK_BOTTOM);
	gtk_container_add(GTK_CONTAINER(item), tb);
	gtk_widget_show(item);

	g_signal_connect_swapped (tb, "hide", 
				  G_CALLBACK (gtk_widget_hide), item);
	g_signal_connect_swapped (tb, "show", 
				  G_CALLBACK (gtk_widget_show), item);
}

static void
galeon_window_remove_bookmark_toolbar (GbGtkToolbarSet *gts, GbFolder *f, GtkWidget *tb, gpointer data)
{
	/* TODO: this is a hack just to keep going while we still use BonoboDock */
	if (tb->parent)
	{
		if (tb->parent->parent)
		{
			gtk_container_remove (GTK_CONTAINER (tb->parent->parent), tb->parent);
		}
	}
}

static GbGtkToolbarSet *
setup_bookmarks_toolbar (GaleonWindow *window, GbBookmarkSet *bs)
{
	GbGtkToolbarSet *toolbar;
	
	toolbar = gb_gtk_toolbar_set_new (bs, galeon_window_add_bookmark_toolbar, 
					  galeon_window_remove_bookmark_toolbar, window);
	gb_gtk_toolbar_set_set_location_source (toolbar, GB_LOCATION_SOURCE (window));
	
	g_signal_connect (toolbar, "bookmark-activated", 
			  G_CALLBACK (galeon_window_bookmark_activated_cb), window);

	return toolbar;
}

static void
update_layout_toggles(GaleonWindow *window)
{
	EmbedChromeMask mask = window->priv->chrome_mask;

	window->priv->ignore_layout_toggles = TRUE;

	gtk_toggle_action_set_active(TOGGLE_ITEM(VIEW_TOOLBAR_ACTION),
				     mask & EMBED_CHROME_TOOLBARON);
	gtk_toggle_action_set_active(TOGGLE_ITEM(VIEW_BMTOOLBARS_ACTION),
				     mask & EMBED_CHROME_PERSONALTOOLBARON);
	gtk_toggle_action_set_active(TOGGLE_ITEM(VIEW_STATUSBAR_ACTION),
				     mask & EMBED_CHROME_STATUSBARON);
	gtk_toggle_action_set_active(TOGGLE_ITEM(VIEW_SIDEBAR_ACTION),
				     mask & EMBED_CHROME_SIDEBARON);
	gtk_toggle_action_set_active(TOGGLE_ITEM(VIEW_FULLSCREEN_ACTION),
				     mask & EMBED_CHROME_OPENASFULLSCREEN);

	window->priv->ignore_layout_toggles = FALSE;
}

static void
allow_setting_gconf_changed_cb(GConfClient *client,
			       guint cnxn_id,
			       GConfEntry *entry,
			       GaleonWindow *window)
{
	gtk_toggle_action_set_active (TOGGLE_ITEM(WEB_POPUPS_ALWAYS_ACTION),
				      eel_gconf_get_boolean(CONF_FILTERING_ALLOW_POPUPS));
	update_permission_control(window);

	gtk_toggle_action_set_active(TOGGLE_ITEM(WEB_ALLOW_JS_ACTION),
				     eel_gconf_get_boolean(CONF_FILTERING_JAVASCRIPT_ENABLED));
	gtk_toggle_action_set_active(TOGGLE_ITEM(WEB_ALLOW_JAVA_ACTION),
				     eel_gconf_get_boolean(CONF_FILTERING_JAVA_ENABLED));
}

static void
radio_group_set_from_value (GaleonWindow *window, GtkRadioActionEntry *entries,
			    int n_entries, GConfValue *value)
{
	GtkAction *action;
	int val = gconf_value_get_int(value);
	g_return_if_fail (val < n_entries);
	g_return_if_fail (entries[val].value == val);

	action = gtk_action_group_get_action(window->priv->action_group, entries[val].name);

	if (! gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
	{
		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
	}
}

static void
web_cookies_policy_changed (GtkRadioAction *action, GtkRadioAction *current, 
			    GaleonWindow *window)
{
	/* The current value is the gconf value */
	gint val = gtk_radio_action_get_current_value (action);
	eel_gconf_set_integer (CONF_PERSISTENT_COOKIES_BEHAVIOR, val);
}

static void
accept_cookies_gconf_changed_cb(GConfClient *client,
				guint cnxn_id,
				GConfEntry *entry,
				GaleonWindow *window)
{
	radio_group_set_from_value (window, cookie_radio_entries,
				    n_cookie_radio_entries, entry->value);
}

static void
setup_web_menu (GaleonWindow *window)
{
	GConfValue *gcvalue;
	gcvalue = eel_gconf_get_value(CONF_PERSISTENT_COOKIES_BEHAVIOR);
	radio_group_set_from_value (window, cookie_radio_entries,
				    n_cookie_radio_entries, gcvalue);
	gconf_value_free (gcvalue);

	galeon_notification_add(CONF_PERSISTENT_COOKIES_BEHAVIOR, 
				(GConfClientNotifyFunc)accept_cookies_gconf_changed_cb, 
				window, &window->priv->notifiers);

	gtk_toggle_action_set_active(TOGGLE_ITEM(WEB_POPUPS_ALWAYS_ACTION),
				     eel_gconf_get_boolean(CONF_FILTERING_ALLOW_POPUPS));
	gtk_toggle_action_set_active(TOGGLE_ITEM(WEB_ALLOW_JS_ACTION),
				     eel_gconf_get_boolean(CONF_FILTERING_JAVASCRIPT_ENABLED));
	gtk_toggle_action_set_active(TOGGLE_ITEM(WEB_ALLOW_JAVA_ACTION),
				     eel_gconf_get_boolean(CONF_FILTERING_JAVA_ENABLED));

	galeon_notification_add(CONF_FILTERING_ALLOW_POPUPS,
				(GConfClientNotifyFunc)allow_setting_gconf_changed_cb,
				window, &window->priv->notifiers);
	galeon_notification_add(CONF_FILTERING_JAVASCRIPT_ENABLED,
				(GConfClientNotifyFunc)allow_setting_gconf_changed_cb,
				window, &window->priv->notifiers);
	galeon_notification_add(CONF_FILTERING_JAVA_ENABLED,
				(GConfClientNotifyFunc)allow_setting_gconf_changed_cb,
				window, &window->priv->notifiers);
}

static void
view_images_policy_changed (GtkRadioAction *action, GtkRadioAction *current, 
			    GaleonWindow *window)
{
	/* The current value is the gconf value */
	gint val = gtk_radio_action_get_current_value (action);
	eel_gconf_set_integer (CONF_FILTERING_IMAGE_LOADING_TYPE, val);
}

static void
view_images_gconf_changed_cb(GConfClient *client,
		             guint cnxn_id,
			     GConfEntry *entry,
			     GaleonWindow *window)
{
	radio_group_set_from_value (window, image_radio_entries,
				    n_image_radio_entries, entry->value);
}

static void
setup_images_menu(GaleonWindow *window)
{
	GConfValue *gcvalue;
	gcvalue = eel_gconf_get_value(CONF_FILTERING_IMAGE_LOADING_TYPE);
	radio_group_set_from_value (window, image_radio_entries,
				    n_image_radio_entries, gcvalue);
	gconf_value_free (gcvalue);

	galeon_notification_add(CONF_FILTERING_IMAGE_LOADING_TYPE, 
				(GConfClientNotifyFunc)view_images_gconf_changed_cb, 
				window, &window->priv->notifiers);
}

static void
sidebar_close_requested_cb (GaleonSidebar *sidebar, 
			    GaleonWindow *window)
{
	GtkToggleAction *action = TOGGLE_ITEM(VIEW_SIDEBAR_ACTION);

	gtk_toggle_action_set_active(action, FALSE);
}

static void
sidebar_page_changed_cb (GaleonSidebar *sidebar, 
			 const char *page_id, 
			 GaleonWindow *window)
{
	GaleonEmbed *embed;

	embed = galeon_window_get_active_embed (window);

	if (strcmp (page_id, "history") == 0)
	{
		window->priv->history_sidebar = 
			history_dialog_new (embed, TRUE);
	
		galeon_sidebar_set_content 
			(sidebar, 
			 G_OBJECT(window->priv->history_sidebar));
	}
	else if (strcmp (page_id, "bookmarks") == 0)
	{
		GtkWidget *w;
		if (!window->priv->bookmarks_sidebar)
		{
			GbEditorDockable *e;
			GbBookmarkSet *set;
			
			set = galeon_shell_get_bookmark_set (galeon_shell);
			if (!set) return;
		
			e = gb_editor_dockable_new_for_set (set);
			
			gb_editor_set_location_source (GB_EDITOR (e), GB_LOCATION_SOURCE (window));

			g_signal_connect (e, "bookmark-activated", 
					  G_CALLBACK (galeon_window_bookmark_activated_cb), window);
			window->priv->bookmarks_sidebar = e;
		}
		w = gb_editor_get_main_widget (GB_EDITOR (window->priv->bookmarks_sidebar));
		gtk_widget_show (w);
		galeon_sidebar_set_content (sidebar, G_OBJECT (w));
	}
}

static GtkWidget *
setup_sidebar (GaleonWindow *window)
{
	GtkWidget *hpaned;
	GtkWidget *sidebar;

	hpaned = gtk_hpaned_new ();
	gtk_widget_show (hpaned);

	sidebar = galeon_sidebar_new ();

	g_signal_connect (G_OBJECT(sidebar),
			  "close_requested",
			  G_CALLBACK (sidebar_close_requested_cb),
			  window);
	
	galeon_sidebar_add_page (GALEON_SIDEBAR(sidebar), 
				 _("Bookmarks"), "bookmarks", FALSE);
	galeon_sidebar_add_page (GALEON_SIDEBAR(sidebar), 
				 _("History"), "history", FALSE);

	g_signal_connect (sidebar, "page_changed",
			  G_CALLBACK (sidebar_page_changed_cb),
			  window);

	gtk_paned_add1 (GTK_PANED(hpaned), 
			sidebar);
	gtk_paned_add2 (GTK_PANED(hpaned),
			GTK_WIDGET(window->priv->notebook));

	gul_state_monitor_paned (hpaned, STATE_SIDEBAR_SIZE,
			         STATE_SIDEBAR_SIZE_DEFAULT);

	window->priv->sidebar = sidebar;
	
	return hpaned;
}

static void
statusbar_request_cb (Statusbar *statusbar, StatusbarRequest request, GaleonWindow *window)
{
	switch (request)
	{
	case STATUSBAR_SHOW_SECURITY_INFO:
		galeon_window_show_page_info (window, PAGE_INFO_SECURITY);
		break;
	}
}


static void
ppview_toolbar_print_cb (PPViewToolbar *toolbar, GaleonWindow *window)
{
	gtk_action_activate (ACTION_ITEM (FILE_PRINT_ACTION));
}

static void
menu_item_select_cb (GtkMenuItem *proxy,
		     GaleonWindow *window)
{
	GtkAction *action;
	char *message;

	action = g_object_get_data (G_OBJECT (proxy),  "gtk-action");
	g_return_if_fail (action != NULL);
	
	g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
	if (message)
	{
		gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar),
				    1, message);
		g_free (message);
	}
}

static void
menu_item_deselect_cb (GtkMenuItem *proxy,
		       GaleonWindow *window)
{
	gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar), 1);
}

static void
ui_manager_disconnect_proxy_cb (GtkUIManager *manager,
				GtkAction *action,
				GtkWidget *proxy,
				GaleonWindow *window)
{
	if (GTK_IS_MENU_ITEM (proxy))
	{
		g_signal_handlers_disconnect_by_func
			(proxy, G_CALLBACK (menu_item_select_cb), window);
		g_signal_handlers_disconnect_by_func
			(proxy, G_CALLBACK (menu_item_deselect_cb), window);
	}
}

static void
ui_manager_connect_proxy_cb (GtkUIManager *manager,
			    GtkAction *action,
			    GtkWidget *proxy,
			    GaleonWindow *window)
{
	if (GTK_IS_MENU_ITEM (proxy))
	{
		g_signal_connect (proxy, "select",
				  G_CALLBACK (menu_item_select_cb), window);
		g_signal_connect (proxy, "deselect",
				  G_CALLBACK (menu_item_deselect_cb), window);
	}
}

static void
ui_manager_widget_add (GtkUIManager *merge, GtkWidget *widget, GaleonWindow *window)
{
	if (GTK_IS_MENU_SHELL(widget))
	{
	        GtkWidget *item;
		window->priv->menubar = widget;
		gtk_widget_show(widget);
		LOG( "Adding menu bar" );

		item = egg_dock_item_new("EggMenu",
					 "Menubar",
					 EGG_DOCK_ITEM_BEH_NORMAL);
		eel_gconf_get_boolean(GCONF_DETACH_MENUBAR) ?
			egg_dock_item_unlock(EGG_DOCK_ITEM(item)) :
			egg_dock_item_lock(EGG_DOCK_ITEM(item));

		egg_dock_add_item(EGG_DOCK(window->egg_dock),
				  EGG_DOCK_ITEM(item),
				  EGG_DOCK_TOP);
		gtk_container_add(GTK_CONTAINER(item), widget);
		gtk_widget_show(item);
	}
	else if (GTK_IS_TOOLBAR(widget))
	{
	        GtkWidget *item;
		gtk_widget_show (widget);
		LOG( "Adding toolbar" );
		item = egg_dock_item_new("PPVToolbar",
					 "Print Preview Toolbar",
					 EGG_DOCK_ITEM_BEH_NORMAL);
		eel_gconf_get_boolean(GCONF_DETACH_TOOLBAR) ?
			egg_dock_item_unlock(EGG_DOCK_ITEM(item)) :
			egg_dock_item_lock(EGG_DOCK_ITEM(item));

		egg_dock_add_item(EGG_DOCK(window->egg_dock),
				  EGG_DOCK_ITEM(item),
				  EGG_DOCK_TOP);
		gtk_container_add(GTK_CONTAINER(item), widget);
		/* Don't show dock_item. Controlled by ppvtoolbar object */
	}
	else
	{
		g_warning ("unexpected widget in egg_widget_add");
	}
}

static void
toolbar_style_gconf_changed_cb(GConfClient *client,
			       guint cnxn_id,
			       GConfEntry *entry,
			       GaleonWindow *window)
{
	gint i;
	EggToolbarsModel *model;
	GtkToolbar *ppvtb;
	EggTbModelFlags flags;
	GtkToolbarStyle style = GTK_TOOLBAR_BOTH_HORIZ;

	gchar *override_style = eel_gconf_get_string(CONF_TOOLBAR_STYLE);

	if (!override_style ||
	    g_ascii_strcasecmp(override_style, "system") == 0)
	{
		flags = 0;
	}
	else if (g_ascii_strcasecmp(override_style, "icons_only") == 0)
	{
		flags = EGG_TB_MODEL_ICONS_ONLY;
		style = GTK_TOOLBAR_ICONS;
	}
	else if (g_ascii_strcasecmp(override_style, "text_only") == 0)
	{
		flags = EGG_TB_MODEL_TEXT_ONLY;
		style = GTK_TOOLBAR_TEXT;
	}
	else if (g_ascii_strcasecmp(override_style, "text_below") == 0)
	{
		flags = EGG_TB_MODEL_ICONS_TEXT;
		style = GTK_TOOLBAR_BOTH;
	}
	else if (g_ascii_strcasecmp(override_style, "text_beside") == 0)
	{
		flags = EGG_TB_MODEL_ICONS_TEXT_HORIZ;
		style = GTK_TOOLBAR_BOTH_HORIZ;
	}
	else
	{
		g_warning("Unrecognised value for toolbar_override_style");
		flags = 0;
	}
	g_free (override_style);

	model =	galeon_shell_get_toolbars_model(galeon_shell);

	for (i=0 ; i<egg_toolbars_model_n_toolbars(model) ; i++)
	{
		egg_toolbars_model_set_flags(model, flags, i);
	}

	ppvtb = GTK_TOOLBAR(gtk_ui_manager_get_widget(window->merge,
						      "/pptoolbar"));
	g_return_if_fail (GTK_IS_TOOLBAR (ppvtb));
	if (flags != 0)
	{
		gtk_toolbar_set_style(ppvtb, style);
	}
	else
	{
		gtk_toolbar_unset_style(ppvtb);
	}
}

static void
galeon_window_init (GaleonWindow *window)
{
	GtkToggleAction *offline_action;
	GaleonWindowPrivate *p;
	GbBookmarkSet *bs;
	Session *session;
	gchar *ui_file;
	GtkAction *act;
	EggDockItem *dock_item;

	session = galeon_shell_get_session (galeon_shell);

        window->priv = g_new0 (GaleonWindowPrivate, 1);
	p = window->priv;
	p->embed_popup = NULL;
	p->active_tab = NULL;
	p->chrome_mask = 0;
	p->ignore_layout_toggles = FALSE;
	p->closing = FALSE;
	p->has_default_size = FALSE;
	p->recent_history = galeon_window_recent_history_new ();

	/* Setup the window */
	setup_gtk_window(window);

	/* Setup the egg components */
	p->main_area = gtk_vbox_new(FALSE, 0);
	gtk_widget_show(p->main_area);
	window->egg_dock = G_OBJECT(egg_dock_new());
	gtk_widget_show(GTK_WIDGET(window->egg_dock));
	gtk_box_pack_start(GTK_BOX(p->main_area),
                           GTK_WIDGET(window->egg_dock), FALSE, FALSE, 0);

	p->action_group = gtk_action_group_new ("MainActions");
	gtk_action_group_set_translation_domain (p->action_group, NULL);
	gtk_action_group_add_actions (p->action_group, entries,
				      n_entries, window);
	
	gtk_action_group_add_toggle_actions (p->action_group, toggle_entries,
					     n_toggle_entries, window);

	gtk_action_group_add_radio_actions (p->action_group, image_radio_entries,
					    n_image_radio_entries, 0,
					    G_CALLBACK (view_images_policy_changed),
					    window);

	gtk_action_group_add_radio_actions (p->action_group, cookie_radio_entries,
					    n_cookie_radio_entries, 0,
					    G_CALLBACK (web_cookies_policy_changed),
					    window);

	/* connect offline action */
	offline_action = TOGGLE_ITEM(FILE_OFFLINE_ACTION);
	set_offline_action_state (offline_action,
			          eel_gconf_get_boolean (CONF_GENERAL_OFFLINE));
	galeon_notification_add(CONF_GENERAL_OFFLINE,
				gtk_cmd_gconf_toggle_monitor, 
				offline_action, &window->priv->notifiers);
	/* keep it around for statusbar */

	window->merge = gtk_ui_manager_new ();
	g_signal_connect(window->merge, "add_widget", 
			 G_CALLBACK(ui_manager_widget_add), window);
	g_signal_connect (window->merge, "connect_proxy",
			  G_CALLBACK (ui_manager_connect_proxy_cb), window);
	g_signal_connect (window->merge, "disconnect_proxy",
			  G_CALLBACK (ui_manager_disconnect_proxy_cb), window);
	gtk_ui_manager_set_add_tearoffs (window->merge,
		       eel_gconf_get_boolean ("/desktop/gnome/interface/menus_have_tearoff"));

	gtk_ui_manager_insert_action_group(window->merge, p->action_group, 0);

	/* Setup any other properties that we need */
	act = gtk_action_group_get_action (p->action_group, "ViewEncodingMenuAction");
	g_object_set (act, "hide_if_empty", FALSE, NULL);

	act = gtk_action_group_get_action (p->action_group, VIEW_FULLSCREEN_ACTION);
	g_object_set (act, "short_label", _("Fullscreen"), NULL);
	act = gtk_action_group_get_action (p->action_group, FILE_PRINT_ACTION);
	g_object_set (act, "short_label", _("Print"), NULL);
	act = gtk_action_group_get_action (p->action_group, "FileSaveAsAction");
	g_object_set (act, "short_label", _("Save As"), NULL);
	act = gtk_action_group_get_action (p->action_group, "EditFindAction");
	g_object_set (act, "short_label", _("Find"), NULL);

	/* add toolbar actions */
	/* we need to create lots of custom actions... */
	{
		GtkActionGroup *ag;

		ag = gtk_action_group_new ("ToolbarActions");
		gtk_action_group_set_translation_domain (ag, NULL);

		act = g_object_new (GALEON_TYPE_ACTION_NAVIGATION,
				    "name", "GoBack",
				    "window", window,
				    "direction", GALEON_NAVIGATION_DIRECTION_BACK,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_NAVIGATION,
				    "name", "GoBackWithArrow",
				    "window", window,
				    "direction", GALEON_NAVIGATION_DIRECTION_BACK,
				    "show_arrow", TRUE,
				    /* "short_label", _("Back History"), */
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_NAVIGATION,
				    "name", "GoForward",
				    "window", window,
				    "direction", GALEON_NAVIGATION_DIRECTION_FORWARD,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_NAVIGATION,
				    "name", "GoForwardWithArrow",
				    "window", window,
				    "direction", GALEON_NAVIGATION_DIRECTION_FORWARD,
				    "show_arrow", TRUE,
				    /* "short_label", _("Forward History"), */
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_NAVIGATION,
				    "name", "GoUp",
				    "window", window,
				    "direction", GALEON_NAVIGATION_DIRECTION_UP,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_NAVIGATION,
				    "name", "GoUpWithArrow",
				    "window", window,
				    "direction", GALEON_NAVIGATION_DIRECTION_UP,
				    "show_arrow", TRUE,
				    /* "short_label", _("Up (with menu)"), */
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_LOCATION,
				    "name", "LocationEntry",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);
		p->location_action = GALEON_ACTION_LOCATION (act);

		act = g_object_new (GALEON_TYPE_ACTION_HOME,
				    "name", "GoHome",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_NEW,
				    "name", "New",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_REFRESH,
				    "name", "Refresh",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_STOP,
				    "name", "Stop",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_GO,
				    "name", "GoTo",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_ZOOM,
				    "name", "ZoomSpinner",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		act = g_object_new (GALEON_TYPE_ACTION_SPINNER,
				    "name", "LogoSpinner",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);
		p->spinner_action = GALEON_ACTION_SPINNER (act);

		act = g_object_new (GALEON_TYPE_ACTION_FAVICON,
				    "name", "Favicon",
				    "window", window,
				    NULL);
		gtk_action_group_add_action (ag, act);
		g_object_unref (act);

		gtk_ui_manager_insert_action_group (window->merge, ag, 0);
		g_object_unref (ag);

	}

	/* add the editable toolbar */
	{
		GtkWidget *item = egg_dock_item_new("EggEditableToolbar",
						    "Primary Toolbar",
						    EGG_DOCK_ITEM_BEH_NORMAL);
		GtkWidget *et = egg_editable_toolbar_new (window->merge, 
							  galeon_shell_get_toolbars_model (galeon_shell));
		gtk_widget_show (et);

		eel_gconf_get_boolean(GCONF_DETACH_TOOLBAR) ?
			egg_dock_item_unlock(EGG_DOCK_ITEM(item)) :
			egg_dock_item_lock(EGG_DOCK_ITEM(item));

		egg_dock_add_item(EGG_DOCK(window->egg_dock),
				  EGG_DOCK_ITEM(item),
				  EGG_DOCK_TOP);
		gtk_container_add(GTK_CONTAINER(item), et);
		gtk_widget_show(item);

		p->egg_toolbar = EGG_EDITABLE_TOOLBAR (et);
	}

	/* Setup the embed popups factory */
	p->embed_popup = galeon_window_get_popup_factory (window);

	/* add the printpreview toolbar */
	p->ppview_toolbar = ppview_toolbar_new(window);
	g_signal_connect_object (p->ppview_toolbar, "print",
				 G_CALLBACK (ppview_toolbar_print_cb),
				 window, 0);

	ui_file = gul_general_user_file("galeon-egg-ui.xml", TRUE);
	gtk_ui_manager_add_ui_from_file (window->merge, ui_file, NULL);
	g_free (ui_file);

	gtk_ui_manager_ensure_update (window->merge);

	dock_item = egg_dock_get_item_by_name (EGG_DOCK(window->egg_dock),
					       "PPVToolbar");

	ppview_toolbar_set_dock_item (p->ppview_toolbar, dock_item);

	gtk_window_add_accel_group (GTK_WINDOW(window), 
				    gtk_ui_manager_get_accel_group (window->merge));


	/* Apply galeon's local override style for the toolbar is appropriate
	 * and attach gconf notifier to override toolbar style
	 */
	toolbar_style_gconf_changed_cb(NULL, 0, NULL, window);

	galeon_notification_add(CONF_TOOLBAR_STYLE,
				(GConfClientNotifyFunc)toolbar_style_gconf_changed_cb,
				window, &window->priv->notifiers);

	/* Setup gtk menus */
	setup_images_menu(window);
	setup_web_menu(window);

	p->css_menu = galeon_css_menu_new (window);
	p->encoding_menu = galeon_encoding_menu_new (window);
	p->window_menu = galeon_window_menu_new (window);
	p->rh_menu = galeon_recent_history_menu_new (window, p->recent_history);

	/* Setup bookmarks ui elements */
	bs = galeon_shell_get_bookmark_set (galeon_shell);
	setup_bookmarks_menu(window, bs);
	p->bookmarks_toolbar = setup_bookmarks_toolbar (window, bs); 	

	/* Setup statusbar */
	p->statusbar = statusbar_new(offline_action);
	g_signal_connect (G_OBJECT(p->statusbar), "request",
			  G_CALLBACK(statusbar_request_cb),
			  window);
	gtk_widget_show(p->statusbar);

	/* Setup window contents */
	p->notebook = setup_notebook (window);
	p->tab_menu = galeon_tab_menu_new (window);

	p->hpaned = setup_sidebar (window);
	gtk_box_pack_end(GTK_BOX(p->main_area),
			 p->statusbar,
			 FALSE, FALSE, 0);
	gtk_box_pack_end(GTK_BOX(p->main_area),
			 GTK_WIDGET(p->hpaned),
			 TRUE, TRUE, 0);

	gtk_container_add(GTK_CONTAINER(window),
			  GTK_WIDGET(p->main_area));

	g_object_ref (galeon_shell);

	/*Once window is fully created, add it to the session list*/
	session_add_window (session, window);
}

static void  
save_window_chrome (GaleonWindow *window)
{
	EmbedChromeMask flags = window->priv->chrome_mask;
	
	if (flags & EMBED_CHROME_OPENASPOPUP)
	{
	}
	else if (flags & EMBED_CHROME_PPVIEWTOOLBARON)
	{
	}
	else if (flags & EMBED_CHROME_OPENASFULLSCREEN)
	{
		eel_gconf_set_boolean (CONF_WINDOWS_FS_SHOW_SIDEBAR,
				       flags & EMBED_CHROME_SIDEBARON);
		eel_gconf_set_boolean (CONF_WINDOWS_FS_SHOW_TOOLBARS,
				       flags & EMBED_CHROME_TOOLBARON);
		eel_gconf_set_boolean (CONF_WINDOWS_FS_SHOW_BOOKMARKS,
				       flags & EMBED_CHROME_PERSONALTOOLBARON);
		eel_gconf_set_boolean (CONF_WINDOWS_FS_SHOW_STATUSBAR,
				       flags & EMBED_CHROME_STATUSBARON);
	}
	else
	{
		eel_gconf_set_boolean (CONF_WINDOWS_SHOW_SIDEBAR,
				       flags & EMBED_CHROME_SIDEBARON);
		eel_gconf_set_boolean (CONF_WINDOWS_SHOW_TOOLBARS,
				       flags & EMBED_CHROME_TOOLBARON);
		eel_gconf_set_boolean (CONF_WINDOWS_SHOW_BOOKMARKS,
				       flags & EMBED_CHROME_PERSONALTOOLBARON);
		eel_gconf_set_boolean (CONF_WINDOWS_SHOW_STATUSBAR,
				       flags & EMBED_CHROME_STATUSBARON);
	}
}

static void
remove_from_session (GaleonWindow *window)
{
	Session *session;

	session = galeon_shell_get_session (galeon_shell);
	g_return_if_fail (session != NULL);
	
	session_remove_window (session, window);
}

static void
galeon_window_dispose (GObject *object)
{
	GaleonWindow *window = GALEON_WINDOW (object);
	GaleonWindowPrivate *p = window->priv;

	if (window->priv->notebook)
	{
		remove_from_session (window);
	}

	/* Ensure that we don't reference these objects after the
	 * dispose, they may have been destroyed */
	window->priv->notebook = 0;
	window->priv->hpaned = 0;
	window->priv->active_tab = 0;
	window->priv->sidebar = 0;

	if (p->css_menu)
	{
		g_object_unref (p->css_menu);
		p->css_menu = 0;
	}

	G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
galeon_window_finalize (GObject *object)
{
        GaleonWindow *window;
	GaleonWindowPrivate *p;

        g_return_if_fail (IS_GALEON_WINDOW (object));

	window = GALEON_WINDOW (object);
	p = window->priv;

        g_return_if_fail (p != NULL);

	galeon_notification_remove (&p->notifiers);

	if (p->embed_popup)
	{
		g_object_unref (G_OBJECT (p->embed_popup));
	}

	g_object_unref (G_OBJECT (window->priv->bookmarks_toolbar));
	g_object_unref (G_OBJECT (window->priv->ppview_toolbar));
	
	if (p->find_dialog)
	{
		g_object_unref (G_OBJECT (p->find_dialog));
	}

	if (p->history_dialog)
	{
		g_object_remove_weak_pointer 
                        (G_OBJECT(p->history_dialog),
                         (gpointer *)&p->history_dialog);
	}

	if (p->bookmarks_sidebar)
	{
		g_object_unref (p->bookmarks_sidebar);
	}
	
	g_object_unref (p->tab_menu);
	g_object_unref (p->window_menu);
	g_object_unref (p->recent_history);
	g_object_unref (p->rh_menu);
	g_object_unref (p->bookmarks_menu);
	g_object_unref (p->encoding_menu);

	g_object_unref(p->action_group);
	g_object_unref(window->merge);

        g_free (p);

        G_OBJECT_CLASS (parent_class)->finalize (object);

	LOG ("Galeon Window finalized %p", window);
	
	g_object_unref (galeon_shell);
}

GaleonWindow *
galeon_window_new (void)
{
	return GALEON_WINDOW (g_object_new (GALEON_WINDOW_TYPE, NULL));
}

EmbedChromeMask  
galeon_window_get_chrome (GaleonWindow *window)
{
	return window->priv->chrome_mask;
}

static void
translate_default_chrome (EmbedChromeMask *chrome_mask)
{	
	/* keep only not layout flags */
	*chrome_mask &= (EMBED_CHROME_WINDOWRAISED |
        		 EMBED_CHROME_WINDOWLOWERED |
        		 EMBED_CHROME_CENTERSCREEN |
        		 EMBED_CHROME_OPENASDIALOG |
        		 EMBED_CHROME_OPENASCHROME |
        		 EMBED_CHROME_OPENASPOPUP |
			 EMBED_CHROME_OPENASFULLSCREEN);

	/* Load defaults */
	if (*chrome_mask & EMBED_CHROME_OPENASFULLSCREEN)
	{
		if (eel_gconf_get_boolean (CONF_WINDOWS_FS_SHOW_SIDEBAR))
		{
			*chrome_mask |= EMBED_CHROME_SIDEBARON;
		}
		if (eel_gconf_get_boolean (CONF_WINDOWS_FS_SHOW_STATUSBAR))
		{
			*chrome_mask |= EMBED_CHROME_STATUSBARON;
		}
		if (eel_gconf_get_boolean (CONF_WINDOWS_FS_SHOW_TOOLBARS))
		{
			*chrome_mask |= EMBED_CHROME_TOOLBARON;
		}
		if (eel_gconf_get_boolean (CONF_WINDOWS_FS_SHOW_BOOKMARKS))
		{
			*chrome_mask |= EMBED_CHROME_PERSONALTOOLBARON;
		}
	}
	else
	{
		if (eel_gconf_get_boolean (CONF_WINDOWS_SHOW_SIDEBAR))
		{
			*chrome_mask |= EMBED_CHROME_SIDEBARON;
		}
		if (eel_gconf_get_boolean (CONF_WINDOWS_SHOW_STATUSBAR))
		{
			*chrome_mask |= EMBED_CHROME_STATUSBARON;
		}
		if (eel_gconf_get_boolean (CONF_WINDOWS_SHOW_TOOLBARS))
		{
			*chrome_mask |= EMBED_CHROME_TOOLBARON;
		}
		if (eel_gconf_get_boolean (CONF_WINDOWS_SHOW_BOOKMARKS))
		{
			*chrome_mask |= EMBED_CHROME_PERSONALTOOLBARON;
		}
		
		*chrome_mask |= EMBED_CHROME_MENUBARON;
	}
}

/* Called after GaleonWindow has switched to fullscreen, setup toolbars etc. to
 * match.
 */
static void
galeon_window_fullscreen (GaleonWindow *window)
{
	EmbedChromeMask mask;

	mask = window->priv->chrome_mask;
	mask |= EMBED_CHROME_DEFAULT;
	mask |= EMBED_CHROME_OPENASFULLSCREEN;
	galeon_window_set_chrome (window, mask);
}

/* Called after GaleonWindow has switched back to normal size again, restore
 * normal toolbar etc. layouts.
 */
static void
galeon_window_unfullscreen (GaleonWindow *window)
{
	EmbedChromeMask mask;

	mask = window->priv->chrome_mask;
	mask |= EMBED_CHROME_DEFAULT;
	mask &= ~EMBED_CHROME_OPENASFULLSCREEN;
	galeon_window_set_chrome (window, mask);
}

static void
galeon_window_toolbar_set_visibility (GaleonWindow *window, gboolean visible)
{
	GaleonWindowPrivate *p = window->priv;
	EggToolbarsModel *model = galeon_shell_get_toolbars_model (galeon_shell);
	int n_toolbars = egg_toolbars_model_n_toolbars (model);
	int i;

	for (i = 0; i < n_toolbars; i++)
	{
		const char *t_name = egg_toolbars_model_toolbar_nth (EGG_TOOLBARS_MODEL (model), i);

		if (visible)
		{
			egg_editable_toolbar_show (p->egg_toolbar, t_name);
		}
		else
		{
			egg_editable_toolbar_hide (p->egg_toolbar, t_name);
			
		}
	}
}

void  
galeon_window_set_chrome (GaleonWindow *window, 
			  EmbedChromeMask flags)
{
	gboolean toolbar, ppvtoolbar, statusbar;
	
	/* If we are already in Print Preview mode, and the flags still
	 * say to stay in print preview mode, then just update the preview
	 * toolbars idea of the old chrome (but only if it there are any flags
	 * set)
	 */
	if (window->priv->chrome_mask & EMBED_CHROME_PPVIEWTOOLBARON &&
	    flags & EMBED_CHROME_PPVIEWTOOLBARON)
	{
		int new_flags = (flags & ~EMBED_CHROME_PPVIEWTOOLBARON);
		if (new_flags)
		{
			ppview_toolbar_set_old_chrome (window->priv->ppview_toolbar,
						       new_flags);
		}
		return;
	}

	if (flags & EMBED_CHROME_DEFAULT)
	{
		translate_default_chrome (&flags);
	}
		
	if ((flags & EMBED_CHROME_MENUBARON) != FALSE)
	{
		if (window->priv->menubar)
		{
			gtk_widget_show(window->priv->menubar->parent);
		}
	}
	else
	{
		if (window->priv->menubar)
		{
			gtk_widget_hide(window->priv->menubar->parent);
		}
	}

	if ((flags & EMBED_CHROME_SIDEBARON) != FALSE)
	{
		gtk_widget_show (window->priv->sidebar);
	}
	else
	{
		gtk_widget_hide (window->priv->sidebar);
	}
	
	toolbar = (flags & EMBED_CHROME_TOOLBARON) != FALSE;
	galeon_window_toolbar_set_visibility (window, toolbar);

	statusbar = (flags & EMBED_CHROME_STATUSBARON) != FALSE;
	statusbar_set_visibility (STATUSBAR(window->priv->statusbar),
				  statusbar);

	ppvtoolbar = (flags & EMBED_CHROME_PPVIEWTOOLBARON) != FALSE;
	ppview_toolbar_set_old_chrome (window->priv->ppview_toolbar,
				       window->priv->chrome_mask);
	ppview_toolbar_set_visibility (window->priv->ppview_toolbar, 
				       ppvtoolbar);
	
	gb_gtk_toolbar_set_set_visible (window->priv->bookmarks_toolbar,
					flags & EMBED_CHROME_PERSONALTOOLBARON);
	
	window->priv->chrome_mask = flags;

	update_layout_toggles (window);

	save_window_chrome (window);
}

void
galeon_window_toggle_fullscreen (GaleonWindow *window)
{
	if (gdk_window_get_state (GTK_WIDGET (window)->window) & GDK_WINDOW_STATE_FULLSCREEN)
	{
		gtk_window_unfullscreen (GTK_WINDOW (window));
	}
	else
	{
		gtk_window_fullscreen (GTK_WINDOW (window));
	}
}

void 
galeon_window_add_tab (GaleonWindow *window, 
		       GaleonTab *tab,
		       gint position,
		       gboolean jump_to)
{
	g_return_if_fail (IS_GALEON_WINDOW (window));
	g_return_if_fail (IS_GALEON_TAB (tab));

	galeon_tab_set_window (tab, window);
	
	gul_notebook_insert_page (GUL_NOTEBOOK (window->priv->notebook), 
				  GTK_WIDGET (tab),
				  position,
				  jump_to);
}

void
galeon_window_next_tab (GaleonWindow *window)
{
	gtk_notebook_next_page (GTK_NOTEBOOK(window->priv->notebook));
}

void
galeon_window_prev_tab (GaleonWindow *window)
{
	gtk_notebook_prev_page (GTK_NOTEBOOK(window->priv->notebook));
}

void 
galeon_window_jump_to_tab (GaleonWindow *window, 
			   GaleonTab *tab)
{
	int page;
	
	page = gtk_notebook_page_num (window->priv->notebook, GTK_WIDGET (tab));
	gtk_notebook_set_current_page (window->priv->notebook, page);
}

static GaleonTab *
get_tab_from_page_num (GtkNotebook *notebook, gint page_num) 
{
	GtkWidget *widget;

	if (page_num < 0) return NULL;
	
	widget = gtk_notebook_get_nth_page (notebook, page_num);
	
	g_return_val_if_fail (IS_GALEON_TAB (widget), NULL);
	
	return GALEON_TAB (widget);
}

static GaleonTab *
real_get_active_tab (GaleonWindow *window, int page_num)
{
	if (page_num == -1)
	{
		page_num = gtk_notebook_get_current_page (window->priv->notebook);
	}

	return get_tab_from_page_num (window->priv->notebook, page_num);
}

gboolean
galeon_window_remove_tab (GaleonWindow *window, 
		          GaleonTab *tab)
{
	GaleonEmbed *embed;
	
	g_return_val_if_fail (IS_GALEON_WINDOW (window), FALSE);
	g_return_val_if_fail (IS_GALEON_TAB (tab), FALSE);

	embed = galeon_tab_get_embed (tab);
	
	if (galeon_embed_has_modified_forms (GALEON_EMBED (embed)) == G_OK &&
	    confirm_close_with_modified_forms (window, tab) == FALSE)
	{
		return FALSE;
	}

	gul_notebook_remove_page (GUL_NOTEBOOK (window->priv->notebook), 
				  GTK_WIDGET (tab));
	return TRUE;
}

void 
galeon_window_move_tab (GaleonWindow *window, 
			GaleonTab *tab,
			GaleonTab *new_sibling)
{
	int move_to;
	GtkNotebook *nb = window->priv->notebook;
	
	move_to = gtk_notebook_page_num (nb, GTK_WIDGET (new_sibling));

	if (tab && move_to != -1)
	{
		gul_notebook_move_page (GUL_NOTEBOOK (nb), NULL, GTK_WIDGET (tab), move_to);
	}
}

void 
galeon_window_load_url (GaleonWindow *window,
			const char *url)
{
	GaleonEmbed *embed;
	GbBookmarkSet *set;
	gchar *real_url;

        g_return_if_fail (IS_GALEON_WINDOW(window));
	embed = galeon_window_get_active_embed (window);
        g_return_if_fail (embed != NULL);
        g_return_if_fail (url != NULL);
	
	set = galeon_shell_get_bookmark_set (galeon_shell);
	real_url = gb_bookmark_set_get_url_by_nick_and_args (set, url);

        galeon_embed_load_url (embed, real_url != NULL ? real_url : url);
	galeon_embed_grab_focus (embed);

	g_free (real_url);
}

void 
galeon_window_edit_location (GaleonWindow *window)
{
	galeon_action_location_edit (window->priv->location_action);
}

gchar *
galeon_window_get_location_entry_location (GaleonWindow *window)
{
	return galeon_action_location_get_location (window->priv->location_action);
}

void
galeon_window_set_location_entry_location (GaleonWindow *window, 
					   const gchar *location)
{
	galeon_action_location_set_location (window->priv->location_action, location);
}

void
galeon_window_show (GtkWidget *widget)
{
	GaleonWindow *window = GALEON_WINDOW(widget);
	int w = -1, h = -1;
	
	if (!window->priv->chrome_mask)
	{
		galeon_window_set_chrome (window, EMBED_CHROME_DEFAULT);
	}

	if (!window->priv->has_default_size &&
	    window->priv->chrome_mask & EMBED_CHROME_OPENASPOPUP)
	{
		GaleonTab *tab;

		tab = galeon_window_get_active_tab (window);
		if (tab) galeon_tab_get_size (tab, &w, &h);
	}
	
	if (w == -1 && h == -1) 
	{
		gul_state_monitor_window (widget, "Main Window",
				          STATE_MAIN_WIDTH_DEFAULT,
					  STATE_MAIN_HEIGHT_DEFAULT);
		window->priv->has_default_size = TRUE;
	}
	
	GTK_WIDGET_CLASS (parent_class)->show (widget);
}

static void
update_status_message (GaleonWindow *window)
{
	const char *message;
	GaleonTab *tab;

	tab = galeon_window_get_active_tab (window);
	g_return_if_fail (tab != NULL);
	
	message = galeon_tab_get_status_message (tab);
	g_return_if_fail (message != NULL);
	
	statusbar_set_message (STATUSBAR(window->priv->statusbar),
			       message);
}

static void
update_progress (GaleonWindow *window)
{
	GaleonTab *tab;
	int load_percent;
	
	tab = galeon_window_get_active_tab (window);
	g_return_if_fail (tab != NULL);
	
	load_percent = galeon_tab_get_load_percent (tab);

	statusbar_set_progress (STATUSBAR(window->priv->statusbar),
			        load_percent);
}

static void
update_security (GaleonWindow *window)
{
	GaleonEmbed *embed;
	EmbedSecurityLevel level;
	char *description;
	char *state = NULL;
	gboolean secure;
	char *tooltip;

	embed = galeon_window_get_active_embed (window);
	g_return_if_fail (embed != NULL);

	if (galeon_embed_get_security_level (embed, &level, &description) != G_OK)
	{
		level = STATE_IS_UNKNOWN;
		description = NULL;
	}

	secure = FALSE;
	switch (level)
	{
	case STATE_IS_UNKNOWN:
		state = _("Unknown");
		break;
	case STATE_IS_INSECURE:
		state = _("Insecure");
		break;
	case STATE_IS_BROKEN:
		state = _("Broken");
		break;
	case STATE_IS_SECURE_MED:
		state = _("Medium");
		secure = TRUE;
		break;
	case STATE_IS_SECURE_LOW:
		state = _("Low");
		secure = TRUE;
		break;
	case STATE_IS_SECURE_HIGH:
		state = _("High");
		secure = TRUE;
		break;
	default:
		g_assert_not_reached ();
		break;
	}

	if (description != NULL)
	{
		tooltip = g_strdup_printf (_("Security level: %s\n%s"),
					   state, description);
		g_free (description);
	}
	else
	{
		tooltip = g_strdup_printf (_("Security level: %s"), state);

	}

	statusbar_set_security_state (STATUSBAR (window->priv->statusbar),
			              secure, tooltip);
	g_free (tooltip);
}

static void
update_popup_block(GaleonWindow *window)
{
	GaleonTab *tab;
	const char *uri = NULL;

	tab = galeon_window_get_active_tab (window);
	g_return_if_fail (tab != NULL);

	uri = galeon_tab_get_blocked_popup_uri(tab);

	statusbar_set_popup_block(STATUSBAR(window->priv->statusbar),
				  uri ? TRUE : FALSE, uri);
}

static void
update_title_control (GaleonWindow *window)
{
	GaleonTab *tab;
	const char *title;
	
	tab = galeon_window_get_active_tab (window);
	g_return_if_fail (tab != NULL);

	title = galeon_tab_get_title (tab);

	if (title)
	{
		gtk_window_set_title (GTK_WINDOW(window), 
				      title);
	}
}

static void
update_location_control (GaleonWindow *window)
{
	GaleonTab *tab;
	const char *location, *host = NULL;
	char *allow_images_str, *block_images_str,
	     *allow_cookies_str, *block_cookies_str,
	     *allow_popups_str;
	GnomeVFSURI *uri = NULL;
	gboolean can_view_source = FALSE;
	GaleonEmbed *embed;

	tab = galeon_window_get_active_tab (window);
	g_return_if_fail (tab != NULL);

	location = galeon_tab_get_location (tab);

	/* don't display about:blank in the location entry, it's uninteresting
	 * and prevents the user from pasting a new url after opening a new
	 * window/tab */
	if (!location || !strcmp (location, "about:blank")) location = "";

	/* Update cookie and image allow/block menu items to refer to
	 * the current host. Makes things clearer for the user
	 */
	if (location)
		uri = gnome_vfs_uri_new(location);

	if (uri)
		host = gnome_vfs_uri_get_host_name(uri);


	if (!host)
		host = _("This Site");

	allow_cookies_str = g_strdup_printf(_("_Allow Cookies From %s"), host);
	block_cookies_str = g_strdup_printf(_("_Block Cookies From %s"), host);
	allow_images_str = g_strdup_printf(_("_Allow Images From %s"), host);
	block_images_str = g_strdup_printf(_("_Block Images From %s"), host);
	allow_popups_str = g_strdup_printf(_("_Allow Popups From %s"), host);

	if (uri)
		gnome_vfs_uri_unref(uri);

	g_object_set(G_OBJECT(ACTION_ITEM(WEB_COOKIES_ALLOWSITE_ACTION)),
		     "label", allow_cookies_str, NULL);
	g_object_set(G_OBJECT(ACTION_ITEM(WEB_COOKIES_BLOCKSITE_ACTION)),
		     "label", block_cookies_str, NULL);
	g_object_set(G_OBJECT(ACTION_ITEM(WEB_POPUPS_ALLOWSITE_ACTION)),
		     "label", allow_popups_str, NULL);
	g_object_set(G_OBJECT(ACTION_ITEM(VIEW_IMAGES_ALLOWSITE_ACTION)),
		     "label", allow_images_str, NULL);
	g_object_set(G_OBJECT(ACTION_ITEM(VIEW_IMAGES_BLOCKSITE_ACTION)),
		     "label", block_images_str, NULL);

	embed = galeon_tab_get_embed (tab);
	can_view_source = (galeon_embed_can_view_source (embed) == G_OK);
	g_object_set(G_OBJECT(ACTION_ITEM(VIEW_SOURCE_ACTION)),
		     "sensitive", can_view_source, NULL);

	g_free(allow_cookies_str);
	g_free(block_cookies_str);
	g_free(allow_images_str);
	g_free(block_images_str);
	g_free(allow_popups_str);
}

static void
update_window_visibility (GaleonWindow *window)
{
	GList *tabs, *l;
	
	tabs = galeon_window_get_tabs (window);
	for (l = tabs; l != NULL; l = l->next)
	{
		GaleonTab *tab = GALEON_TAB(l->data);
		g_return_if_fail (IS_GALEON_TAB(tab));
		
		if (galeon_tab_get_visibility (tab))
		{
			gtk_widget_show (GTK_WIDGET(window));
			g_list_free (tabs);
			return;
		}
	}
	g_list_free (tabs);

	if (GTK_WIDGET_VISIBLE (GTK_WIDGET (window)))
	{
		gtk_widget_hide (GTK_WIDGET (window));
	}
}

static void
update_spinner_control (GaleonWindow *window)
{
	galeon_action_update (GALEON_ACTION (window->priv->spinner_action));
}

static void
update_permission_control (GaleonWindow *window)
{
	GaleonEmbedShell *embed_shell;
	gresult result;
	PermissionActionType image_action, cookie_action, popup_action;
	GaleonTab *tab = galeon_window_get_active_tab(window);
	if (tab == NULL) return;

	embed_shell = galeon_shell_get_embed_shell(galeon_shell);
	g_return_if_fail(embed_shell != NULL);

	result = galeon_embed_shell_test_permission(embed_shell,
						    galeon_tab_get_location(tab),
						    IMAGES_PERMISSION,
						    &image_action);
	if (result == G_OK)
	{
		g_object_set(G_OBJECT(ACTION_ITEM(VIEW_IMAGES_ALLOWSITE_ACTION)),
			     "sensitive", (image_action != ALLOW_ACTION), NULL);
		g_object_set(G_OBJECT(ACTION_ITEM(VIEW_IMAGES_BLOCKSITE_ACTION)),
			     "sensitive", (image_action != DENY_ACTION), NULL);
	}

	result = galeon_embed_shell_test_permission(embed_shell,
						    galeon_tab_get_location(tab),
						    COOKIES_PERMISSION,
						    &cookie_action);
	if (result == G_OK)
	{
		g_object_set(G_OBJECT(ACTION_ITEM(WEB_COOKIES_ALLOWSITE_ACTION)),
			     "sensitive", (cookie_action != ALLOW_ACTION), NULL);
		g_object_set(G_OBJECT(ACTION_ITEM(WEB_COOKIES_BLOCKSITE_ACTION)),
			     "sensitive", (cookie_action != DENY_ACTION), NULL);
	}

	/* If global allow popups, then the site specific menu item
	 * is always insensitive */
	if (eel_gconf_get_boolean(CONF_FILTERING_ALLOW_POPUPS))
	{
		g_object_set(G_OBJECT(ACTION_ITEM(WEB_POPUPS_ALLOWSITE_ACTION)),
			     "sensitive", FALSE, NULL);
		galeon_tab_clear_blocked_popup_uri(tab);
		update_popup_block(window);
		return;
	}
	
	result = galeon_embed_shell_test_permission(embed_shell,
						    galeon_tab_get_location(tab),
						    POPUPS_PERMISSION,
						    &popup_action);
	if (result == G_OK)
	{
		g_object_set(G_OBJECT(ACTION_ITEM(WEB_POPUPS_ALLOWSITE_ACTION)),
			     "sensitive", (popup_action != ALLOW_ACTION), NULL);
		if (popup_action == ALLOW_ACTION)
		{
			galeon_tab_clear_blocked_popup_uri(tab);
			update_popup_block(window);
		}
	}
}

void  
galeon_window_update_control (GaleonWindow *window,
			      ControlID control)
{
	g_return_if_fail (IS_GALEON_WINDOW (window));
	
	switch (control)
	{
	case StatusbarMessageControl:
		update_status_message (window);
		break;
	case StatusbarProgressControl:
		update_progress (window);
		break;
	case StatusbarSecurityControl:
		update_security (window);
		break;
	case StatusbarPopupBlockControl:
		update_popup_block(window);
		break;
	case TitleControl:
		update_title_control (window);
		break;
	case WindowVisibilityControl:
		update_window_visibility (window);
		break;
	case SpinnerControl:
		update_spinner_control (window);
		break;
	case LocationControl:
		update_location_control (window);
		break;
	case PermissionControl:
		update_permission_control(window);
		break;
	break;
	default:
		g_warning ("unknown control specified for updating");
		break;
	}
}

static void
galeon_window_update_all_controls (GaleonWindow *window)
{
	g_return_if_fail (IS_GALEON_WINDOW (window));
	
	if (galeon_window_get_active_tab (window) != NULL)
	{
		update_title_control (window);
		update_location_control (window);
		update_status_message (window);
		update_progress (window);
		update_security (window);
		update_popup_block(window);
		update_spinner_control (window);
		update_permission_control(window);
	}
}

GtkWidget *
galeon_window_get_statusbar(GaleonWindow *window)
{
	g_return_val_if_fail(IS_GALEON_WINDOW(window), NULL);
	g_return_val_if_fail(IS_STATUSBAR(window->priv->statusbar), NULL);

	return window->priv->statusbar;
}

GaleonSidebar *
galeon_window_get_sidebar (GaleonWindow *window)
{
	g_return_val_if_fail (IS_GALEON_WINDOW (window), NULL);

	if(!IS_GALEON_SIDEBAR(G_OBJECT(window->priv->sidebar)))
		setup_sidebar(window);

	return GALEON_SIDEBAR(window->priv->sidebar);
}	

GaleonTab *
galeon_window_get_active_tab (GaleonWindow *window)
{
	g_return_val_if_fail (IS_GALEON_WINDOW (window), NULL);

	return window->priv->active_tab;
}

GaleonEmbed *
galeon_window_get_active_embed (GaleonWindow *window)
{
	GaleonTab *tab;

	tab = galeon_window_get_active_tab (window);
	if (!tab) return NULL;

	g_return_val_if_fail (IS_GALEON_WINDOW (window), NULL);
	return galeon_tab_get_embed (tab);
}

GaleonPopup *
galeon_window_get_popup_factory(GaleonWindow *window)
{
	if (!window->priv->embed_popup)
	{
		window->priv->embed_popup = galeon_popup_new (window);
		galeon_popup_connect_verbs
			(GALEON_POPUP (window->priv->embed_popup),
			 window->merge);
	}
	
	return window->priv->embed_popup;
}

GulNotebook *
galeon_window_get_notebook(GaleonWindow *window)
{
	g_return_val_if_fail(IS_GALEON_WINDOW(window), NULL);
	g_return_val_if_fail(window->priv, NULL);
	g_return_val_if_fail(window->priv->notebook, NULL);

	return GUL_NOTEBOOK(window->priv->notebook);
}

GList *
galeon_window_get_tabs (GaleonWindow *window)
{
	GList *tabs = NULL;
	GtkWidget *w;
	int i = 0;
	
	g_return_val_if_fail (IS_GALEON_WINDOW (window), NULL);
	g_return_val_if_fail (window->priv->notebook, NULL);

	while ((w = gtk_notebook_get_nth_page (window->priv->notebook, i)) != NULL)
	{
		g_return_val_if_fail (IS_GALEON_TAB (w), NULL);
		
		tabs = g_list_append (tabs, GALEON_TAB (w));
		i++;
	}

	return tabs;
}

static void
save_old_embed_status (GaleonTab *tab, GaleonWindow *window)
{
	/* save old tab location status */
	gchar *l = galeon_action_location_get_location (window->priv->location_action);
	galeon_tab_set_location (tab, l);
	g_free (l);
}

static void
update_embed_dialogs (GaleonWindow *window,
		      GaleonTab *tab)
{
	GaleonEmbed *embed;
	GaleonDialog *find_dialog = window->priv->find_dialog;
	GaleonDialog *history_dialog = window->priv->history_dialog;
	GaleonDialog *history_sidebar = window->priv->history_sidebar;

	embed = galeon_tab_get_embed (tab);

	if (find_dialog)
	{
		galeon_embed_dialog_set_embed 
			(GALEON_EMBED_DIALOG(find_dialog),
			 embed);
	}

	if (history_dialog)
	{
		galeon_embed_dialog_set_embed 
			(GALEON_EMBED_DIALOG(history_dialog),
			 embed);
	}

	if (history_sidebar)
	{
		galeon_embed_dialog_set_embed 
			(GALEON_EMBED_DIALOG(history_sidebar),
			 embed);
	}
}


static void
update_tabs_menu_sensitivity (GaleonWindow *window)
{
	gboolean prev_tab, next_tab, detach;
	int current, n_pages;

	n_pages = gtk_notebook_get_n_pages
		(GTK_NOTEBOOK (window->priv->notebook));
	current = gtk_notebook_get_current_page
		(GTK_NOTEBOOK (window->priv->notebook));

	prev_tab  = (current > 0);
	next_tab  = (current < (n_pages-1));
	detach    = n_pages > 1;

	g_object_set (ACTION_ITEM ("TabsPrevAction"), "sensitive", prev_tab, NULL);
	g_object_set (ACTION_ITEM ("TabsNextAction"), "sensitive", next_tab, NULL);
	g_object_set (ACTION_ITEM ("TabsMoveLeftAction"), "sensitive", prev_tab, NULL);
	g_object_set (ACTION_ITEM ("TabsMoveRightAction"), "sensitive", next_tab, NULL);
	g_object_set (ACTION_ITEM ("TabsDetachAction"), "sensitive", detach, NULL);
	g_object_set (ACTION_ITEM ("TabsCloseOtherTabsAction"), "sensitive", detach, NULL);
}

static gboolean
show_notebook_popup_menu(GtkNotebook *notebook,
			 GaleonWindow *window,
			 guint button,
                         guint32 activate_time)
{
	GtkWidget *menu;

        menu = gtk_ui_manager_get_widget(window->merge,
					 TAB_POPUP_PATH);
	g_return_val_if_fail(menu, FALSE);
	
	gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
		       button, activate_time);
	return TRUE;
}

static gboolean
galeon_window_notebook_button_press_cb(GtkNotebook *notebook,
				       GdkEventButton *event,
				       GaleonWindow *window)
{
	if (event->type == GDK_BUTTON_PRESS && event->button == 3)
	{
		return show_notebook_popup_menu(notebook,
						window,
						3, event->time);
	}
	else
	{
		return FALSE;
	}
}

static gboolean
galeon_window_notebook_popup_menu_cb(GtkNotebook *notebook,
				     GaleonWindow *window)
{
	GtkWidget *widget = gtk_window_get_focus(GTK_WINDOW(window));

	/* Only respond if the notebook is the actual focus */
	if (IS_GUL_NOTEBOOK(widget))
	{
		return show_notebook_popup_menu(notebook,
						window,
						0,
						gtk_get_current_event_time());
	}
	else
	{
		return FALSE;
	}
}

static void
galeon_window_notebook_switch_page_cb (GtkNotebook *notebook,
				       GtkNotebookPage *page,
				       guint page_num,
				       GaleonWindow *window)
{
	GaleonTab *tab, *old_tab;
	GaleonEmbed *old_embed = NULL;
	GaleonEmbed *new_embed = NULL;

	g_return_if_fail (IS_GALEON_WINDOW (window));
	if (window->priv->closing) return;

	/* get the new tab */
	tab = real_get_active_tab (window, page_num);
	
	/* update old tab */
	old_tab = window->priv->active_tab;
	if (old_tab && tab != old_tab)
	{
		g_return_if_fail (IS_GALEON_TAB (G_OBJECT (old_tab)));
		old_embed = galeon_tab_get_embed (old_tab);
		galeon_tab_set_is_active (old_tab, FALSE);
		save_old_embed_status (old_tab, window);
	}

	/* update new tab */
	window->priv->active_tab = tab;
	galeon_tab_set_is_active (tab, TRUE);
	new_embed = galeon_tab_get_embed (window->priv->active_tab);

	g_signal_emit (window, GaleonWindowSignals[ACTIVE_EMBED_CHANGED], 0, old_embed, new_embed);

	update_embed_dialogs (window, tab);
	update_tabs_menu_sensitivity (window);

	/* update window controls */
	galeon_window_update_all_controls (window);
}

/**
 * Prompt the user for a smart bookmark arguments, and return the
 * completed URL to load, or NULL if cancelled.
 */
static char *
handle_smartsite (GaleonWindow *w, GbSmartSite *s)
{
	GtkWidget *dialog, *vbox, *label, *entry;
	int response;
	char *args[2]; /* TODO: match this with get_num_fields() */
	char *url;
	
	dialog = gtk_dialog_new_with_buttons (_("Galeon"), GTK_WINDOW(w),
					      GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
					      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					      GTK_STOCK_OK, GTK_RESPONSE_OK,
					      NULL);
	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);

	vbox = gtk_vbox_new (FALSE, 8);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);

	label = gtk_label_new (_("Enter the arguments for this smart site:"));
	gtk_box_pack_start_defaults (GTK_BOX (vbox), label);

	entry = gtk_entry_new ();
	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
	gtk_box_pack_start_defaults (GTK_BOX (vbox), entry);

	gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
	gtk_widget_show_all (dialog);

	response = gtk_dialog_run (GTK_DIALOG (dialog));
	if (response != GTK_RESPONSE_OK) {
		gtk_widget_destroy (dialog);
		return NULL;
	}

	args[0] = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
	args[1] = NULL;
	gtk_widget_destroy (dialog);
	url = gb_smart_site_subst_args(s, args);
	g_free(args[0]);
	return url;
}

/**
 * Handle the activation of a bookmark.
 */
void
galeon_window_bookmark_activate (GaleonWindow *w, GbBookmarkEventActivated *ev)
{
	GaleonTab *tab = galeon_window_get_active_tab (w);
	GbBookmark *b = ev->bookmark;
	gchar *smarted_url = NULL;
	GbBookmarkActivatedFlags f = ev->flags;
	GaleonNewTabFlags flags = 0;
	const gchar *final_url;

	g_return_if_fail (f == 	GB_BAF_DEFAULT 
			  || f == GB_BAF_NEW_TAB_OR_WINDOW
			  || f == GB_BAF_NEW_WINDOW
			  || f == GB_BAF_NEW_TAB
			  || f == GB_BAF_EDITOR);

	if (GB_IS_SEPARATOR (b))
	{
		/* don't need to activate separators */
		return;
	}

	if (GB_IS_SMART_SITE (b) 
	    && GB_SMART_SITE (b)->smarturl != NULL 
	    && (GB_SITE (b)->url == NULL 
		|| GB_SITE (b)->url[0]=='\0')
	    && (ev->url == NULL
		|| ev->url[0] == '\0'))
	{
		smarted_url = handle_smartsite (w, GB_SMART_SITE (b));
		if (smarted_url == NULL)
		{
			return;
		}
	}

	final_url = smarted_url ? smarted_url 
				: ev->url ? ev->url 
					  : GB_IS_SITE (b) ? GB_SITE (b)->url
							   : NULL;

	if (f == GB_BAF_DEFAULT)
	{
		if (GB_IS_SITE (b) && f == GB_BAF_DEFAULT)
		{
			g_return_if_fail (final_url);
			galeon_window_load_url (w, final_url);
			gb_site_set_time_visited_now (GB_SITE (b));
			g_free (smarted_url);
			return;
		}
		else if (GB_IS_FOLDER (b))
		{
			f = GB_BAF_NEW_TAB_OR_WINDOW;
		}
		else
		{
			g_free (smarted_url);
			g_warning ("Don't know what to do...");
			return;
		}
	}

	if (f == GB_BAF_NEW_WINDOW)
	{
		flags = GALEON_NEW_TAB_IN_NEW_WINDOW;
	}
	else if (f == GB_BAF_NEW_TAB)
	{
		flags = GALEON_NEW_TAB_IN_EXISTING_WINDOW;
	}
	else if (f == GB_BAF_NEW_TAB_OR_WINDOW)
	{
		GdkModifierType mod;
		gdk_event_get_state (ev->event, &mod);
		flags = galeon_shell_modifier_flags (mod);
	}
	else if (f == GB_BAF_EDITOR)
	{
		/* ignore it */
		g_free (smarted_url);
		return;
	}
	else
	{
		g_assert_not_reached ();
	}

	if (GB_IS_SITE (b))
	{
		galeon_shell_new_tab (galeon_shell, w, tab, final_url, flags);
		gb_site_set_time_visited_now (GB_SITE (b));
	}
	else if (GB_IS_FOLDER (b))
	{
		GbBookmark *bi;
		int count = 0;
		
		/* count the number of activated bookmarks */
		for (bi = GB_FOLDER (b)->child; bi; bi = bi->next)
		{
			if (GB_IS_SITE (bi))
			{
				count++;
			}
		}
		
#define MANY_BOOKMARKS_WARNING_THRESHOLD 10
		if (count > MANY_BOOKMARKS_WARNING_THRESHOLD)
		{
			gint response;
			GtkWidget *dialog = hig_alert_new
				(GTK_WINDOW (w),
				 GTK_DIALOG_MODAL,
				 HIG_ALERT_CONFIRMATION,
				 _("Open multiple bookmarks?"),
				 NULL,
				 GTK_STOCK_CANCEL,
				 GTK_RESPONSE_CANCEL,
				 _("_Open the bookmarks"),
				 1,
				 NULL);
			hig_alert_set_secondary_printf (HIG_ALERT (dialog),
				 ngettext("You have requested to show %d bookmarked "
					  "site in a different window or tab. Are you sure?",
					  "You have requested to show %d bookmarked sites "
					  "in different windows or tabs. Are you sure?", 
					  count), count);

			gtk_dialog_set_default_response (GTK_DIALOG (dialog), 1);
			
			response = gtk_dialog_run (GTK_DIALOG (dialog));
			gtk_widget_destroy (dialog);

			if (response != 1)
			{
				g_free (smarted_url);
				return;
			}
		}
		
		if (flags & GALEON_NEW_TAB_IN_NEW_WINDOW)
		{
			for (bi = GB_FOLDER (b)->child; bi; bi = bi->next)
			{
				if (GB_IS_SITE (bi))
				{
					galeon_shell_new_tab (galeon_shell, w, tab, 
							      GB_SITE (bi)->url, flags);
					gb_site_set_time_visited_now (GB_SITE (bi));
				}
			}
		}
		else
		{
			GaleonTab *jump_to_tab;
			gboolean jump_to;
			
			jump_to = flags & GALEON_NEW_TAB_JUMP;
			if (flags & GALEON_NEW_TAB_DONT_JUMP_TO) jump_to = FALSE;
			
			/* Open all bookmarks in order in the background.  Jumping
			 * to them automatically is a major performance hit with
			 * >3 bookmarks in a folder.  Once all bookmarks are opened,
			 * we can efficiently jump to the first one if 'jump to
			 * new tabs automatically' is enabled.
			 */
			flags |= GALEON_NEW_TAB_DONT_JUMP_TO;
			
			jump_to_tab = NULL;
			for (bi = GB_FOLDER (b)->child; bi; bi = bi->next)
			{
				if (GB_IS_SITE (bi))
				{
					tab = galeon_shell_new_tab (galeon_shell, w, tab,
								    GB_SITE (bi)->url, 
								    flags);
					gb_site_set_time_visited_now (GB_SITE (bi));

					if (jump_to_tab == NULL) jump_to_tab = tab;
				}
			}

			if (jump_to && jump_to_tab != NULL)
			{
				galeon_window_jump_to_tab (w, jump_to_tab);
			}
		}
	}
	else
	{
		g_warning ("don't know what to do...");
	}

	g_free (smarted_url);
}

static void
galeon_window_bookmark_activated_cb (GObject *sender,
				     GbBookmarkEventActivated *ev,
				     GaleonWindow *w)
{
	galeon_window_bookmark_activate (w, ev);
}


void
galeon_window_show_page_info (GaleonWindow *window, PageInfoDialogPage page)
{
	GaleonDialog *dialog = page_info_dialog_new(GTK_WIDGET(window));
	page_info_dialog_set_current_page (PAGE_INFO_DIALOG (dialog), page);
	galeon_dialog_show(dialog);
}

void
galeon_window_show_find (GaleonWindow *window)
{			       
	GaleonDialog *dialog;
	GaleonEmbed *embed;

	if (!window->priv->find_dialog)
	{
		embed = galeon_window_get_active_embed (window);
		g_return_if_fail (GTK_IS_WINDOW(window));

		dialog = find_dialog_new_with_parent (GTK_WIDGET(window),
						      embed);
		window->priv->find_dialog = dialog;

		g_object_add_weak_pointer(G_OBJECT (dialog),
					  (gpointer *) &window->priv->find_dialog);
	}
	galeon_dialog_show (window->priv->find_dialog);
}

void
galeon_window_show_history (GaleonWindow *window)
{
	GaleonEmbed *embed;

	embed = galeon_window_get_active_embed (window);
	g_return_if_fail (embed != NULL);

	window->priv->history_dialog = history_dialog_new_with_parent 
						(GTK_WIDGET(window),
			 		     	 embed,
						 FALSE);
	g_object_add_weak_pointer 
                        (G_OBJECT(window->priv->history_dialog),
                         (gpointer)&window->priv->history_dialog);

	galeon_dialog_show (window->priv->history_dialog);
}

static char *
galeon_window_gb_location_source_get_location (GbLocationSource *src)
{
	GaleonWindow *window;
	GaleonTab *tab;
	const gchar *location;

	window = GALEON_WINDOW (src);
	g_return_val_if_fail (window, NULL);

	tab = galeon_window_get_active_tab (window);
	g_return_val_if_fail (tab, NULL);

	location = galeon_tab_get_location (tab);
	if (!location) location = "";

	return g_strdup (location);
}

static char *
galeon_window_gb_location_source_get_title (GbLocationSource *src)
{
	GaleonWindow *window;
	GaleonTab *tab;
	const gchar *title;

	window = GALEON_WINDOW (src);
	g_return_val_if_fail (window, NULL);

	tab = galeon_window_get_active_tab (window);
	g_return_val_if_fail (tab, NULL);

	title = galeon_tab_get_title (tab);
	if (!title) 
	{
		return galeon_window_gb_location_source_get_location (src);
	}

	return g_strdup (title);
}

void
galeon_window_set_zoom (GaleonWindow *window, 
			gint zoom)
{
	GaleonEmbed *embed;

        g_return_if_fail (IS_GALEON_WINDOW (window));
        
	embed = galeon_window_get_active_embed (window);
        g_return_if_fail (embed != NULL);
	
        galeon_embed_zoom_set (embed, zoom, TRUE);
}

EggEditableToolbar *
galeon_window_get_toolbar (GaleonWindow *window)
{
	return window->priv->egg_toolbar;
}

/**
 * Adds / updates an item to the window recent history menu 
 */
void
galeon_window_site_visited (GaleonWindow *window, const gchar *url, const gchar *title)
{
	g_return_if_fail (IS_GALEON_WINDOW (window));

	/* ignore about:blank, it's not shown in any other history either */
	if (!url || !strcmp (url, "about:blank")) return;

	galeon_window_recent_history_visited (window->priv->recent_history, url, title);
}

/**
 *  Clear the recent history menu
 */
void
galeon_window_clear_history (GaleonWindow *window)
{
	GList *tabs, *item;

	g_return_if_fail (IS_GALEON_WINDOW (window));

	galeon_window_recent_history_clear (window->priv->recent_history);

	tabs = galeon_window_get_tabs (window);
	for (item = tabs ; item ; item = item->next)
	{
		GaleonTab *tab = GALEON_TAB (item->data);
		GaleonEmbed *embed = galeon_tab_get_embed (tab);

		galeon_embed_shistory_clear (embed);
	}
	g_list_free (tabs);

	/* FIXME: We need to sort this out - crispin (the actions aren't in the 
	 * main action group)
	 *
	 * galeon_action_update (GALEON_ACTION (ACTION_ITEM(GO_BACK_ACTION)));
	 * galeon_action_update (GALEON_ACTION (ACTION_ITEM(GO_FORWARD_ACTION)));
	 */
}


/**
 *  Little helper structure that we use while iterating through the
 *  dropped urls
 */
typedef struct {
	gboolean first_url;
	GaleonTab * tab;
	GaleonWindow * window;
} UrlReceiveContext;


static void
each_url_receive_data_binder (const char * url, const char * title, 
			      gpointer data )
{
	UrlReceiveContext * context = (UrlReceiveContext*)data;

	if (context->first_url && context->tab)
	{
		GaleonEmbed *embed = galeon_tab_get_embed (context->tab);
		/**
		 * The first url is special: if the drag was to an
		 * existing tab, load it there
		 */
		galeon_embed_load_url (embed, url);
	}
	else
	{
		context->tab =
			galeon_shell_new_tab (galeon_shell, context->window,
					      context->tab, url,
					      GALEON_NEW_TAB_IN_EXISTING_WINDOW |
					      GALEON_NEW_TAB_APPEND);
	}
	context->first_url = FALSE;
}


static void
galeon_window_tab_drag_data_received_cb(GtkWidget *widget,
					GdkDragContext *dc,
					gint x, gint y,
					GtkSelectionData *selection_data,
					guint info,
					guint t,
					GtkWidget * child)
{
	UrlReceiveContext context;
	GtkWidget * toplevel;
	context.first_url = TRUE;
	context.tab = GALEON_TAB (child);

	toplevel = gtk_widget_get_toplevel (widget);
	g_return_if_fail (IS_GALEON_WINDOW (toplevel));
	
	context.window = GALEON_WINDOW(toplevel);

	galeon_dnd_drag_data_receive (widget, dc, x, y, selection_data,
			 info, t, &context, each_url_receive_data_binder);
}


static void		
galeon_window_tab_added_cb  (GulNotebook *notebook, GtkWidget *child, GaleonWindow *window)
{
	GtkWidget * label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (notebook), child);

	galeon_dnd_url_drag_dest_set (label);

	g_signal_connect (G_OBJECT(label), "drag_data_received",
			  G_CALLBACK(galeon_window_tab_drag_data_received_cb),
			  child);

	update_tabs_menu_sensitivity (window);
}


static void		
galeon_window_tab_removed_cb (GulNotebook *notebook, GtkWidget *child, GaleonWindow *window)
{
	update_spinner_control (window);

	update_tabs_menu_sensitivity (window);
}


static void
galeon_window_tabs_reordered_cb (GulNotebook *notebook, GaleonWindow *window)
{
	update_tabs_menu_sensitivity (window);
}

static gboolean
galeon_window_tab_delete_cb (GulNotebook *notebook, GtkWidget *child, GaleonWindow *window)
{
	GaleonEmbed *embed;

	g_return_val_if_fail (IS_GALEON_TAB (child), FALSE);
	embed = galeon_tab_get_embed (GALEON_TAB (child));

	if (galeon_embed_has_modified_forms (GALEON_EMBED (embed)) == G_OK)
	{
		return !confirm_close_with_modified_forms (window, GALEON_TAB (child));
	}

	return FALSE;
}


static void
galeon_window_tab_detached_cb (GulNotebook *notebook, gint page, 
			        gint x, gint y, GaleonWindow *window)
{
	GaleonWindow *new_win;
	GaleonTab *tab;

	tab = get_tab_from_page_num (GTK_NOTEBOOK (notebook), page);
	new_win = galeon_window_new ();

	galeon_window_reparent_tab (new_win, window, tab);

	gtk_widget_show (GTK_WIDGET (new_win));
}

void
galeon_window_reparent_tab (GaleonWindow *window, GaleonWindow *source,
		            GaleonTab *tab)
{
	gul_notebook_move_page (GUL_NOTEBOOK (source->priv->notebook),
				GUL_NOTEBOOK (window->priv->notebook),
				GTK_WIDGET (tab), -1);
	galeon_tab_set_window (tab, window);
}

void
galeon_window_set_tab_status (GaleonWindow	*window,
		              GaleonTab		*tab,
			      TabLoadStatus	 status)
{
	GdkColor *color;
	GtkWidget *icon = galeon_tab_get_icon(tab);
	gboolean have_ref = FALSE;

	switch (status)
	{
	case TAB_LOAD_STARTED:
		color = &_galeon_window_loading_tab_color;

		/* Don't display the loading animation if favicons in tabs are
		 * disabled. If they are disabled, then the icon retreived above
		 * will be empty, so won't get displayed */
		if (eel_gconf_get_integer (CONF_TABS_FAVICON))
		{
			icon = gtk_image_new_from_animation (_galeon_window_loading_animation);
			gtk_widget_show (icon);
			g_object_ref (G_OBJECT (icon));
			gtk_object_sink (GTK_OBJECT (icon));
			have_ref = TRUE;
		}

        	break;
	case TAB_LOAD_COMPLETED:
		color = &_galeon_window_new_tab_color;
		break;
	case TAB_LOAD_NONE:
	default:
		color = NULL;
		break;
	}

	gul_notebook_set_page_icon( GUL_NOTEBOOK (window->priv->notebook),
				    GTK_WIDGET (tab),
				    icon );

	gul_notebook_set_page_color (GUL_NOTEBOOK (window->priv->notebook),
			             GTK_WIDGET (tab),
				     color);
	
	if (have_ref)
	{
		g_object_unref (G_OBJECT(icon));
	}
}

void
galeon_window_set_tab_title (GaleonWindow	*window,
		             GaleonTab		*tab,
			     const char 	*title)
{
	gul_notebook_set_page_title (GUL_NOTEBOOK (window->priv->notebook),
				     GTK_WIDGET (tab),
				     title);

	if (galeon_window_get_active_tab (window) == tab)
	{
		galeon_window_update_control (window, TitleControl);
	}
}
