/*
 * Pidgin TooBars Plugin
 *
 * Copyright 2009-2010 VaYurik <vayurik@mail.ru> (original code)
 *
 * 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 of the License, 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
 */

/* При допиливании убедительная просьба сохранить форматирование исходного кода в текущем стиле */
/* Please, save formatting of code if you want to saw this source */

#ifdef HAVE_CONFIG_H
#include "../toobars_config.h"
#endif

#ifndef PURPLE_PLUGINS
#define PURPLE_PLUGINS
#endif

#include "internal.h"

#include "core.h"
#include "glib.h"
#include "gtkblist.h"
#include "gtkaccount.h"
#include "gtkstatusbox.h"
#include "gtksavedstatuses.h"
#include "gtkplugin.h"
#include "gtkpluginpref.h"
#include "gtkprefs.h"
#include "gtkutils.h"
#include "pidginstock.h"
#include "request.h"
#include "version.h"
#include "debug.h"
#include "gdk/gdkkeysyms.h"

#if (GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION == 6)
#define GTK_STOCK_INFO                  GTK_STOCK_DIALOG_INFO
#endif

#define PLUGIN_ID												"gtk-toobars"
#define PLUGIN_VERSION									"1.14"

#define PLUGIN_NAME											_("Toolbar'n'Statusbar")
#define PLUGIN_SUMMARY									_("Adds toolbar and statusbar to buddy list.")
#define PLUGIN_DESCRIPTION							_("Adds toolbar to buddy list with buttons: add a new contact, settings of display a buddy list, enable or disable sound notifications and quick access to program settings and user accounts.\nCreates a statusbar that displays the active accounts, and allows you to change the status and the mood of each of the accounts from the menu.\nAllows you to hide the main menu.\nAdds a context menu to empty space of buddy list.")
#define PLUGIN_AUTHOR										"VaYurik <vayurik@mail.ru>"
#define PLUGIN_MAIL											"vayurik@mail.ru"
#define PLUGIN_WEBSITE									"http://vayurik.ru/wordpress/toobars"
#define PLUGIN_TRANSLATORS							"\tRussian:\t<a href=\"mailto:vayurik@mail.ru\">VaYurik</a>\n\tSpanish:\t<a href=\"mailto:acidrums4@gmail.com\">Acidrums4</a>\n\tGerman:\t<a href=\"mailto:Mario_Siegmann@web.de\">Siggi0904 and Dirtsa</a>\n\tCzech:\t<a href=\"mailto:lukas@francalek.cz\">Lukas Francalek</a>\n\tFrench:\t<a href=\"mailto:louis.scheidt@free.fr\">Louis SCHEIDT</a>\n\tPolish:\t<a href=\"mailto:krystian.maksymowicz@gmail.com\">Krystian Maksymowicz</a>"
#define PLUGIN_AD												_("Do not forget to visit the <a href=\"http://avremont.ru\">site</a> and click there on the banner. It a moment for you, but hosting for the author.")

#define IS_DEBUGGING 										FALSE // Режим отображения названий функций в окне отладки

#define TOOBARS_ICON_TOKEN_STATUS				"tb_token.png"

static struct
{
	gchar *filename;
	gchar *id;
} TooBars_stock [] =
	{
		{"tb_add.png", "TOOBARS_STOCK_ADD_BUDDY"},
		{"tb_online.png", "TOOBARS_STOCK_SHOW_ONLINE"},
		{"tb_offline.png", "TOOBARS_STOCK_SHOW_OFFLINE"},
		{"tb_list.png", "TOOBARS_STOCK_SHOW_LIST"},
		{"tb_details.png", "TOOBARS_STOCK_SHOW_DETAILS"},
		{"tb_mute.png", "TOOBARS_STOCK_MUTE_SOUND"},
		{"tb_sound.png", "TOOBARS_STOCK_ENABLED_SOUND"},
		{"tb_options.png", "TOOBARS_STOCK_OPTIONS"},
		{"tb_accounts.png", "TOOBARS_STOCK_ACCOUNTS"}
	};

struct _TooBars_interface
{
	GtkWidget *MainMenu_widget;
	GtkWidget *ToolBar_widget;
	GtkWidget *StatusBar_widget;

	GtkToolItem *AddBuddy_btn;
	GtkToolItem *ShowOffline_tgl;
	GtkToolItem *ShowDetails_tgl;
	GtkToolItem *MuteSound_tgl;

	PurpleAccount *LastAccount;
	gchar *LastAccount_tt;

	GList *StatusBoxes_glist;

	GtkWidget *AddBuddy_item;
	GtkWidget *ShowMainMenu_item;
	GtkWidget *ShowToolbar_item;
	GtkWidget *ShowStatusbar_item;
} TooBars_interface;

/********************* Функции связанные с главным меню *********************/
// Функции показывающие и скрывающие главное меню
static void ShowMainMenu (void); //
static void HideMainMenu (void); //
static void DrawMainMenu (void); //
static void DrawMainMenu_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
// Функции отвечающие за отображение главного меню при нажатии кнопок мыши или клавиш
static gboolean KeyPress_cb (GtkWidget *widget, GdkEventKey *event, gpointer data); //
static gboolean ButtonPress_cb (GtkWidget *widget, GdkEventButton *event, gpointer data); //
static gboolean FocusOut_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data); //

/********************* Функции связанные с панелью инструментов *********************/
// Функции создающие, выводящие, перевыводящие и уничтожающие панель инструментов
static void CreateToolBar (PidginBuddyList *gtkblist); //
static void DrawToolBar (PidginBuddyList *gtkblist); //
static void RemoveToolBar (PidginBuddyList *gtkblist); //
static void ReDrawToolBar (void); //
static void ReDrawToolBar_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
// Функции отвечающие за отображение и состояние кнопок панели инструментов
static void DrawAddBuddyIcon (void); //
static void DrawToolbarToggleIcon (GtkToolItem *toggle, gboolean flag, gchar *label, gchar *tooltip_on, gchar *tooltip_off, gchar *icon_on, gchar *icon_off); //
static void AddBuddy_cb (GtkButton *widget, gpointer data); //
static void ShowOffline_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
static void SetShowOfflineIcon (void); //
static void SyncOffline_cb (GtkCheckMenuItem *MenuItem, gpointer data); //
static void ShowDetails_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
static void SetShowDetailsIcon (void); //
static void SyncDetails_cb (GtkCheckMenuItem *MenuItem, gpointer data); //
static void MuteSound_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
static void SetMuteSoundIcon (gconstpointer value); //
static void SyncMuteSound_cb (GtkCheckMenuItem *MenuItem, gpointer data); //
static void CheckSound_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //

/********************* Функции отвечающие за контекстные меню *********************/
// Функции отвечающая за вывод разных контекстных меню
static gboolean DrawContextMenu_cb (GtkWidget *widget, GdkEvent *event); //
// Функции отвечающие за контекстное меню панели инструментов
static GtkWidget *CreateToolbarMenu (void); //
static void ReDrawToolbarMenu (void); //
static void CheckToolbarMenuItem_cb (GtkWidget *widget, gpointer data); //
// Функции отвечающие за контекстное меню окна списка контактов
static void CreateBListMenu (PidginBuddyList *gtkblist); //

/********************* Функции связанные со статусной строкой *********************/
// Функции создающие, выводящие, перевыводящие и уничтожающие статусную строку
static void CreateStatusBar (PidginBuddyList *gtkblist); //
static void DrawStatusBar (PidginBuddyList *gtkblist); //
static void RemoveStatusBar (PidginBuddyList *gtkblist); //
static void ReDrawStatusBar (void); //
static void ReDrawStatusBar_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
// Функции отвечающие за создание, вывод и состояние кнопок учётных записей
static GtkWidget *CreateSmallButton (GtkWidget *toggle); //
static GdkPixbuf *GetProtocolStatusIcon (GdkPixbuf *ProtocolEmblem, PurpleStatusPrimitive StatusPrim, PidginBuddyList *gtkblist); //
static gboolean QueryTooltip_cb (GtkWidget *widget, gint x, gint y, gboolean kbdtip, GtkTooltip *tooltip, gpointer data); //
static char *FormatTooltip (const char *property, const char *value); //
static void ResetLastAccount (void); //
static void UnToggle_cb (GtkMenuShell *menu, gpointer data); //
// Функции связанные с созданием меню статусов
static void ShowCustomStatusEditor_cb (GtkMenuItem *menuitem, gpointer data); //
static void ShowCustomSubStatusEditor_cb (GtkMenuItem *menuitem, gpointer data); //
static void ApplyCustomSubStatus_cb (GtkWidget *widget, gpointer data); //
static void ActivateStatusPrim_cb (GtkMenuItem *menuitem, gpointer data); //
static void ActivateSavedStatus_cb (GtkMenuItem *menuitem, gpointer data); //
static void ActivateAccountStatus_cb (GtkMenuItem *menuitem, gpointer data); //
static GtkWidget *NewMenuItemWithMoodIcon (GtkWidget *menu, const gchar *label, GCallback cb, gpointer data); //
static GtkWidget *NewMenuItemWithStatusIcon (GtkWidget *menu, const gchar *label, PurpleStatusPrimitive StatusPrim, GCallback cb, gpointer data); //
static PurpleSavedStatus *CreateTransientStatus (PurpleStatusPrimitive StatusPrim, PurpleStatusType *StatusType); //
static void AddAccountStatuses (GtkWidget *menu, PurpleAccount *account); //
static void StatusMenuPosition (GtkMenu *menu, gint *x, gint *y, gboolean *push, gpointer data); //
static gboolean IsHaveMood (PurpleAccount *account); //
static char *GetMoodInfo (PurpleAccount *account, gint flag); //
static GtkWidget *CreateStatusMenu (PidginBuddyList *gtkblist, PurpleAccount *account); //
static void DrawStatusMenu_cb (GtkWidget *widget, gpointer data); //
// Функции связанные с создание StatusBox'ов
static void CreateStatusBoxes (void); //
static void RemoveStatusBoxes (void); //
static void CreateStatusBox (PurpleAccount *account); //
static void RemoveStatusBox (PurpleAccount *account); //
static void ShowStatusBox (PidginBuddyList *gtkblist, PurpleAccount *account); //
static void HideStatusBoxes (PidginBuddyList *gtkblist); //
static void DrawStatusBoxes_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data); //
// Функции вызываемые при возникновении событий, связанных с учётными записями
static void AccountEnabled_cb (PurpleAccount *account, gpointer data); //
static void AccountDisabled_cb (PurpleAccount *account, gpointer data); //
static void AccountError_cb (PurpleAccount *account, const PurpleConnectionErrorInfo *old, const PurpleConnectionErrorInfo *new); //
static void AccountSign_cb (PurpleConnection *gc); //
static void ModifyAccount_cb (GtkWidget *widget, gpointer data); //
static void DisableAccount_cb (GtkCheckMenuItem *widget, gpointer data); //
// Функции вызываемые при возникновении событий, связанных со статусами учётных записей
static void AccountStatusChanged_cb (PurpleAccount *account, PurpleStatus *old, PurpleStatus *new); //
static void SavedStatusChanged_cb (PurpleSavedStatus *now, PurpleSavedStatus *old, gpointer data); //
static void SavedStatusUpdated_cb (PurpleSavedStatus *status, gpointer data); //
// Функции отвечающие за иконку непрочитанных сообщений
static void CreateUnreadIconMenu (void); //
static gboolean UnreadIconClick_cb (GtkWidget *widget, GdkEventButton *event); //
static void ConvUpdate_cb (PurpleConversation *conv, PurpleConvUpdateType type, PidginBuddyList *gtkblist); //
static void ConvDelete_cb (PurpleConversation *conv, PidginBuddyList *gtkblist); //

/********************* Прочие функции *********************/
// Функция создания всех панелей
static void CreateAllBox (PurpleBuddyList *blist); //
// Функция получения полного пути к файлу картинки
static char *GetIconFilename (const gchar *name); //
// Функция регистрации набора картинок
static void RegisterStockIcons (void); //
// Функция выводящая отладочные сообщения при установке переменной IsDebbuging
static void Debugging (const gchar *str); //

/********************* Настройки плагина *********************/
// Функции создающие окно настроек плагина
static GtkWidget *CreatePrefFrame (PurplePlugin *plugin); //
static void CreatePrefDialog_cb (GtkWidget *widget, gpointer data); //
static void ToggleSizeBtn_cb (GtkWidget *widget, gpointer data); //
static void StyleSelected_cb (GtkWidget *widget, gpointer data); //
static void SizeSelected_cb (GtkWidget *widget, gpointer data); //
static GtkWidget *CreatePrefBtn (GtkWidget *PrefGroup_vbox, GtkWidget *Group_tgl, gboolean active, gchar *PrefName, gchar *pref); //
static GtkWidget *CreateSubPrefBtn (GtkWidget *PrefGroup_vbox, GtkWidget *Group_tgl, GtkWidget *SubGroup_tgl, gchar *PrefName, gchar *pref); //
static void SwitchPrefPage_cb (GtkNotebook *Pref_nb, GtkNotebookPage *page, guint num, gpointer data); //
static void TogglePrefBtn_cb (GtkWidget *widget, gpointer data); //
static void ToggleSubGroupBtn_cb (GtkWidget *widget, gpointer data); //
static void SensChangeSubGroupBtn_cb (GtkWidget *widget, GtkStateType state, gpointer data); //
static void ToggleGroupBtn_cb (GtkWidget *widget, gpointer data); //

/********************* Загрузка, выгрузка и инициация плагина *********************/
static gboolean PluginLoad (PurplePlugin *plugin); //
static gboolean PluginUnload (PurplePlugin *plugin); //
static void InitPlugin (PurplePlugin *plugin); //

/*****************************************************************************************************************/

static void Debugging (const gchar *str)
{
	if (IS_DEBUGGING) purple_debug_info (PLUGIN_ID, "%s\n", str);
}

static char *GetIconFilename (const gchar *name)
{
	gchar *filename;
	Debugging ("GetIconFilename");
	filename = g_build_filename (purple_user_dir (), "pixmaps", "pidgin", "buttons", name, NULL);
	if (!g_file_test (filename, G_FILE_TEST_EXISTS))
	{
		g_free (filename);
		filename = g_build_filename (DATADIR, "pixmaps", "pidgin", "buttons", name, NULL);
	}
	return filename;
}

static gboolean KeyPress_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("KeyPress_cb");
	if ((event->keyval == GDK_F10) ||
		(purple_prefs_get_bool ("/plugins/gtk/toobars/mainmenu/use_alt_key") && ((event->keyval == GDK_Alt_L) || (event->keyval == GDK_Alt_R))) ||
		(purple_prefs_get_bool ("/plugins/gtk/toobars/mainmenu/use_ctrl_key") && ((event->keyval == GDK_Control_L) || (event->keyval == GDK_Control_R))))
		{
			gtk_widget_show (TB->MainMenu_widget);
		}
	else if (event->state & GDK_CONTROL_MASK)
		{
			PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
 /* Код ниже нужен для обхода "пропадания" горячих клавиш при отключении главного меню */
 			if (gtkblist)
			{
				gtk_widget_show (TB->MainMenu_widget);
				if (gtk_accel_groups_activate (G_OBJECT (gtkblist->window), event->keyval, event->state))
				{
					gtk_widget_hide (TB->MainMenu_widget);
					return TRUE;
				}
/* Конец кода для обхода "пропадания" горячих клавиш */
			}
			gtk_widget_hide (TB->MainMenu_widget);
		}
	else if ((!(event->state & GDK_MOD1_MASK)) &&
		((event->keyval != GDK_Alt_L) && (event->keyval != GDK_Alt_R)))
		{
			gtk_widget_hide (TB->MainMenu_widget);
		}
	return FALSE;
}

static gboolean ButtonPress_cb (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("ButtonPress_cb");
	gtk_widget_hide (TB->MainMenu_widget);
	return FALSE;
}

static gboolean FocusOut_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("FocusOut_cb");
	gtk_widget_hide (TB->MainMenu_widget);
	return FALSE;
}

static void ShowMainMenu (void)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("ShowMainMenu");
	if (!gtkblist) return;
	gtk_widget_show (TB->MainMenu_widget);
	g_signal_handlers_disconnect_matched (G_OBJECT (gtkblist->window), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (KeyPress_cb), NULL);
	g_signal_handlers_disconnect_matched (G_OBJECT (gtkblist->treeview), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (ButtonPress_cb), NULL);
	g_signal_handlers_disconnect_matched (G_OBJECT (gtkblist->vbox), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (ButtonPress_cb), NULL);
	g_signal_handlers_disconnect_matched (G_OBJECT (gtkblist->treeview), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (FocusOut_cb), NULL);
}

static void HideMainMenu (void)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("HideMainMenu");
	if (!gtkblist) return;
	gtk_widget_hide (TB->MainMenu_widget);
	g_signal_connect (G_OBJECT (gtkblist->window), "key-press-event", G_CALLBACK (KeyPress_cb), NULL);
	g_signal_connect (G_OBJECT (gtkblist->treeview), "button-press-event", G_CALLBACK (ButtonPress_cb), NULL);
	g_signal_connect (G_OBJECT (gtkblist->vbox), "button-press-event", G_CALLBACK (ButtonPress_cb), NULL);
	g_signal_connect (G_OBJECT (gtkblist->treeview), "focus-out-event", G_CALLBACK (FocusOut_cb), NULL);
}

static void DrawMainMenu (void)
{
	Debugging ("DrawMainMenu");
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/mainmenu/show_mainmenu")) ShowMainMenu ();
	else HideMainMenu ();
}

static void DrawMainMenu_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	Debugging ("DrawMainMenu_cb");
	ReDrawToolbarMenu ();
	DrawMainMenu ();
}

static void DrawToolbarToggleIcon (GtkToolItem *toggle, gboolean flag, gchar *label, gchar *tooltip_on, gchar *tooltip_off, gchar *icon_on, gchar *icon_off)
{
	GtkWidget *img;
	Debugging ("DrawToolbarToggleIcon");
	if (flag)
	{
		img = gtk_image_new_from_stock (icon_on, GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toggle), img);
		gtk_tool_item_set_tooltip_text (toggle, _(tooltip_on));
	}
	else
	{
		img = gtk_image_new_from_stock (icon_off, GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toggle), img);
		gtk_tool_item_set_tooltip_text (toggle, _(tooltip_off));
	}
	gtk_tool_button_set_label  (GTK_TOOL_BUTTON (toggle), _(label));
	gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toggle), flag);
	gtk_widget_show_all (GTK_WIDGET (toggle));
}

static void DrawAddBuddyIcon (void)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	Debugging ("DrawAddBuddyIcon");
	flag = (purple_connections_get_all () != NULL);
	gtk_widget_set_sensitive (GTK_WIDGET (TB->AddBuddy_item), flag);
	if ((purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_add_btn")) && (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_toolbar")))
	{
		gtk_widget_set_sensitive (GTK_WIDGET (TB->AddBuddy_btn), flag);
		if (flag) gtk_tool_item_set_tooltip_text (TB->AddBuddy_btn, _("Add Buddy to your Buddy List"));
		else gtk_tool_item_set_tooltip_text (TB->AddBuddy_btn, _("Service unavailable"));
	}
}

static void AddBuddy_cb (GtkButton *widget, gpointer data)
{
	Debugging ("AddBuddy_cb");
	purple_blist_request_add_buddy (NULL, NULL, NULL, NULL);
}

static void SetShowOfflineIcon (void)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	Debugging ("SetShowOfflineIcon");
	flag = purple_prefs_get_bool (PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
	DrawToolbarToggleIcon (TB->ShowOffline_tgl, flag, "Buddies", "Show Offline Buddies", "Show Online Buddies", "TOOBARS_STOCK_SHOW_OFFLINE", "TOOBARS_STOCK_SHOW_ONLINE");
}

static void ShowOffline_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	gboolean flag;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("ShowOffline_cb");
	if (!gtkblist) return;
	flag = purple_prefs_get_bool (PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
	purple_prefs_set_bool (PIDGIN_PREFS_ROOT "/blist/show_offline_buddies", !flag);
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies"))), !flag);
	SetShowOfflineIcon ();
}

static void SyncOffline_cb (GtkCheckMenuItem *MenuItem, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	Debugging ("SyncOffline_cb");
	flag = gtk_check_menu_item_get_active (MenuItem);
	DrawToolbarToggleIcon (TB->ShowOffline_tgl, flag, "Buddies", "Show Offline Buddies", "Show Online Buddies", "TOOBARS_STOCK_SHOW_OFFLINE", "TOOBARS_STOCK_SHOW_ONLINE");
}

static void SetShowDetailsIcon (void)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	Debugging ("SetShowDetailsIcon");
	flag = purple_prefs_get_bool (PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
	DrawToolbarToggleIcon (TB->ShowDetails_tgl, flag, "View", "Show Buddy Details", "Show Buddy List", "TOOBARS_STOCK_SHOW_DETAILS", "TOOBARS_STOCK_SHOW_LIST");
}

static void ShowDetails_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	gboolean flag;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("ShowDetails_cb");
	if (!gtkblist) return;
	flag = purple_prefs_get_bool (PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
	purple_prefs_set_bool (PIDGIN_PREFS_ROOT "/blist/show_buddy_icons", !flag);
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details"))), !flag);
	SetShowDetailsIcon ();
}

static void SyncDetails_cb (GtkCheckMenuItem *MenuItem, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	Debugging ("SyncDetails_cb");
	flag = gtk_check_menu_item_get_active (MenuItem);
	DrawToolbarToggleIcon (TB->ShowDetails_tgl, flag, "View", "Show Buddy Details", "Show Buddy List", "TOOBARS_STOCK_SHOW_DETAILS", "TOOBARS_STOCK_SHOW_LIST");
}

static void MuteSound_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("MuteSound_cb");
	if (!gtkblist) return;
	flag = purple_prefs_get_bool (PIDGIN_PREFS_ROOT "/sound/mute");
	purple_prefs_set_bool (PIDGIN_PREFS_ROOT "/sound/mute", !flag);
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds"))), !flag);
	SetMuteSoundIcon (TB->MuteSound_tgl);
}

static void SetMuteSoundIcon (gconstpointer value)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	GtkWidget *img;
	gboolean flag;
	Debugging ("SetMuteSoundIcon");
	if (strcmp (value, "none"))
	{
		gtk_widget_set_sensitive (GTK_WIDGET (TB->MuteSound_tgl), TRUE);
		flag = purple_prefs_get_bool (PIDGIN_PREFS_ROOT "/sound/mute");
		DrawToolbarToggleIcon (TB->MuteSound_tgl, flag, "Sounds", "No sounds", "Enable Sounds", "TOOBARS_STOCK_MUTE_SOUND", "TOOBARS_STOCK_ENABLED_SOUND");
	}
	else
	{
		gtk_widget_set_sensitive (GTK_WIDGET (TB->MuteSound_tgl), FALSE);
		gtk_tool_item_set_tooltip_text (TB->MuteSound_tgl, _("Service unavailable"));
		img = gtk_image_new_from_stock ("TOOBARS_STOCK_MUTE_SOUND", GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (TB->MuteSound_tgl), img);
		gtk_widget_show_all (GTK_WIDGET (TB->MuteSound_tgl));
	}
}

static void SyncMuteSound_cb (GtkCheckMenuItem *MenuItem, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	gboolean flag;
	Debugging ("SyncMuteSound_cb");
	flag = gtk_check_menu_item_get_active (MenuItem);
	DrawToolbarToggleIcon (TB->MuteSound_tgl, flag, "Sounds", "No sounds", "Enable Sounds", "TOOBARS_STOCK_MUTE_SOUND", "TOOBARS_STOCK_ENABLED_SOUND");
}

static void CheckSound_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	Debugging ("CheckSound_cb");
	SetMuteSoundIcon (value);
}

static void CreatePrefDialog_cb (GtkWidget *widget, gpointer data)
{
	static GtkWidget *Pref_dlg = NULL;
	GtkWidget *PrefMain_vbox, *Close_btn;
	Debugging ("CreatePrefDialog_cb");
	if (Pref_dlg)
	{
		gtk_window_present (GTK_WINDOW (Pref_dlg));
		return;
	}
	Pref_dlg = pidgin_create_dialog (PLUGIN_NAME, 0, NULL, FALSE);
	PrefMain_vbox = pidgin_dialog_get_vbox_with_properties (GTK_DIALOG (Pref_dlg), FALSE, 0);
	gtk_box_pack_start (GTK_BOX (PrefMain_vbox), CreatePrefFrame (NULL), FALSE, FALSE, 0);
	Close_btn = pidgin_dialog_add_button (GTK_DIALOG (Pref_dlg), GTK_STOCK_CLOSE, NULL, NULL);
	g_signal_connect_swapped (G_OBJECT (Close_btn), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (Pref_dlg));
	gtk_widget_show (Pref_dlg);
	gtk_window_present (GTK_WINDOW (Pref_dlg));
	g_signal_connect (G_OBJECT (Pref_dlg), "destroy", G_CALLBACK (gtk_widget_destroyed), &Pref_dlg);
}

static gboolean DrawContextMenu_cb (GtkWidget *widget, GdkEvent *event)
{
	GtkMenu *menu;
	GdkEventButton *EventButton;
	Debugging ("DrawContextMenu_cb");
	g_return_val_if_fail (widget != NULL, FALSE);
	g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	menu = GTK_MENU (widget);
	if (event->type == GDK_BUTTON_PRESS)
	{
		EventButton = (GdkEventButton *) event;
		if (EventButton->button == 3)
		{
			DrawAddBuddyIcon ();
			gtk_menu_popup (menu, NULL, NULL, NULL, NULL, EventButton->button, EventButton->time);
			return TRUE;
		}
	}
	return FALSE;
}

static void CheckToolbarMenuItem_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("CheckToolbarMenuItem_cb");
	purple_prefs_set_bool ((gchar *) data, gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)));
}

static GtkWidget *CreateToolbarMenu (void)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GtkWidget *Toolbar_menu;

	Debugging ("CreateToolbarMenu");
	Toolbar_menu = gtk_menu_new ();
	TB->ShowMainMenu_item = gtk_check_menu_item_new_with_mnemonic (_("Show main m_enu"));
	gtk_menu_shell_append (GTK_MENU_SHELL (Toolbar_menu), TB->ShowMainMenu_item);
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (TB->ShowMainMenu_item), purple_prefs_get_bool ("/plugins/gtk/toobars/mainmenu/show_mainmenu"));
	g_signal_connect (G_OBJECT (TB->ShowMainMenu_item), "toggled", G_CALLBACK (CheckToolbarMenuItem_cb), "/plugins/gtk/toobars/mainmenu/show_mainmenu");

	TB->ShowToolbar_item = gtk_check_menu_item_new_with_mnemonic (_("Show _toolbar"));
	gtk_menu_shell_append (GTK_MENU_SHELL (Toolbar_menu), TB->ShowToolbar_item);
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (TB->ShowToolbar_item), purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_toolbar"));
	g_signal_connect (G_OBJECT (TB->ShowToolbar_item), "toggled", G_CALLBACK (CheckToolbarMenuItem_cb), "/plugins/gtk/toobars/toolbar/show_toolbar");

	TB->ShowStatusbar_item = gtk_check_menu_item_new_with_mnemonic (_("Show _statusbar"));
	gtk_menu_shell_append (GTK_MENU_SHELL (Toolbar_menu), TB->ShowStatusbar_item);
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (TB->ShowStatusbar_item), purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_statusbar"));
	g_signal_connect (G_OBJECT (TB->ShowStatusbar_item), "toggled", G_CALLBACK (CheckToolbarMenuItem_cb), "/plugins/gtk/toobars/statusbar/show_statusbar");

	pidgin_separator (Toolbar_menu);
	pidgin_new_item_from_stock (Toolbar_menu, _("_Configure Plugin"), GTK_STOCK_PROPERTIES, G_CALLBACK (CreatePrefDialog_cb), NULL, 0, 0, NULL);
	gtk_widget_show_all (Toolbar_menu);
	return Toolbar_menu;
}

static void CreateToolBar (PidginBuddyList *gtkblist)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	GtkWidget *ToolBar_tbar, *Toolbar_menu;
	GtkToolItem *Sep, *Space, *Button;

	Debugging ("CreateToolBar");
	TB->ToolBar_widget = gtk_vbox_new (FALSE, 0);
	gtk_box_pack_start (GTK_BOX (gtkblist->vbox), TB->ToolBar_widget, FALSE, FALSE, 0);
	gtk_box_reorder_child (GTK_BOX (gtkblist->vbox), TB->ToolBar_widget, 0);

	ToolBar_tbar = gtk_toolbar_new ();
	gtk_toolbar_set_orientation (GTK_TOOLBAR (ToolBar_tbar), GTK_ORIENTATION_HORIZONTAL);
	if (purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style") != 3) gtk_toolbar_set_style (GTK_TOOLBAR (ToolBar_tbar), purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style"));
	else gtk_toolbar_unset_style (GTK_TOOLBAR (ToolBar_tbar));
	if (purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_size") == 2) gtk_toolbar_unset_icon_size (GTK_TOOLBAR (ToolBar_tbar));
	else gtk_toolbar_set_icon_size (GTK_TOOLBAR (ToolBar_tbar), purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_size") + 2);
	gtk_box_pack_start (GTK_BOX (TB->ToolBar_widget), ToolBar_tbar, FALSE, FALSE, 0);
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_add_btn"))
	{
		TB->AddBuddy_btn = gtk_tool_button_new_from_stock ("TOOBARS_STOCK_ADD_BUDDY");
		gtk_tool_button_set_label (GTK_TOOL_BUTTON (TB->AddBuddy_btn), _("Add Buddy"));
		DrawAddBuddyIcon ();
		gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), TB->AddBuddy_btn, -1);
		g_signal_connect (G_OBJECT (TB->AddBuddy_btn), "clicked", G_CALLBACK (AddBuddy_cb), NULL);
		GTK_WIDGET_UNSET_FLAGS (TB->AddBuddy_btn, GTK_CAN_DEFAULT);
		if ((purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_offline_btn")) ||
			(purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_details_btn")) ||
			(purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_mute_btn")))
		{
			Sep = gtk_separator_tool_item_new ();
			gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), Sep, -1);
		}
	}

	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_offline_btn"))
	{
		TB->ShowOffline_tgl = gtk_toggle_tool_button_new ();
		SetShowOfflineIcon ();
		gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), TB->ShowOffline_tgl, -1);
		g_signal_connect (G_OBJECT (TB->ShowOffline_tgl), "toggled", G_CALLBACK (ShowOffline_cb), NULL);
		g_signal_connect (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies")))), "toggled", G_CALLBACK (SyncOffline_cb), NULL);
		GTK_WIDGET_UNSET_FLAGS (TB->ShowOffline_tgl, GTK_CAN_DEFAULT);
	}
	else
		g_signal_handlers_disconnect_matched (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies")))), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (SyncOffline_cb), NULL);

	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_details_btn"))
	{
		TB->ShowDetails_tgl = gtk_toggle_tool_button_new ();
		SetShowDetailsIcon ();
		gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), TB->ShowDetails_tgl, -1);
		g_signal_connect (G_OBJECT (TB->ShowDetails_tgl), "toggled", G_CALLBACK (ShowDetails_cb), NULL);
		g_signal_connect (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details")))), "toggled", G_CALLBACK (SyncDetails_cb), NULL);
		GTK_WIDGET_UNSET_FLAGS (TB->ShowDetails_tgl, GTK_CAN_DEFAULT);
	}
	else
		g_signal_handlers_disconnect_matched (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Buddy Details")))), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (SyncDetails_cb), NULL);

	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_mute_btn"))
	{
		if ((purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_offline_btn")) ||
			(purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_details_btn")))
		{
			Sep = gtk_separator_tool_item_new ();
			gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), Sep, -1);
		}
		TB->MuteSound_tgl = gtk_toggle_tool_button_new ();
		SetMuteSoundIcon (TB->MuteSound_tgl);
		gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), TB->MuteSound_tgl, -1);
		g_signal_connect (G_OBJECT (TB->MuteSound_tgl), "toggled", G_CALLBACK (MuteSound_cb), NULL);
		gtk_widget_set_sensitive (GTK_WIDGET (TB->MuteSound_tgl), strcmp (purple_prefs_get_string (PIDGIN_PREFS_ROOT "/sound/method"), "none"));
		purple_prefs_connect_callback (pidgin_blist_get_handle (), PIDGIN_PREFS_ROOT "/sound/method", CheckSound_cb, NULL);
		g_signal_connect (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds")))), "toggled", G_CALLBACK (SyncMuteSound_cb), NULL);
		GTK_WIDGET_UNSET_FLAGS (TB->MuteSound_tgl, GTK_CAN_DEFAULT);
	}
	else
		g_signal_handlers_disconnect_matched (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds")))), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (SyncMuteSound_cb), NULL);

	Space = gtk_tool_item_new ();
	gtk_tool_item_set_expand (Space, TRUE);
	gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), Space, -1);

	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_pref_btn"))
	{
		Button = gtk_tool_button_new_from_stock ("TOOBARS_STOCK_OPTIONS");
		gtk_tool_button_set_label (GTK_TOOL_BUTTON (Button), _("Preferences"));
		gtk_tool_item_set_tooltip_text (Button, _("Preferences"));
		gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), Button, -1);
		g_signal_connect (G_OBJECT (Button), "clicked", G_CALLBACK (pidgin_prefs_show), NULL);
		GTK_WIDGET_UNSET_FLAGS (Button, GTK_CAN_DEFAULT);
	}

	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_accounts_btn"))
	{
		Button = gtk_tool_button_new_from_stock ("TOOBARS_STOCK_ACCOUNTS");
		gtk_tool_button_set_label (GTK_TOOL_BUTTON (Button), _("Accounts"));
		gtk_tool_item_set_tooltip_text (Button, _("Manage Accounts"));
		gtk_toolbar_insert (GTK_TOOLBAR (ToolBar_tbar), Button, -1);
		g_signal_connect (G_OBJECT (Button), "clicked", G_CALLBACK (pidgin_accounts_window_show), NULL);
		GTK_WIDGET_UNSET_FLAGS (Button, GTK_CAN_DEFAULT);
	}
	gtk_toolbar_set_show_arrow (GTK_TOOLBAR (ToolBar_tbar), TRUE);
	gtk_widget_show_all (ToolBar_tbar);
	gtk_widget_show (TB->ToolBar_widget);
	Toolbar_menu = CreateToolbarMenu ();
	g_signal_connect_swapped (G_OBJECT (TB->ToolBar_widget), "button-press-event", G_CALLBACK (DrawContextMenu_cb), Toolbar_menu);
}

static void RemoveToolBar (PidginBuddyList *gtkblist)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("RemoveToolBar");
	if (TB->ToolBar_widget != NULL)
	{
		gtk_widget_destroy (TB->ToolBar_widget);
		TB->ToolBar_widget = NULL;
	}
}

static void DrawToolBar (PidginBuddyList *gtkblist)
{
	Debugging ("DrawToolBar");
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_toolbar")) CreateToolBar (gtkblist);
}

static void ReDrawToolBar (void)
{
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("ReDrawToolBar");
	if (!gtkblist) return;
	RemoveToolBar (gtkblist);
	DrawToolBar (gtkblist);
}

static void ReDrawToolBar_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	Debugging ("ReDrawToolBar_cb");
	ReDrawToolbarMenu ();
	ReDrawToolBar ();
	DrawMainMenu ();
}

/*****************************************************************************************************************/

static void ResetLastAccount (void)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("ResetLastAccount");
	if (TB->LastAccount_tt != NULL)
	{
		g_free (TB->LastAccount_tt);
		TB->LastAccount_tt = NULL;
	}
}

static void UnToggle_cb (GtkMenuShell *menu, gpointer data)
{
	Debugging ("UnToggle_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void StatusMenuPosition (GtkMenu *menu, gint *x, gint *y, gboolean *push, gpointer data)
{
	GtkRequisition req;
	gint xpos, ypos;
	GtkWidget *widget = GTK_WIDGET (data);
	Debugging ("StatusMenuPosition");
	gdk_window_get_origin (widget->window, &xpos, &ypos);
	xpos += widget->allocation.x;
	ypos += widget->allocation.y;
	gtk_widget_size_request (GTK_WIDGET (menu), &req);
	if (ypos > gdk_screen_get_height (gtk_widget_get_screen (widget)) / 2) ypos -= req.height;
	else ypos += widget->allocation.height;
	*x = xpos;
	*y = ypos;
	*push = TRUE;
}

static void ShowCustomStatusEditor_cb (GtkMenuItem *menuitem, gpointer data)
{
	PurpleSavedStatus *SavedStatus = purple_savedstatus_get_current ();
	Debugging ("ShowCustomStatusEditor_cb");
	if (purple_savedstatus_get_type (SavedStatus) == PURPLE_STATUS_AVAILABLE) SavedStatus = purple_savedstatus_new (NULL, PURPLE_STATUS_AVAILABLE);
	pidgin_status_editor_show (FALSE, purple_savedstatus_is_transient (SavedStatus) ? SavedStatus : NULL);
}

static void ApplyCustomSubStatus_cb (GtkWidget *widget, gpointer data)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	const gchar *message = NULL;
	Debugging ("ApplyCustomSubStatus_cb");
	if (data) message = gtk_entry_get_text ((GtkEntry *) data);
	if (TB->LastAccount != NULL)
	{
		const char *id = NULL;
		PurpleStatus *AccountStatus = purple_account_get_active_status (TB->LastAccount);
		PurpleStatusType *StatusType = purple_status_get_type (AccountStatus);
		id = purple_status_type_get_id (StatusType);
		if (message) purple_account_set_status (TB->LastAccount, id, TRUE, "message", message, NULL);
		else purple_account_set_status (TB->LastAccount, id, TRUE, NULL);
	}
	else purple_savedstatus_set_message (purple_savedstatus_get_current (), message);
	ReDrawStatusBar ();
}

static void ShowCustomSubStatusEditor_cb (GtkMenuItem *menuitem, gpointer data)
{
	static GtkWidget *NewMessage_dlg = NULL;
	GtkWidget *NewMessage_vbox, *Apply_btn, *Clear_btn, *Cancel_btn;
	GtkWidget *entry, *label;
	gchar *UserName, *message;
	PurpleAccount *Account = (PurpleAccount *) data;

	Debugging ("ShowCustomSubStatusEditor_cb");
	if (NewMessage_dlg) gtk_widget_destroy (NewMessage_dlg);
	if (Account == NULL) UserName = PIDGIN_NAME;
	else UserName = (gchar *) purple_account_get_username (Account);
	NewMessage_dlg = pidgin_create_dialog (UserName, 0, NULL, FALSE);
	NewMessage_vbox = pidgin_dialog_get_vbox_with_properties (GTK_DIALOG (NewMessage_dlg), FALSE, 0);
	label = gtk_label_new (_("Enter new message:"));
	gtk_box_pack_start (GTK_BOX (NewMessage_vbox), label, FALSE, FALSE, 0);
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
	entry = gtk_entry_new ();
	if (Account != NULL) message = (gchar *) purple_status_get_attr_string (purple_account_get_active_status (Account), "message");
	else message = (gchar *) purple_savedstatus_get_message (purple_savedstatus_get_current ());
	if (message != NULL) gtk_entry_set_text (GTK_ENTRY (entry), message);
	gtk_box_pack_start (GTK_BOX (NewMessage_vbox), entry, FALSE, FALSE, 0);
	Cancel_btn = pidgin_dialog_add_button (GTK_DIALOG (NewMessage_dlg), GTK_STOCK_CANCEL, NULL, NULL);
	g_signal_connect_swapped (G_OBJECT (Cancel_btn), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (NewMessage_dlg));
	Clear_btn = pidgin_dialog_add_button (GTK_DIALOG (NewMessage_dlg), GTK_STOCK_CLEAR, NULL, NULL);
	g_signal_connect (G_OBJECT (Clear_btn), "clicked", G_CALLBACK (ApplyCustomSubStatus_cb), NULL);
	g_signal_connect_swapped (G_OBJECT (Clear_btn), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (NewMessage_dlg));
	Apply_btn = pidgin_dialog_add_button (GTK_DIALOG (NewMessage_dlg), GTK_STOCK_APPLY, NULL, NULL);
	g_signal_connect (G_OBJECT (Apply_btn), "clicked", G_CALLBACK (ApplyCustomSubStatus_cb), entry);
	g_signal_connect_swapped (G_OBJECT (Apply_btn), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (NewMessage_dlg));
	g_signal_connect (G_OBJECT (NewMessage_dlg), "destroy", G_CALLBACK (gtk_widget_destroyed), &NewMessage_dlg);
	GTK_WIDGET_SET_FLAGS (Apply_btn, GTK_CAN_DEFAULT);
	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
	gtk_widget_grab_default (Apply_btn);
	gtk_widget_show_all (NewMessage_dlg);
	gtk_window_present (GTK_WINDOW (NewMessage_dlg));
}

#if (PURPLE_MAJOR_VERSION >= 2 && PURPLE_MINOR_VERSION >= 7)
/*
   ========================================================================
   Следующий код взят без изменений из файла gtkblist.c,
   т.к. описания нужных функций в файле заголовков отсутствуют,
   однако очевидно, что этот код будет переписываться разработчиками Pidgin
   ========================================================================
*/

static char *get_mood_icon_path(const char *mood)
{
	char *path;

	if (!strcmp(mood, "busy")) {
		path = g_build_filename(DATADIR, "pixmaps", "pidgin",
		                        "status", "16", "busy.png", NULL);
	} else if (!strcmp(mood, "hiptop")) {
		path = g_build_filename(DATADIR, "pixmaps", "pidgin",
		                        "emblems", "16", "hiptop.png", NULL);
	} else {
		char *filename = g_strdup_printf("%s.png", mood);
		path = g_build_filename(DATADIR, "pixmaps", "pidgin",
		                        "emotes", "small", filename, NULL);
		g_free(filename);
	}
	return path;
}

static void
update_status_with_mood(PurpleAccount *account, const gchar *mood,
    const gchar *text)
{
	if (mood && *mood) {
		if (text) {
			purple_account_set_status(account, "mood", TRUE,
			                          PURPLE_MOOD_NAME, mood,
				    				  PURPLE_MOOD_COMMENT, text,
			                          NULL);
		} else {
			purple_account_set_status(account, "mood", TRUE,
			                          PURPLE_MOOD_NAME, mood,
			                          NULL);
		}
	} else {
		purple_account_set_status(account, "mood", FALSE, NULL);
	}
}

static void
edit_mood_cb(PurpleConnection *gc, PurpleRequestFields *fields)
{
	PurpleRequestField *mood_field;
	GList *l;

	mood_field = purple_request_fields_get_field(fields, "mood");
	l = purple_request_field_list_get_selected(mood_field);

	if (l) {
		const char *mood = purple_request_field_list_get_data(mood_field, l->data);

		if (gc) {
			const char *text;
			PurpleAccount *account = purple_connection_get_account(gc);

			if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES) {
				PurpleRequestField *text_field;
				text_field = purple_request_fields_get_field(fields, "text");
				text = purple_request_field_string_get_value(text_field);
			} else {
				text = NULL;
			}

			update_status_with_mood(account, mood, text);
		} else {
			GList *accounts = purple_accounts_get_all_active();

			for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) {
				PurpleAccount *account = (PurpleAccount *) accounts->data;
				PurpleConnection *gc = purple_account_get_connection(account);

				if (gc && gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
					update_status_with_mood(account, mood, NULL);
				}
			}
		}
	}
}

static void
global_moods_for_each(gpointer key, gpointer value, gpointer user_data)
{
	GList **out_moods = (GList **) user_data;
	PurpleMood *mood = (PurpleMood *) value;

	*out_moods = g_list_append(*out_moods, mood);
}

static PurpleMood *
get_global_moods(void)
{
	GHashTable *global_moods =
		g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
	GHashTable *mood_counts =
		g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
	GList *accounts = purple_accounts_get_all_active();
	PurpleMood *result = NULL;
	GList *out_moods = NULL;
	int i = 0;
	int num_accounts = 0;

	for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) {
		PurpleAccount *account = (PurpleAccount *) accounts->data;
		if (purple_account_is_connected(account)) {
			PurpleConnection *gc = purple_account_get_connection(account);

			if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) {
				PurplePluginProtocolInfo *prpl_info =
					PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
				PurpleMood *mood = NULL;

				/* PURPLE_CONNECTION_SUPPORT_MOODS would not be set if the prpl doesn't
				 * have get_moods, so using PURPLE_PROTOCOL_PLUGIN_HAS_FUNC isn't necessary
				 * here */
				for (mood = prpl_info->get_moods(account) ;
				    mood->mood != NULL ; mood++) {
					int mood_count =
							GPOINTER_TO_INT(g_hash_table_lookup(mood_counts, mood->mood));

					if (!g_hash_table_lookup(global_moods, mood->mood)) {
						g_hash_table_insert(global_moods, (gpointer)mood->mood, mood);
					}
					g_hash_table_insert(mood_counts, (gpointer)mood->mood,
					    GINT_TO_POINTER(mood_count + 1));
				}

				num_accounts++;
			}
		}
	}

	g_hash_table_foreach(global_moods, global_moods_for_each, &out_moods);
	result = g_new0(PurpleMood, g_hash_table_size(global_moods) + 1);

	while (out_moods) {
		PurpleMood *mood = (PurpleMood *) out_moods->data;
		int in_num_accounts =
			GPOINTER_TO_INT(g_hash_table_lookup(mood_counts, mood->mood));

		if (in_num_accounts == num_accounts) {
			/* mood is present in all accounts supporting moods */
			result[i].mood = mood->mood;
			result[i].description = mood->description;
			i++;
		}
		out_moods = g_list_delete_link(out_moods, out_moods);
	}

	g_hash_table_destroy(global_moods);
	g_hash_table_destroy(mood_counts);

	return result;
}

/* get current set mood for all mood-supporting accounts, or NULL if not set
 or not set to the same on all */
static const gchar *
get_global_mood_status(void)
{
	GList *accounts = purple_accounts_get_all_active();
	const gchar *found_mood = NULL;

	for (; accounts ; accounts = g_list_delete_link(accounts, accounts)) {
		PurpleAccount *account = (PurpleAccount *) accounts->data;

		if (purple_account_is_connected(account) &&
		    (purple_account_get_connection(account)->flags &
		     PURPLE_CONNECTION_SUPPORT_MOODS)) {
			PurplePresence *presence = purple_account_get_presence(account);
			PurpleStatus *status = purple_presence_get_status(presence, "mood");
			const gchar *curr_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);

			if (found_mood != NULL && !purple_strequal(curr_mood, found_mood)) {
				/* found a different mood */
				found_mood = NULL;
				break;
			} else {
				found_mood = curr_mood;
			}
		}
	}

	return found_mood;
}

static void
set_mood_cb(GtkWidget *widget, PurpleAccount *account)
{
	const char *current_mood;
	PurpleRequestFields *fields;
	PurpleRequestFieldGroup *g;
	PurpleRequestField *f;
	PurpleConnection *gc = NULL;
	PurplePluginProtocolInfo *prpl_info = NULL;
	PurpleMood *mood;
	PurpleMood *global_moods = get_global_moods();

	if (account) {
		PurplePresence *presence = purple_account_get_presence(account);
		PurpleStatus *status = purple_presence_get_status(presence, "mood");
		gc = purple_account_get_connection(account);
		g_return_if_fail(gc->prpl != NULL);
		prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
		current_mood = purple_status_get_attr_string(status, PURPLE_MOOD_NAME);
	} else {
		current_mood = get_global_mood_status();
	}

	fields = purple_request_fields_new();
	g = purple_request_field_group_new(NULL);
	f = purple_request_field_list_new("mood", _("Please select your mood from the list"));

	purple_request_field_list_add(f, _("None"), "");
	if (current_mood == NULL)
		purple_request_field_list_add_selected(f, _("None"));

	/* TODO: rlaager wants this sorted. */
	/* The connection is checked for PURPLE_CONNECTION_SUPPORT_MOODS flag before
	 * this function is called for a non-null account. So using
	 * PURPLE_PROTOCOL_PLUGIN_HAS_FUNC isn't necessary here */
	for (mood = account ? prpl_info->get_moods(account) : global_moods;
	     mood->mood != NULL ; mood++) {
		char *path;

		if (mood->mood == NULL || mood->description == NULL)
			continue;

		path = get_mood_icon_path(mood->mood);
		purple_request_field_list_add_icon(f, _(mood->description),
				path, (gpointer)mood->mood);
		g_free(path);

		if (current_mood && !strcmp(current_mood, mood->mood))
			purple_request_field_list_add_selected(f, _(mood->description));
	}
	purple_request_field_group_add_field(g, f);

	purple_request_fields_add_group(fields, g);

	/* if the connection allows setting a mood message */
	if (gc && (gc->flags & PURPLE_CONNECTION_SUPPORT_MOOD_MESSAGES)) {
		g = purple_request_field_group_new(NULL);
		f = purple_request_field_string_new("text",
		    _("Message (optional)"), NULL, FALSE);
		purple_request_field_group_add_field(g, f);
		purple_request_fields_add_group(fields, g);
	}

	purple_request_fields(gc, _("Edit User Mood"), _("Edit User Mood"),
                              NULL, fields,
                              _("OK"), G_CALLBACK(edit_mood_cb),
                              _("Cancel"), NULL,
                              gc ? purple_connection_get_account(gc) : NULL,
                              NULL, NULL, gc);

	g_free(global_moods);
}

/*
   ========================================================================
   Конец заимствованного кода
   ========================================================================
*/

static gboolean IsHaveMood (PurpleAccount *account)
{
	Debugging ("IsHaveMood");
	if (account)
	{
		if (purple_account_is_connected (account))
		{
			PurpleConnection *gc = purple_account_get_connection (account);
			if (gc->flags & PURPLE_CONNECTION_SUPPORT_MOODS) return TRUE;
			else return FALSE;
		}
		else return FALSE;
	}
	return TRUE;
}

static char *GetMoodInfo (PurpleAccount *account, gint flag) // flag: 0 - name; 1 - description
{
	PurplePluginProtocolInfo *PurpleInfo = NULL;
	PurpleConnection *gc = NULL;
	const char *CurrentMood;
	const PurpleMood *mood;
	PurpleMood *GlobalMoods = get_global_moods ();

	Debugging ("GetMoodInfo");
	if (!IsHaveMood (account)) return NULL;
	if (account)
	{
		PurpleStatus *status = purple_presence_get_status (purple_account_get_presence (account), "mood");
		if (!status) return NULL;
		gc = purple_account_get_connection (account);
		if (gc->prpl == NULL) return NULL;
		PurpleInfo = PURPLE_PLUGIN_PROTOCOL_INFO (gc->prpl);
		CurrentMood = purple_status_get_attr_string (status, PURPLE_MOOD_NAME);
	}
	else
		CurrentMood = get_global_mood_status ();
	for (mood = account ? PurpleInfo->get_moods (account) : GlobalMoods; mood->mood != NULL ; mood++)
	{
		if (CurrentMood && !strcmp (CurrentMood, mood->mood))
		{
			if ((flag == 0) || (mood->description == NULL)) return g_strdup_printf (("%s"), mood->mood);
			else if (flag == 1) return g_strdup_printf (("%s"), mood->description);
		}
	}
	return NULL;
}
#endif

static PurpleSavedStatus *CreateTransientStatus (PurpleStatusPrimitive StatusPrim, PurpleStatusType *StatusType)
{
	PurpleSavedStatus *SavedStatus = purple_savedstatus_new (NULL, StatusPrim);
	Debugging ("CreateTransientStatus");
	if (StatusType != NULL)
	{
		GList *tmp, *ActiveAccounts = purple_accounts_get_all_active ();
		for (tmp = ActiveAccounts; tmp != NULL; tmp = tmp->next)
			purple_savedstatus_set_substatus (SavedStatus, (PurpleAccount*) tmp->data, StatusType, NULL);
		g_list_free (ActiveAccounts);
	}
	return SavedStatus;
}

static void ActivateStatusPrim_cb (GtkMenuItem *menuitem, gpointer data)
{
	PurpleStatusPrimitive StatusPrim;
	PurpleSavedStatus *SavedStatus;
	Debugging ("ActivateStatusPrim_cb");
	StatusPrim = GPOINTER_TO_INT (data);
	SavedStatus = purple_savedstatus_find_transient_by_type_and_message (StatusPrim, NULL);
	if (SavedStatus == NULL) SavedStatus = CreateTransientStatus (StatusPrim, NULL);
	purple_savedstatus_activate (SavedStatus);
}

static void ActivateSavedStatus_cb (GtkMenuItem *menuitem, gpointer data)
{
	time_t CreationTime;
	PurpleSavedStatus *SavedStatus;
	Debugging ("ActivateSavedStatus_cb");
	CreationTime = GPOINTER_TO_INT (data);
	SavedStatus = purple_savedstatus_find_by_creation_time (CreationTime);
	if (SavedStatus != NULL) purple_savedstatus_activate (SavedStatus);
}

#if (PURPLE_MAJOR_VERSION >= 2 && PURPLE_MINOR_VERSION >= 7)
static GtkWidget *NewMenuItemWithMoodIcon (GtkWidget *menu, const gchar *label, GCallback cb, gpointer data)
{
	GtkWidget *MenuItem;
	GtkWidget *img;
	gchar *MoodName;
	PurpleAccount *Account = (PurpleAccount *) data;

	Debugging ("NewMenuItemWithMoodIcon");
	MenuItem = gtk_image_menu_item_new_with_label (label);
	if (menu) gtk_menu_shell_append (GTK_MENU_SHELL (menu), MenuItem);
	if (cb) g_signal_connect (G_OBJECT (MenuItem), "activate", cb, data);
	MoodName = GetMoodInfo (Account, 0);
	if (MoodName)
	{
		gchar *filename;
		filename = get_mood_icon_path (MoodName);
		if ((filename) && (g_file_test (filename, G_FILE_TEST_EXISTS)))
		{
			img = gtk_image_new_from_file (filename);
			gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (MenuItem), img);
		}
	}
	gtk_widget_show_all (MenuItem);
	return MenuItem;
}
#endif

static GtkWidget *NewMenuItemWithStatusIcon (GtkWidget *menu, const gchar *label, PurpleStatusPrimitive StatusPrim, GCallback cb, gpointer data)
{
	GtkWidget *MenuItem;
	GdkPixbuf *pixbuf;
	GtkWidget *img;
	Debugging ("NewMenuItemWithStatusIcon");
	MenuItem = gtk_image_menu_item_new_with_label (label);
	if (menu) gtk_menu_shell_append (GTK_MENU_SHELL (menu), MenuItem);
	if (cb) g_signal_connect (G_OBJECT (MenuItem), "activate", cb, data);
	pixbuf = pidgin_create_status_icon (StatusPrim, menu, PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL);
	img = gtk_image_new_from_pixbuf (pixbuf);
	g_object_unref (pixbuf);
	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (MenuItem), img);
	gtk_widget_show_all (MenuItem);
	return MenuItem;
}

static void ActivateAccountStatus_cb (GtkMenuItem *menuitem, gpointer data)
{
	struct _TooBars_interface *TB = &TooBars_interface;
	PurpleStatusType *StatusType;
	PurpleAccount *Account = NULL;
	PurpleStatusPrimitive StatusPrim;
	PurpleSavedStatus *SavedStatus = NULL;
	GList *iter = purple_savedstatuses_get_all ();

	Debugging ("ActivateAccountStatus_cb");
	StatusType = (PurpleStatusType *) data;
	StatusPrim = purple_status_type_get_primitive (StatusType);
	if (TB->LastAccount == NULL)
	{
		for (; iter != NULL; iter = iter->next)
		{
			PurpleSavedStatus *tmp = iter->data;
			if ((purple_savedstatus_get_type (tmp) == StatusPrim) && purple_savedstatus_is_transient (tmp) && purple_savedstatus_has_substatuses (tmp))
			{
				GList *AllAccounts = purple_accounts_get_all_active ();
				gboolean found = FALSE;
				while (AllAccounts != NULL)
				{
					PurpleSavedStatusSub *SavedSubStatus;
					Account = (PurpleAccount *) AllAccounts->data;
					SavedSubStatus = purple_savedstatus_get_substatus (tmp, Account);
					if (SavedSubStatus)
					{
						const PurpleStatusType *SubStatusType = purple_savedstatus_substatus_get_type (SavedSubStatus);
						const char *SubStatusTypeID = purple_status_type_get_id (SubStatusType);
						if (SubStatusTypeID && !strcmp (SubStatusTypeID, purple_status_type_get_id (StatusType))) found = TRUE;
					}
					AllAccounts = AllAccounts->next;
				}
				g_list_free (AllAccounts);
				if (!found) continue;
				SavedStatus = tmp;
				break;
			}
		}
		if (SavedStatus == NULL) SavedStatus = CreateTransientStatus (StatusPrim, StatusType);
		purple_savedstatus_activate (SavedStatus);
	}
	else
	{
		SavedStatus = purple_savedstatus_new (NULL, StatusPrim);
		purple_savedstatus_activate_for_account (SavedStatus, TB->LastAccount);
	}
}

static void AddAccountStatuses (GtkWidget *menu, PurpleAccount *Account)
{
	GList *l;
	Debugging ("AddAccountStatuses");
	for (l = purple_account_get_status_types (Account); l != NULL; l = l->next)
	{
		PurpleStatusPrimitive StatusPrim;
		gchar *StatusName;
		PurpleStatusType *StatusType = (PurpleStatusType *) l->data;
		if ((!purple_status_type_is_user_settable (StatusType)) || (purple_status_type_is_independent (StatusType))) continue;
		StatusPrim = purple_status_type_get_primitive (StatusType);
		StatusName = (gchar *) purple_status_type_get_name (StatusType);
		NewMenuItemWithStatusIcon (menu, StatusName, StatusPrim, G_CALLBACK (ActivateAccountStatus_cb), StatusType);
	}
}

static GtkWidget *CreateStatusMenu (PidginBuddyList *gtkblist, PurpleAccount *account)
{
	GtkWidget *StatusMenu;
	GList *PopularStatuses, *cur;
	PidginStatusBox *StatusBox = PIDGIN_STATUS_BOX (gtkblist->statusbox);

	Debugging ("CreateStatusMenu");
	StatusMenu = gtk_menu_new ();
#if (PURPLE_MAJOR_VERSION >= 2 && PURPLE_MINOR_VERSION >= 7)
	if (IsHaveMood (account) == TRUE)
	{
		NewMenuItemWithMoodIcon (StatusMenu, _("Set Mood..."), G_CALLBACK (set_mood_cb), account);
		pidgin_separator (StatusMenu);
	}
#endif
	if (StatusBox && account != NULL) AddAccountStatuses (StatusMenu, account);
	else
	{
		if (StatusBox && StatusBox->token_status_account != NULL)
			AddAccountStatuses (StatusMenu, StatusBox->token_status_account);
		else
		{
			NewMenuItemWithStatusIcon (StatusMenu, _("Available"), PURPLE_STATUS_AVAILABLE, G_CALLBACK (ActivateStatusPrim_cb), GINT_TO_POINTER (PURPLE_STATUS_AVAILABLE));
			NewMenuItemWithStatusIcon (StatusMenu, _("Away"), PURPLE_STATUS_AWAY, G_CALLBACK (ActivateStatusPrim_cb), GINT_TO_POINTER (PURPLE_STATUS_AWAY));
			NewMenuItemWithStatusIcon (StatusMenu, _("Do not disturb"), PURPLE_STATUS_UNAVAILABLE, G_CALLBACK (ActivateStatusPrim_cb), GINT_TO_POINTER (PURPLE_STATUS_UNAVAILABLE));
			NewMenuItemWithStatusIcon (StatusMenu, _("Invisible"), PURPLE_STATUS_INVISIBLE, G_CALLBACK (ActivateStatusPrim_cb), GINT_TO_POINTER (PURPLE_STATUS_INVISIBLE));
			NewMenuItemWithStatusIcon (StatusMenu, _("Offline"), PURPLE_STATUS_OFFLINE, G_CALLBACK (ActivateStatusPrim_cb), GINT_TO_POINTER (PURPLE_STATUS_OFFLINE));
		}
		PopularStatuses = purple_savedstatuses_get_popular (6);
		if (PopularStatuses != NULL) pidgin_separator (StatusMenu);
		for (cur = PopularStatuses; cur != NULL; cur = cur->next)
		{
			PurpleSavedStatus *SavedStatus = cur->data;
			time_t CreationTime = purple_savedstatus_get_creation_time (SavedStatus);
			NewMenuItemWithStatusIcon (StatusMenu, purple_savedstatus_get_title (SavedStatus), purple_savedstatus_get_type (SavedStatus), G_CALLBACK (ActivateSavedStatus_cb), GINT_TO_POINTER (CreationTime));
		}
		g_list_free (PopularStatuses);
		pidgin_separator(StatusMenu);
		pidgin_new_item_from_stock (StatusMenu, _("New status..."), GTK_STOCK_NEW, G_CALLBACK (ShowCustomStatusEditor_cb), NULL, 0, 0, NULL);
		pidgin_new_item_from_stock (StatusMenu, _("Saved statuses..."), GTK_STOCK_SAVE, G_CALLBACK (pidgin_status_window_show), NULL, 0, 0, NULL);
	}
	pidgin_separator(StatusMenu);
	pidgin_new_item_from_stock (StatusMenu, _("Status message..."), GTK_STOCK_EDIT, G_CALLBACK (ShowCustomSubStatusEditor_cb), account, 0, 0, NULL);
	gtk_widget_show_all (StatusMenu);
	return StatusMenu;
}

static void ShowStatusBox (PidginBuddyList *gtkblist, PurpleAccount *account)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("ShowStatusBox");
	if (account == NULL)
	{
		g_object_set (gtkblist->statusbox, "iconsel", purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_icon"), NULL);
		gtk_widget_show (gtkblist->statusbox);
	}
	else
	{
		GList *iter;
		for (iter = TB->StatusBoxes_glist; iter; iter = iter->next)
		{
			PidginStatusBox *sbox = iter->data;
			if (sbox->account == account)
			{
				g_object_set (sbox, "iconsel", purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_icon"), NULL);
				gtk_widget_show (GTK_WIDGET (sbox));
				break;
			}
		}
	}
}

static void HideStatusBoxes (PidginBuddyList *gtkblist)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GList *iter;
	Debugging ("HideStatusBoxes");
	gtk_widget_hide (gtkblist->statusbox);
	for (iter = TB->StatusBoxes_glist; iter; iter = iter->next) gtk_widget_hide (GTK_WIDGET (iter->data));
}

static void DrawStatusMenu_cb (GtkWidget *widget, gpointer data)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GtkWidget *StatusMenu;
	PurpleAccount *Account = (PurpleAccount *) data;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("DrawStatusMenu_cb");
	if (!gtkblist) return;
	if (g_strcmp0 (TB->LastAccount_tt, gtk_widget_get_tooltip_text (widget)) != 0)
	{
		TB->LastAccount = Account;
		TB->LastAccount_tt = gtk_widget_get_tooltip_text (widget);
		if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/use_statusbox"))
		{
			HideStatusBoxes (gtkblist);
			ReDrawStatusBar ();
			ShowStatusBox (gtkblist, Account);
		}
		else
		{
			StatusMenu = CreateStatusMenu (gtkblist, Account);
			gtk_menu_popup (GTK_MENU (StatusMenu), NULL, NULL, (GtkMenuPositionFunc) StatusMenuPosition, widget, 0, gtk_get_current_event_time ());
			g_signal_connect (G_OBJECT (StatusMenu), "deactivate", G_CALLBACK (UnToggle_cb), NULL);
		}
	}
	else
	{
		if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/use_statusbox"))
		{
			HideStatusBoxes (gtkblist);
			ResetLastAccount ();
			ReDrawStatusBar ();
		}
	}
}

static void ModifyAccount_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("ModifyAccount_cb");
	pidgin_account_dialog_show (PIDGIN_MODIFY_ACCOUNT_DIALOG, data);
}

static void DisableAccount_cb (GtkCheckMenuItem *widget, gpointer data)
{
	Debugging ("DisableAccount_cb");
	purple_account_set_enabled (data, PIDGIN_UI, FALSE);
}

static GdkPixbuf *GetProtocolStatusIcon (GdkPixbuf *ProtocolEmblem, PurpleStatusPrimitive StatusPrim, PidginBuddyList *gtkblist)
{
	const gchar *StatusStock = NULL;
	GdkPixbuf *StatusEmblem;
	GtkIconSize StatusEmblemSize = gtk_icon_size_from_name (PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC);
	Debugging ("GetProtocolStatusIcon");
	StatusStock = pidgin_stock_id_from_status_primitive (StatusPrim);
	StatusEmblem = gtk_widget_render_icon (GTK_WIDGET (PIDGIN_STATUS_BOX (gtkblist->statusbox)), StatusStock, StatusEmblemSize, "PidginStatusBox");
	gdk_pixbuf_composite (StatusEmblem, ProtocolEmblem, 5, 5, 11, 11, 5, 5, 1.0, 1.0, GDK_INTERP_BILINEAR, 196);
	g_object_unref (StatusEmblem);
	return ProtocolEmblem;
}

static GtkWidget *CreateSmallButton (GtkWidget *toggle)
{
	GtkRcStyle *rcstyle;
	Debugging ("CreateSmallButton");
	gtk_button_set_relief (GTK_BUTTON (toggle), GTK_RELIEF_NONE);
	GTK_WIDGET_UNSET_FLAGS (toggle, GTK_CAN_FOCUS);
	GTK_WIDGET_UNSET_FLAGS (toggle, GTK_CAN_DEFAULT);
	rcstyle = gtk_rc_style_new ();
	rcstyle->xthickness = 0;
	rcstyle->ythickness = 0;
	gtk_widget_modify_style (toggle, rcstyle);
	g_object_unref (rcstyle);
	return toggle;
}

static void CreateUnreadIconMenu (void)
{
	static GtkWidget *menu = NULL;
	GList *convs = NULL;
	GList *chats, *ims;
	Debugging ("CreateUnreadIconMenu");
	if (menu)
	{
		gtk_widget_destroy (menu);
		menu = NULL;
	}
	ims = pidgin_conversations_find_unseen_list (PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, FALSE, 0);
	chats = pidgin_conversations_find_unseen_list (PURPLE_CONV_TYPE_CHAT, PIDGIN_UNSEEN_NICK, FALSE, 0);
	if (ims && chats) convs = g_list_concat (ims, chats);
	else if (ims && !chats) convs = ims;
	else if(!ims && chats) convs = chats;
	if (!convs) return;
	menu = gtk_menu_new ();
	pidgin_conversations_fill_menu (menu, convs);
	g_list_free (convs);
	gtk_widget_show_all (menu);
	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time ());
}

static gboolean UnreadIconClick_cb (GtkWidget *widget, GdkEventButton *event)
{
	GList *convs;
	Debugging ("UnreadIconClick_cb");
	switch (event->button)
	{
		case 1:
			convs = pidgin_conversations_find_unseen_list (PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, FALSE, 1);
			if (!convs) convs = pidgin_conversations_find_unseen_list (PURPLE_CONV_TYPE_CHAT, PIDGIN_UNSEEN_NICK, FALSE, 1);
			if (convs)
			{
				pidgin_conv_present_conversation ((PurpleConversation *) convs->data);
				g_list_free (convs);
			}
			break;
		case 3:
			CreateUnreadIconMenu ();
			break;
	}
	return TRUE;
}

static void ConvUpdate_cb (PurpleConversation *conv, PurpleConvUpdateType type, PidginBuddyList *gtkblist)
{
	Debugging ("ConvUpdate_cb");
	if (type != PURPLE_CONV_UPDATE_UNSEEN) return;
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void ConvDelete_cb (PurpleConversation *conv, PidginBuddyList *gtkblist)
{
	Debugging ("ConvDelete_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void CreateStatusBoxes (void)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GList *iter, *AllAccounts;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("CreateStatusBoxes");
	if (!gtkblist) return;
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/use_statusbox"))
	{
		TB->StatusBoxes_glist = NULL;
		AllAccounts = purple_accounts_get_all_active ();
		for (iter = AllAccounts; iter; iter = iter->next) CreateStatusBox (iter->data);
		g_list_free (AllAccounts);
	}
}

static void RemoveStatusBoxes (void)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GList *iter, *AllAccounts;
	Debugging ("RemoveStatusBoxes");
	AllAccounts = purple_accounts_get_all_active ();
	for (iter = AllAccounts; iter; iter = iter->next) RemoveStatusBox (iter->data);
	g_list_free (AllAccounts);
	g_list_free (TB->StatusBoxes_glist);

}

static gboolean QueryTooltip_cb (GtkWidget *widget, gint x, gint y, gboolean kbdtip, GtkTooltip *tooltip, gpointer data)
{
	Debugging ("QueryTooltip_cb");
  gtk_tooltip_set_markup (tooltip, gtk_widget_get_tooltip_text (widget));
	gtk_tooltip_set_icon (tooltip, data);
  return TRUE;
}

static char *FormatTooltip (const char *property, const char *value)
{
	Debugging ("FormatTooltip");
	return g_strconcat ("\n<span size=\"smaller\"><b>", property, ":</b> ", value, "</span>", NULL);
}

static void CreateStatusBar (PidginBuddyList *gtkblist)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GtkWidget *StatusBar_sb, *StatusBar_hbox, *Status_hbox, *StatusName_widget, *ProtocolEmblem_widget;
	GtkWidget *AccountMenu;
	GtkStatusbar *StatusBar_sbar;
	PurpleAccount *Account;
	GdkPixbuf *ProtocolEmblem;
	PurpleStatusPrimitive StatusPrim;
	gchar *StatusName, *SubStatus;
	gint count = 0;
	gboolean IsShowAccountsStatusName, IsShowTokenStatusName, IsShowAccounts, IsShowToken;
	GtkWidget *child, *parent;

	Debugging ("CreateStatusBar");
	IsShowToken = purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_token");
	IsShowTokenStatusName = purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_token_statusname");
	IsShowAccounts = purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_accounts");
	IsShowAccountsStatusName = purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_accounts_statusname");

	TB->StatusBar_widget = gtk_vbox_new (FALSE, 0);
	gtk_box_pack_end (GTK_BOX (gtkblist->vbox), TB->StatusBar_widget, FALSE, FALSE, 0);

	StatusBar_sb = gtk_statusbar_new ();
	StatusBar_sbar = GTK_STATUSBAR (StatusBar_sb);
	gtk_statusbar_set_has_resize_grip (StatusBar_sbar, purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_resize_grip"));

#if GTK_CHECK_VERSION (2,19,1)
	child = gtk_statusbar_get_message_area (StatusBar_sbar);
#else
	child = StatusBar_sbar->label;
#endif
	parent = gtk_widget_get_parent (child);
	g_object_ref (child);
	gtk_container_remove (GTK_CONTAINER (parent), child);
	StatusBar_hbox = gtk_hbox_new (FALSE, 2);
	gtk_box_pack_start (GTK_BOX (StatusBar_hbox), child, FALSE, FALSE, 0);
	g_object_unref (child);
	gtk_container_add (GTK_CONTAINER (parent), StatusBar_hbox);
	gtk_widget_show (StatusBar_hbox);
	gtk_widget_set_size_request (StatusBar_hbox, -1, 17);

	if (IsShowToken)
	{
		GtkWidget *TokenStatus_tgl;
		gchar *TokenStatus_tt;
		PurpleSavedStatus *SavedStatus = purple_savedstatus_get_current ();
		PidginStatusBox *StatusBox = PIDGIN_STATUS_BOX (gtkblist->statusbox);
		if (StatusBox->token_status_account && purple_savedstatus_is_transient (SavedStatus))
		{
			PurpleStatus *TokenStatus = purple_account_get_active_status (StatusBox->token_status_account);
			StatusPrim = purple_status_type_get_primitive (purple_status_get_type (TokenStatus));
			StatusName = (gchar *) purple_status_get_name (TokenStatus);
		}
		else if (purple_savedstatus_is_transient (SavedStatus))
		{
			StatusPrim = purple_savedstatus_get_type (SavedStatus);
			StatusName = (gchar *) purple_primitive_get_name_from_type (StatusPrim);
		}
		else
		{
			StatusPrim = purple_savedstatus_get_type (SavedStatus);
			StatusName = (gchar *) purple_savedstatus_get_title (SavedStatus);
		}
		Status_hbox = gtk_hbox_new (FALSE, 0);
		gtk_box_pack_start (GTK_BOX (StatusBar_hbox), Status_hbox, FALSE, FALSE, 0);
		TokenStatus_tgl = CreateSmallButton (gtk_toggle_button_new ());
		gtk_box_pack_start (GTK_BOX (Status_hbox), TokenStatus_tgl, FALSE, FALSE, 2);

		AccountMenu = gtk_menu_new ();
		pidgin_new_item_from_stock (AccountMenu, _("_Accounts"), "TOOBARS_STOCK_ACCOUNTS", G_CALLBACK (pidgin_accounts_window_show), NULL, 0, 0, NULL);
		gtk_widget_show_all (AccountMenu);
		if (TokenStatus_tgl) g_signal_connect_swapped (G_OBJECT (TokenStatus_tgl), "button-press-event", G_CALLBACK (DrawContextMenu_cb), AccountMenu);

		SubStatus = (gchar *) purple_savedstatus_get_message (SavedStatus);
		ProtocolEmblem = gdk_pixbuf_new_from_file (GetIconFilename (TOOBARS_ICON_TOKEN_STATUS), NULL);
		if (!IsShowTokenStatusName) ProtocolEmblem = GetProtocolStatusIcon (ProtocolEmblem, StatusPrim, gtkblist);
		if (StatusPrim == PURPLE_STATUS_OFFLINE) gdk_pixbuf_saturate_and_pixelate (ProtocolEmblem, ProtocolEmblem, 0.0, FALSE);
		ProtocolEmblem_widget = gtk_image_new_from_pixbuf (ProtocolEmblem);
		gtk_widget_set_size_request (TokenStatus_tgl, 24, 17);
		gtk_container_add (GTK_CONTAINER (TokenStatus_tgl), ProtocolEmblem_widget);

		TokenStatus_tt = g_strdup_printf ("<b>%s</b>", PIDGIN_NAME);
		if (IsShowTokenStatusName)
		{
			StatusName_widget = gtk_label_new (StatusName);
			gtk_box_pack_start (GTK_BOX (Status_hbox), StatusName_widget, FALSE, FALSE, 0);
		}
		TokenStatus_tt = g_strconcat (TokenStatus_tt, FormatTooltip (_("Status"), StatusName), NULL);
		if (SubStatus != NULL) TokenStatus_tt = g_strconcat (TokenStatus_tt, FormatTooltip (_("Message"), SubStatus), NULL);
#if (PURPLE_MAJOR_VERSION >= 2 && PURPLE_MINOR_VERSION >= 7)
		{
			gchar *MoodName;
			MoodName = GetMoodInfo (NULL, 1);
			if (MoodName != NULL) TokenStatus_tt = g_strconcat (TokenStatus_tt, FormatTooltip (_("Mood"), _(MoodName)), NULL);
		}
#endif
		gtk_widget_set_tooltip_text (TokenStatus_tgl, TokenStatus_tt);
		g_signal_connect (G_OBJECT (TokenStatus_tgl), "query-tooltip", G_CALLBACK (QueryTooltip_cb), ProtocolEmblem);
		g_object_unref (ProtocolEmblem);
		if (g_strcmp0 (TB->LastAccount_tt, TokenStatus_tt) == 0) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (TokenStatus_tgl), TRUE);
		g_free (TokenStatus_tt);
		g_signal_connect (G_OBJECT (TokenStatus_tgl), "toggled", G_CALLBACK (DrawStatusMenu_cb), NULL);
		gtk_widget_show (Status_hbox);
	}
	if (IsShowAccounts)
	{
		gchar *AccountStatus_tt;
		GtkWidget *AccountStatus_tgl;
		GList *AllAccounts;
		AllAccounts = purple_accounts_get_all_active ();
		while (AllAccounts != NULL)
		{
			Account = (PurpleAccount *) AllAccounts->data;
			if (Account != NULL)
			{
				PurpleStatus *AccountStatus = purple_account_get_active_status (Account);
				if (AccountStatus != NULL)
				{
					PurpleStatusType *StatusType = purple_status_get_type (AccountStatus);
					Status_hbox = gtk_hbox_new (FALSE, 0);
					gtk_box_pack_start (GTK_BOX (StatusBar_hbox), Status_hbox, FALSE, FALSE, 0);
					if (((IsShowAccountsStatusName) && (count)) || ((IsShowToken) && (count == 0))) gtk_box_pack_start (GTK_BOX (Status_hbox), gtk_vseparator_new (), FALSE, FALSE, 2);
					count++;
					AccountStatus_tgl = CreateSmallButton (gtk_toggle_button_new ());
					StatusPrim = purple_status_type_get_primitive (StatusType);
					ProtocolEmblem = pidgin_create_prpl_icon (Account, PIDGIN_PRPL_ICON_SMALL);
					if (!IsShowAccountsStatusName) ProtocolEmblem = GetProtocolStatusIcon (ProtocolEmblem, StatusPrim, gtkblist);
					if (purple_account_is_disconnected (Account)) gdk_pixbuf_saturate_and_pixelate (ProtocolEmblem, ProtocolEmblem, 0.0, FALSE);
					ProtocolEmblem_widget = gtk_image_new_from_pixbuf (ProtocolEmblem);
					gtk_widget_set_size_request (AccountStatus_tgl, 24, 17);
					gtk_container_add (GTK_CONTAINER (AccountStatus_tgl), ProtocolEmblem_widget);
					gtk_box_pack_start (GTK_BOX (Status_hbox), AccountStatus_tgl, FALSE, FALSE, 2);

					AccountMenu = gtk_menu_new ();
					pidgin_new_item_from_stock (AccountMenu, _("_Edit Account"), GTK_STOCK_EDIT, G_CALLBACK (ModifyAccount_cb), Account, 0, 0, NULL);
					pidgin_new_item_from_stock (AccountMenu, _("_Disable Account"), GTK_STOCK_CLOSE, G_CALLBACK (DisableAccount_cb), Account, 0, 0, NULL);
					gtk_widget_show_all (AccountMenu);
					if (AccountStatus_tgl) g_signal_connect_swapped (G_OBJECT (AccountStatus_tgl), "button-press-event", G_CALLBACK (DrawContextMenu_cb), AccountMenu);

					StatusName = (gchar *) purple_status_type_get_name (StatusType);
					SubStatus = (gchar *) purple_status_get_attr_string (AccountStatus, "message");
					AccountStatus_tt = g_strdup_printf ("<b>%s</b>", (gchar *) purple_account_get_username (Account));

					if (IsShowAccountsStatusName)
					{
						StatusName_widget = gtk_label_new (StatusName);
						gtk_box_pack_start (GTK_BOX (Status_hbox), StatusName_widget, FALSE, FALSE, 0);
					}
					AccountStatus_tt = g_strconcat (AccountStatus_tt, FormatTooltip (_("Status"), StatusName), NULL);
					if (SubStatus != NULL) AccountStatus_tt = g_strconcat (AccountStatus_tt, FormatTooltip (_("Message"), SubStatus), NULL);
#if (PURPLE_MAJOR_VERSION >= 2 && PURPLE_MINOR_VERSION >= 7)
					{
						gchar *MoodName;
						MoodName = GetMoodInfo (Account, 1);
						if (MoodName != NULL) AccountStatus_tt = g_strconcat (AccountStatus_tt, FormatTooltip (_("Mood"), _(MoodName)), NULL);
					}
#endif
					gtk_widget_set_tooltip_text (AccountStatus_tgl, AccountStatus_tt);
					g_signal_connect (G_OBJECT (AccountStatus_tgl), "query-tooltip", G_CALLBACK (QueryTooltip_cb), ProtocolEmblem);
					g_object_unref (ProtocolEmblem);
					if (g_strcmp0 (TB->LastAccount_tt, AccountStatus_tt) == 0) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (AccountStatus_tgl), TRUE);
					g_free (AccountStatus_tt);
					g_signal_connect (G_OBJECT (AccountStatus_tgl), "toggled", G_CALLBACK (DrawStatusMenu_cb), Account);
					gtk_widget_show (Status_hbox);
				}
				AllAccounts = AllAccounts->next;
			}
		}
		g_list_free (AllAccounts);
	}
	gtk_box_pack_end (GTK_BOX (TB->StatusBar_widget), StatusBar_sb, FALSE, FALSE, 0);
	if ((purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_statusbar")) && (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_unread")))
	{
		GtkWidget *Unread_btn;
		GList *convs = NULL;
		GList *ims, *chats;
		GList *l = NULL;
		if (gtkblist->menutrayicon) gtk_widget_hide (gtkblist->menutrayicon);
		ims = pidgin_conversations_find_unseen_list (PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, FALSE, 0);
		chats = pidgin_conversations_find_unseen_list (PURPLE_CONV_TYPE_CHAT, PIDGIN_UNSEEN_NICK, FALSE, 0);
		if (ims && chats) convs = g_list_concat (ims, chats);
		else if (ims && !chats) convs = ims;
		else if (!ims && chats) convs = chats;
		if (convs)
		{
			GtkWidget *img = NULL;
			GString *tooltip = NULL;
			tooltip = g_string_new (NULL);
			l = convs;
			while (l != NULL)
			{
				gint count = 0;
				PidginConversation *gtkconv = PIDGIN_CONVERSATION ((PurpleConversation *) l->data);
				if (gtkconv)
					count = gtkconv->unseen_count;
				else if (purple_conversation_get_data (l->data, "unseen-count"))
					count = GPOINTER_TO_INT (purple_conversation_get_data (l->data, "unseen-count"));
				g_string_append_printf (tooltip, dngettext (GETTEXT_PACKAGE, "%d unread message from %s\n", "%d unread messages from %s\n", count), count, purple_conversation_get_title (l->data));
				l = l->next;
			}
			if (tooltip->len > 0)
			{
				g_string_truncate (tooltip, tooltip->len -1);
				img = gtk_image_new_from_stock (PIDGIN_STOCK_TOOLBAR_PENDING, gtk_icon_size_from_name (PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
				Unread_btn = CreateSmallButton (gtk_button_new ());
				gtk_container_add (GTK_CONTAINER (Unread_btn), img);
				gtk_widget_show (img);
				gtk_widget_show (Unread_btn);
				g_signal_connect (G_OBJECT (Unread_btn), "button-press-event", G_CALLBACK (UnreadIconClick_cb), NULL);
				gtk_widget_set_tooltip_text (Unread_btn, tooltip->str);
				gtk_box_pack_end (GTK_BOX (StatusBar_hbox), Unread_btn, FALSE, FALSE, 0);
			}
			g_string_free (tooltip, TRUE);
			g_list_free (convs);
		}
	}
	gtk_widget_show_all (TB->StatusBar_widget);
}

static void RemoveStatusBar (PidginBuddyList *gtkblist)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("RemoveStatusBar");
	if (TB->StatusBar_widget != NULL)
	{
		gtk_widget_destroy (TB->StatusBar_widget);
		TB->StatusBar_widget = NULL;
	}
	gtk_widget_show (GTK_WIDGET (gtkblist->statusbox));
	g_object_set (gtkblist->statusbox, "iconsel", TRUE, NULL);
	if (gtkblist->menutrayicon) gtk_widget_show (gtkblist->menutrayicon);
}

static void DrawStatusBar (PidginBuddyList *gtkblist)
{
	Debugging ("DrawStatusBar");
	DrawAddBuddyIcon ();
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_statusbar"))
	{
		CreateStatusBar (gtkblist);
		HideStatusBoxes	(gtkblist);
	}
}

static void ReDrawStatusBar (void)
{
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("ReDrawStatusBar");
	if (!gtkblist) return;
	RemoveStatusBar (gtkblist);
	DrawStatusBar (gtkblist);
}

static void ReDrawStatusBar_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	Debugging ("ReDrawStatusBar_cb");
	ReDrawToolbarMenu ();
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void DrawStatusBoxes_cb (const gchar *name, PurplePrefType type, gconstpointer value, gpointer data)
{
	Debugging ("DrawStatusBoxes_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/use_statusbox")) CreateStatusBoxes ();
	else RemoveStatusBoxes ();
}

static void CreateStatusBox (PurpleAccount *account)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("CreateStatusBox");
	if (!gtkblist) return;
	if (purple_account_get_enabled (account, purple_core_get_ui ()))
	{
		GtkWidget *sbox = pidgin_status_box_new_with_account (account);
		gtk_box_pack_start (GTK_BOX (gtkblist->vbox), sbox, FALSE, FALSE, 3);
		TB->StatusBoxes_glist = g_list_append (TB->StatusBoxes_glist, sbox);
	}
}

static void AccountEnabled_cb (PurpleAccount *account, gpointer data)
{
	Debugging ("AccountEnabled_cb");
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/use_statusbox")) CreateStatusBox (account);
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void RemoveStatusBox (PurpleAccount *account)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GList *iter;
	Debugging ("RemoveStatusBox");
	for (iter = TB->StatusBoxes_glist; iter; iter = iter->next)
	{
		PidginStatusBox *sbox = iter->data;
		if (sbox->account == account)
		{
			TB->StatusBoxes_glist = g_list_remove (TB->StatusBoxes_glist, sbox);
			gtk_widget_destroy (GTK_WIDGET (sbox));
			break;
		}
	}
}

static void AccountDisabled_cb (PurpleAccount *account, gpointer data)
{
	Debugging ("AccountDisabled_cb");
	if (purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/use_statusbox")) RemoveStatusBox (account);
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void AccountError_cb (PurpleAccount *account, const PurpleConnectionErrorInfo *old, const PurpleConnectionErrorInfo *new)
{
	Debugging ("AccountError_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void AccountSign_cb (PurpleConnection *gc)
{
	Debugging ("AccountSign_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void AccountStatusChanged_cb (PurpleAccount *account, PurpleStatus *old, PurpleStatus *new)
{
	Debugging ("AccountStatusChanged_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void SavedStatusChanged_cb (PurpleSavedStatus *now, PurpleSavedStatus *old, gpointer data)
{
	Debugging ("SavedStatusChanged_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void SavedStatusUpdated_cb (PurpleSavedStatus *status, gpointer data)
{
	Debugging ("SavedStatusUpdated_cb");
	ResetLastAccount ();
	ReDrawStatusBar ();
}

static void ReDrawToolbarMenu (void)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	Debugging ("ReDrawToolbarMenu");
	if (TB->ShowMainMenu_item) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (TB->ShowMainMenu_item), purple_prefs_get_bool ("/plugins/gtk/toobars/mainmenu/show_mainmenu"));
	if (TB->ShowToolbar_item) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (TB->ShowToolbar_item), purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_toolbar"));
	if (TB->ShowStatusbar_item) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (TB->ShowStatusbar_item), purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_statusbar"));
}

static void CreateBListMenu (PidginBuddyList *gtkblist)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	GtkWidget *BListMenu, *BListSubMenu, *MenuItem;
	GtkWidget *img;

	Debugging ("CreateBListMenu");
	if ((gtkblist == NULL) || (gtkblist->ift == NULL)) return;
	BListMenu = gtk_menu_new ();

	TB->AddBuddy_item = gtk_image_menu_item_new_with_mnemonic (_("Add _Buddy..."));
	img = gtk_image_new_from_stock (GTK_STOCK_ADD, gtk_icon_size_from_name (PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (TB->AddBuddy_item), img);
	gtk_menu_shell_append (GTK_MENU_SHELL (BListMenu), TB->AddBuddy_item);
	g_signal_connect (G_OBJECT (TB->AddBuddy_item), "activate", G_CALLBACK (AddBuddy_cb), NULL);
	pidgin_separator (BListMenu);
	BListSubMenu = gtk_item_factory_get_widget (gtkblist->ift, N_("/Buddies/Show"));
	if (BListSubMenu != NULL)
	{
		MenuItem = gtk_image_menu_item_new_with_mnemonic (_("Sh_ow"));
		img = gtk_image_new_from_stock (GTK_STOCK_INFO, gtk_icon_size_from_name (PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (MenuItem), img);
		gtk_menu_item_set_submenu (GTK_MENU_ITEM (MenuItem), BListSubMenu);
		gtk_menu_shell_append (GTK_MENU_SHELL (BListMenu), MenuItem);
		gtk_widget_show_all (BListSubMenu);
	}
	if ((purple_prefs_get_string (PIDGIN_PREFS_ROOT "/blist/sort_type") != NULL))
	{
		BListSubMenu = gtk_item_factory_get_widget (gtkblist->ift, N_("/Buddies/Sort Buddies"));
		if (BListSubMenu != NULL)
		{
			MenuItem = gtk_image_menu_item_new_with_mnemonic (_("_Sort Buddies"));
			img = gtk_image_new_from_stock (GTK_STOCK_SORT_ASCENDING, gtk_icon_size_from_name (PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
			gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (MenuItem), img);
			gtk_menu_item_set_submenu (GTK_MENU_ITEM (MenuItem), BListSubMenu);
			gtk_menu_shell_append (GTK_MENU_SHELL (BListMenu), MenuItem);
			gtk_widget_show_all (BListSubMenu);
		}
	}
	pidgin_separator (BListMenu);
	BListSubMenu = gtk_item_factory_get_widget (gtkblist->ift, N_("/Accounts"));
	if (BListSubMenu != NULL)
	{
		MenuItem = gtk_image_menu_item_new_with_mnemonic (_("_Accounts"));
		img = gtk_image_new_from_stock ("TOOBARS_STOCK_ACCOUNTS", gtk_icon_size_from_name (PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL));
		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (MenuItem), img);
		gtk_menu_item_set_submenu (GTK_MENU_ITEM (MenuItem), BListSubMenu);
		gtk_menu_shell_append (GTK_MENU_SHELL (BListMenu), MenuItem);
		gtk_widget_show_all (BListSubMenu);
	}
	pidgin_separator (BListMenu);
	pidgin_new_item_from_stock (BListMenu, _("Plu_gins"), PIDGIN_STOCK_TOOLBAR_PLUGINS, G_CALLBACK (pidgin_plugin_dialog_show), NULL, 0, 0, NULL);
	pidgin_new_item_from_stock (BListMenu, _("Pr_eferences"), GTK_STOCK_PREFERENCES, G_CALLBACK (pidgin_prefs_show), NULL, 0, 0, NULL);
	pidgin_separator (BListMenu);
	pidgin_new_item_from_stock (BListMenu, _("_Configure Plugin"), GTK_STOCK_PROPERTIES, G_CALLBACK (CreatePrefDialog_cb), NULL, 0, 0, NULL);
	gtk_widget_show_all (BListMenu);
	g_signal_connect_swapped (G_OBJECT (gtkblist->treeview), "button-press-event", G_CALLBACK (DrawContextMenu_cb), BListMenu);
}

static void CreateAllBox (PurpleBuddyList *blist)
{
 	struct _TooBars_interface *TB = &TooBars_interface;
	PidginBuddyList *gtkblist = PIDGIN_BLIST (blist);
	Debugging ("CreateAllBox");
	if ((gtkblist != NULL) && (GTK_IS_WINDOW (gtkblist->window)))
	{
		RegisterStockIcons ();
		TB->MainMenu_widget = gtk_item_factory_get_widget (gtkblist->ift, "<PurpleMain>");
		TB->StatusBar_widget = NULL;
		TB->ToolBar_widget = NULL;
		CreateBListMenu (gtkblist);
		DrawMainMenu ();
		DrawToolBar (gtkblist);
		DrawStatusBar (gtkblist);
		CreateStatusBoxes ();
		ResetLastAccount ();
	}
}

static void RegisterStockIcons (void)
{
	GtkIconFactory *IconFactory;
	GtkIconSet *IconSet;
	GtkIconSource *IconSource;
	PidginStatusBox *StatusBox;
	gint i;
	gint count = G_N_ELEMENTS (TooBars_stock);
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	if (gtkblist) StatusBox = PIDGIN_STATUS_BOX (gtkblist->statusbox);
	Debugging ("RegisterStockIcons");
	IconFactory = gtk_icon_factory_new ();
	for (i = 0; i < count; i++)
	{
		IconSet = gtk_icon_set_new ();
		IconSource = gtk_icon_source_new ();
		gtk_icon_source_set_filename (IconSource, GetIconFilename (TooBars_stock [i].filename));
		gtk_icon_set_add_source (IconSet, IconSource);
		gtk_icon_source_free (IconSource);
		gtk_icon_factory_add (IconFactory, TooBars_stock [i].id, IconSet);
		gtk_icon_set_unref (IconSet);
	}
	gtk_icon_factory_add_default (IconFactory);
	g_object_unref (IconFactory);
}

/*****************************************************************************************************************/

static void TogglePrefBtn_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("TogglePrefBtn_cb");
	purple_prefs_set_bool ((gchar *) data, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
}

static void ToggleSubGroupBtn_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("ToggleSubGroupBtn_cb");
	gtk_widget_set_sensitive (data, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
}

static void SensChangeSubGroupBtn_cb (GtkWidget *widget, GtkStateType state, gpointer data)
{
	gboolean flag;
	Debugging ("SensChangeSubGroupBtn_cb");
	if (state == GTK_STATE_INSENSITIVE)
	{
		flag = GTK_WIDGET_SENSITIVE (GTK_WIDGET (widget)) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
		gtk_widget_set_sensitive (data, flag);
	}
}

static void ToggleGroupBtn_cb (GtkWidget *widget, gpointer data)
{
	gboolean flag;
	Debugging ("ToggleGroupBtn_cb");
	flag = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
	if (!flag) gtk_widget_set_sensitive (data, flag);
}

static GtkWidget *CreatePrefBtn (GtkWidget *PrefGroup_vbox, GtkWidget *Group_tgl, gboolean active, gchar *PrefName, gchar *pref)
{
	GtkWidget *toggle, *hbox;
	Debugging ("CreatePrefBtn");
	hbox = gtk_hbox_new (FALSE, 5);
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), hbox, FALSE, FALSE, 0);
	toggle = gtk_check_button_new_with_mnemonic (PrefName);
	gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 18);
	if (active) gtk_widget_set_sensitive (toggle, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	else gtk_widget_set_sensitive (toggle, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), purple_prefs_get_bool (pref));
	g_signal_connect (G_OBJECT (toggle), "toggled", G_CALLBACK (TogglePrefBtn_cb), pref);
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (pidgin_toggle_sensitive), toggle);
	return toggle;
}

static GtkWidget *CreateSubPrefBtn (GtkWidget *PrefGroup_vbox, GtkWidget *Group_tgl, GtkWidget *SubGroup_tgl, gchar *PrefName, gchar *pref)
{
	GtkWidget *toggle, *hbox;
	gboolean flag;
	Debugging ("CreateSubPrefBtn");
	hbox = gtk_hbox_new (FALSE, 5);
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), hbox, FALSE, FALSE, 0);
	toggle = gtk_check_button_new_with_mnemonic (PrefName);
	gtk_box_pack_start (GTK_BOX (hbox), toggle, FALSE, FALSE, 36);
	flag = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (SubGroup_tgl));
	gtk_widget_set_sensitive (toggle, flag);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), purple_prefs_get_bool (pref));
	g_signal_connect (G_OBJECT (toggle), "toggled", G_CALLBACK (TogglePrefBtn_cb), pref);
	g_signal_connect (G_OBJECT (SubGroup_tgl), "toggled", G_CALLBACK (ToggleSubGroupBtn_cb), toggle);
	g_signal_connect (G_OBJECT (SubGroup_tgl), "state-changed", G_CALLBACK (SensChangeSubGroupBtn_cb), toggle);
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (ToggleGroupBtn_cb), toggle);
	return toggle;
}

static void ToggleSizeBtn_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("ToggleSizeBtn_cb");
	if ((gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) && (purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style") != 1)) gtk_widget_set_sensitive (data, TRUE);
	else gtk_widget_set_sensitive (data, FALSE);
}

static void SwitchPrefPage_cb (GtkNotebook *Pref_nb, GtkNotebookPage *page, guint num, gpointer data)
{
	Debugging ("SwitchPrefPage_cb");
	purple_prefs_set_int ("/plugins/gtk/toobars/pref_page", num);
}

static void StyleSelected_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("StyleSelected_cb");
	purple_prefs_set_int ("/plugins/gtk/toobars/toolbar/toolbar_style", gtk_combo_box_get_active (GTK_COMBO_BOX (widget)));
	gtk_widget_set_sensitive (data, (purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style") != 1));
}

static void SizeSelected_cb (GtkWidget *widget, gpointer data)
{
	Debugging ("SizeSelected_cb");
	purple_prefs_set_int ("/plugins/gtk/toobars/toolbar/toolbar_size", gtk_combo_box_get_active (GTK_COMBO_BOX (widget)));
}

static GtkWidget *CreatePrefFrame (PurplePlugin *plugin)
{
	GtkWidget *Pref_nb, *Pref_vbox, *PrefGroup_vbox, *Group_tgl;
	GtkWidget *hbox, *vbox, *frm, *img, *toggle, *combo1, *combo2, *label, *txt, *table;
	GString *str;

	Debugging ("CreatePrefFrame");
	Pref_nb = gtk_notebook_new ();
	vbox = gtk_vbox_new (FALSE, PIDGIN_HIG_BOX_SPACE);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), PIDGIN_HIG_BORDER);
	gtk_notebook_append_page (GTK_NOTEBOOK (Pref_nb), vbox, gtk_label_new (_("Info")));
	str = g_string_new (NULL);
	g_string_append_printf (str, "<font size=\"4\"><b>%s</b></font> %s\n\n", PLUGIN_NAME, PLUGIN_VERSION);
	g_string_append_printf (str, "%s\n\n", PLUGIN_DESCRIPTION);
	g_string_append_printf (str, _("<b>Website:</b> <a href=\"%s\">%s</a>\n"), PLUGIN_WEBSITE, PLUGIN_WEBSITE);
	g_string_append_printf (str, _("<b>Author:</b> <a href=\"mailto:%s\">%s</a>\n"), PLUGIN_MAIL, PLUGIN_AUTHOR);
	g_string_append_printf (str, _("<b>Translators:</b>\n%s\n\n"), PLUGIN_TRANSLATORS);
	g_string_append_printf (str, "<font color=\"red\" size=\"1\">%s</font>", PLUGIN_AD);
	frm = pidgin_create_imhtml (FALSE, &txt, NULL, NULL);
	gtk_imhtml_set_format_functions (GTK_IMHTML (txt), GTK_IMHTML_ALL);
	gtk_imhtml_append_text (GTK_IMHTML (txt), str->str, GTK_IMHTML_NO_SCROLL);
	gtk_box_pack_start (GTK_BOX (vbox), frm, TRUE, TRUE, 0);
	g_string_free (str, TRUE);

	Pref_vbox = gtk_vbox_new (FALSE, PIDGIN_HIG_BOX_SPACE);
	gtk_container_set_border_width (GTK_CONTAINER (Pref_vbox), PIDGIN_HIG_BORDER);
	gtk_notebook_append_page (GTK_NOTEBOOK (Pref_nb), Pref_vbox, gtk_label_new (_("Main Menu")));
	PrefGroup_vbox = gtk_vbox_new (FALSE, 5);
	gtk_container_add (GTK_CONTAINER (Pref_vbox), PrefGroup_vbox);
	Group_tgl = gtk_check_button_new_with_mnemonic (_("Show main m_enu"));
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), Group_tgl, FALSE, FALSE, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (Group_tgl), purple_prefs_get_bool ("/plugins/gtk/toobars/mainmenu/show_mainmenu"));
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (TogglePrefBtn_cb), "/plugins/gtk/toobars/mainmenu/show_mainmenu");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, FALSE, _("Use _Alt to show main menu"), "/plugins/gtk/toobars/mainmenu/use_alt_key");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, FALSE, _("Use _Ctrl to show main menu"), "/plugins/gtk/toobars/mainmenu/use_ctrl_key");
	hbox = gtk_hbox_new (FALSE, 5);
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), hbox, FALSE, FALSE, 15);
	gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (NULL), FALSE, FALSE, 7);
	img = gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_MENU);
	gtk_box_pack_start (GTK_BOX (hbox), img, FALSE, FALSE, 0);
	label = gtk_label_new (NULL);
	gtk_label_set_markup (GTK_LABEL (label), _("Press <b>F10</b> to show the main menu."));
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
	gtk_widget_set_sensitive (hbox, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (pidgin_toggle_sensitive), hbox);

	Pref_vbox = gtk_vbox_new (FALSE, PIDGIN_HIG_BOX_SPACE);
	gtk_container_set_border_width (GTK_CONTAINER (Pref_vbox), PIDGIN_HIG_BORDER);
	gtk_notebook_append_page (GTK_NOTEBOOK (Pref_nb), Pref_vbox, gtk_label_new (_("Toolbar")));
	PrefGroup_vbox = gtk_vbox_new (FALSE, 5);
	gtk_container_add (GTK_CONTAINER (Pref_vbox), PrefGroup_vbox);
	Group_tgl = gtk_check_button_new_with_mnemonic (_("Show _toolbar"));
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), Group_tgl, FALSE, FALSE, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (Group_tgl), purple_prefs_get_bool ("/plugins/gtk/toobars/toolbar/show_toolbar"));
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (TogglePrefBtn_cb), "/plugins/gtk/toobars/toolbar/show_toolbar");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show add buddy _button"), "/plugins/gtk/toobars/toolbar/show_add_btn");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show _hide offline buddies button"), "/plugins/gtk/toobars/toolbar/show_offline_btn");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show buddy _details button"), "/plugins/gtk/toobars/toolbar/show_details_btn");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show _mute sound button"), "/plugins/gtk/toobars/toolbar/show_mute_btn");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show _preferences button"), "/plugins/gtk/toobars/toolbar/show_pref_btn");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show _accounts button"), "/plugins/gtk/toobars/toolbar/show_accounts_btn");
	table = gtk_table_new (2, 2, FALSE);
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), table, FALSE, FALSE, 0);
	label = gtk_label_new (_("Style:"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 20, 0);
	gtk_widget_set_sensitive (label, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	combo1 = gtk_combo_box_new_text ();
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo1), _("Icons Only"));
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo1), _("Text Only"));
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo1), _("Text Below Icons"));
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo1), _("Default"));
	gtk_combo_box_set_active (GTK_COMBO_BOX (combo1), purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style"));
	gtk_widget_set_sensitive (combo1, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	gtk_table_attach (GTK_TABLE (table), combo1, 1, 2, 0, 1, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (pidgin_toggle_sensitive), label);
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (pidgin_toggle_sensitive), combo1);
	label = gtk_label_new (_("Icon Size:"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 20, 0);
	gtk_widget_set_sensitive (label, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	gtk_widget_set_sensitive (label, (purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style") != 1));
	combo2 = gtk_combo_box_new_text ();
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo2), _("Small"));
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo2), _("Large"));
	gtk_combo_box_append_text (GTK_COMBO_BOX (combo2), _("Default"));
	gtk_combo_box_set_active (GTK_COMBO_BOX (combo2), purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_size"));
	gtk_widget_set_sensitive (combo2, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (Group_tgl)));
	gtk_widget_set_sensitive (combo2, (purple_prefs_get_int ("/plugins/gtk/toobars/toolbar/toolbar_style") != 1));
	gtk_table_attach (GTK_TABLE (table), combo2, 1, 2, 1, 2, GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0);
	g_signal_connect (G_OBJECT (combo1), "changed", G_CALLBACK (StyleSelected_cb), label);
	g_signal_connect (G_OBJECT (combo1), "changed", G_CALLBACK (StyleSelected_cb), combo2);
	g_signal_connect (G_OBJECT (combo2), "changed", G_CALLBACK (SizeSelected_cb), NULL);
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (ToggleSizeBtn_cb), label);
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (ToggleSizeBtn_cb), combo2);

	Pref_vbox = gtk_vbox_new (FALSE, PIDGIN_HIG_BOX_SPACE);
	gtk_container_set_border_width (GTK_CONTAINER (Pref_vbox), PIDGIN_HIG_BORDER);
	gtk_notebook_append_page (GTK_NOTEBOOK (Pref_nb), Pref_vbox, gtk_label_new (_("Statusbar" )));
	PrefGroup_vbox = gtk_vbox_new (FALSE, 5);
	gtk_container_add (GTK_CONTAINER (Pref_vbox), PrefGroup_vbox);
	Group_tgl = gtk_check_button_new_with_mnemonic (_("Show _statusbar"));
	gtk_box_pack_start (GTK_BOX (PrefGroup_vbox), Group_tgl, FALSE, FALSE, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (Group_tgl), purple_prefs_get_bool ("/plugins/gtk/toobars/statusbar/show_statusbar"));
	g_signal_connect (G_OBJECT (Group_tgl), "toggled", G_CALLBACK (TogglePrefBtn_cb), "/plugins/gtk/toobars/statusbar/show_statusbar");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show t_oken account"), "/plugins/gtk/toobars/statusbar/show_token");
	toggle = CreateSubPrefBtn (PrefGroup_vbox, Group_tgl, toggle, _("Sho_w token status name"), "/plugins/gtk/toobars/statusbar/show_token_statusname");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show a_ctive accounts"), "/plugins/gtk/toobars/statusbar/show_accounts");
	toggle = CreateSubPrefBtn (PrefGroup_vbox, Group_tgl, toggle, _("Show accounts status _name"), "/plugins/gtk/toobars/statusbar/show_accounts_statusname");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Use status_box to change status"), "/plugins/gtk/toobars/statusbar/use_statusbox");
	toggle = CreateSubPrefBtn (PrefGroup_vbox, Group_tgl, toggle, _("Show _user icon in statusbox"), "/plugins/gtk/toobars/statusbar/show_icon");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show unrea_d message icon"), "/plugins/gtk/toobars/statusbar/show_unread");
	toggle = CreatePrefBtn (PrefGroup_vbox, Group_tgl, TRUE, _("Show statusbar resize _grip"), "/plugins/gtk/toobars/statusbar/show_resize_grip");
	gtk_widget_show_all (Pref_nb);
	gtk_notebook_set_current_page (GTK_NOTEBOOK (Pref_nb), purple_prefs_get_int ("/plugins/gtk/toobars/pref_page"));
	g_signal_connect (G_OBJECT (Pref_nb), "switch-page", G_CALLBACK (SwitchPrefPage_cb), NULL);
	return Pref_nb;
}

static gboolean PluginLoad (PurplePlugin *plugin)
{
	void *handle;
	PurpleBuddyList *blist = purple_get_blist ();
	PidginBuddyList *gtkblist = PIDGIN_BLIST (blist);
	Debugging ("PluginLoad");
	if ((gtkblist != NULL) && (GTK_IS_WINDOW (gtkblist->window))) CreateAllBox (blist);
	else purple_signal_connect (pidgin_blist_get_handle (), "gtkblist-created", plugin, PURPLE_CALLBACK (CreateAllBox), NULL);

	handle = purple_accounts_get_handle ();
	purple_signal_connect (handle, "account-status-changed", plugin, PURPLE_CALLBACK (AccountStatusChanged_cb), NULL);
	purple_signal_connect (handle, "account-connecting", plugin, PURPLE_CALLBACK (AccountStatusChanged_cb), NULL);
	purple_signal_connect (handle, "account-added", plugin, PURPLE_CALLBACK (AccountEnabled_cb), NULL);
	purple_signal_connect (handle, "account-enabled", plugin, PURPLE_CALLBACK (AccountEnabled_cb), NULL);
	purple_signal_connect (handle, "account-removed", plugin, PURPLE_CALLBACK (AccountDisabled_cb), NULL);
	purple_signal_connect (handle, "account-disabled", plugin, PURPLE_CALLBACK (AccountDisabled_cb), NULL);
	purple_signal_connect (handle, "account-error-changed", plugin, PURPLE_CALLBACK (AccountError_cb), NULL);

	handle = purple_connections_get_handle ();
	purple_signal_connect (handle, "signed-on", plugin, PURPLE_CALLBACK (AccountSign_cb), NULL);
	purple_signal_connect (handle, "signed-off", plugin, PURPLE_CALLBACK (AccountSign_cb), NULL);

	handle = purple_savedstatuses_get_handle ();
	purple_signal_connect (handle, "savedstatus-changed", plugin, PURPLE_CALLBACK (SavedStatusChanged_cb), NULL);
	purple_signal_connect (handle, "savedstatus-added", plugin, PURPLE_CALLBACK (SavedStatusUpdated_cb), NULL);
	purple_signal_connect (handle, "savedstatus-deleted", plugin, PURPLE_CALLBACK (SavedStatusUpdated_cb), NULL);
	purple_signal_connect (handle, "savedstatus-modified", plugin, PURPLE_CALLBACK (SavedStatusUpdated_cb), NULL);

	handle = purple_conversations_get_handle ();
	purple_signal_connect (handle, "conversation-updated", gtkblist, PURPLE_CALLBACK (ConvUpdate_cb), gtkblist);
	purple_signal_connect (handle, "deleting-conversation", gtkblist, PURPLE_CALLBACK (ConvDelete_cb), gtkblist);

	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/mainmenu/show_mainmenu", DrawMainMenu_cb, NULL);

	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_toolbar", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_add_btn", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_offline_btn", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_details_btn", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_mute_btn", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_pref_btn", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/show_accounts_btn", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/toolbar_style", ReDrawToolBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/toolbar/toolbar_size", ReDrawToolBar_cb, NULL);

	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_statusbar", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_token", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_token_statusname", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_accounts", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_accounts_statusname", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_unread", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_resize_grip", ReDrawStatusBar_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/use_statusbox", DrawStatusBoxes_cb, NULL);
	purple_prefs_connect_callback (plugin, "/plugins/gtk/toobars/statusbar/show_icon", ReDrawStatusBar_cb, NULL);

	return TRUE;
}

static gboolean PluginUnload (PurplePlugin *plugin)
{
	PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist ();
	Debugging ("PluginUnLoad");
	if (gtkblist)
	{
		ShowMainMenu ();
		RemoveToolBar (gtkblist);
		RemoveStatusBar (gtkblist);
		RemoveStatusBoxes ();
		if (gtkblist->menutrayicon) gtk_widget_show (gtkblist->menutrayicon);
		g_signal_handlers_disconnect_matched (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Buddies/Show/Offline Buddies")))), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (SyncOffline_cb), NULL);
		g_signal_handlers_disconnect_matched (G_OBJECT (GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (gtkblist->ift, N_("/Tools/Mute Sounds")))), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (SyncMuteSound_cb), NULL);
		g_signal_handlers_disconnect_matched (G_OBJECT (gtkblist->treeview), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK (DrawContextMenu_cb), NULL);
	}
	purple_prefs_disconnect_by_handle (plugin);
	return TRUE;
}

static PidginPluginUiInfo Preferences =
{
	CreatePrefFrame,
	0,
	NULL,
	NULL,
	NULL,
	NULL
};

static PurplePluginInfo info =
{
	PURPLE_PLUGIN_MAGIC,
	PURPLE_MAJOR_VERSION,
	PURPLE_MINOR_VERSION,
	PURPLE_PLUGIN_STANDARD,
	PIDGIN_PLUGIN_TYPE,
	0,
	NULL,

	PURPLE_PRIORITY_DEFAULT,
	PLUGIN_ID,
	NULL,
	PLUGIN_VERSION,
	NULL,
	NULL,
	PLUGIN_AUTHOR,
	PLUGIN_WEBSITE,

	PluginLoad,
	PluginUnload,
	NULL,

	&Preferences,
	NULL,
	NULL,
	NULL,

	NULL,
	NULL,
	NULL,
	NULL
};


static void InitPlugin (PurplePlugin *plugin)
{
	Debugging ("InitPlugin");

#ifdef ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif
	info.name = PLUGIN_NAME;
	info.summary = PLUGIN_SUMMARY;
	info.description = PLUGIN_DESCRIPTION;

	purple_prefs_add_none ("/plugins/gtk/toobars");

	purple_prefs_add_none ("/plugins/gtk/toobars/mainmenu");
	purple_prefs_add_bool ("/plugins/gtk/toobars/mainmenu/show_mainmenu", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/mainmenu/use_alt_key", FALSE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/mainmenu/use_ctrl_key", FALSE);

	purple_prefs_add_none ("/plugins/gtk/toobars/toolbar");
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_toolbar", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_add_btn", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_offline_btn", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_details_btn", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_mute_btn", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_pref_btn", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/toolbar/show_accounts_btn", TRUE);
	purple_prefs_add_int ("/plugins/gtk/toobars/toolbar/toolbar_style", 3);
	purple_prefs_add_int ("/plugins/gtk/toobars/toolbar/toolbar_size", 2);

	purple_prefs_add_none ("/plugins/gtk/toobars/statusbar");
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_statusbar", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_token", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_token_statusname", FALSE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_accounts", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_accounts_statusname", FALSE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/use_statusbox", FALSE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_icon", FALSE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_unread", TRUE);
	purple_prefs_add_bool ("/plugins/gtk/toobars/statusbar/show_resize_grip", FALSE);

	purple_prefs_add_int ("/plugins/gtk/toobars/pref_page", 0);
}

PURPLE_INIT_PLUGIN (toobars, InitPlugin, info)
