/*
 * Copyright © 2009-2010 freedcpp, http://code.google.com/p/freedcpp
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * In addition, as a special exception, compiling, linking, and/or
 * using OpenSSL with this program is allowed.
 */

#include "favoriteusers.hh"

#include <dcpp/ClientManager.h>
#include "settingsmanager.hh"
#include "wulformanager.hh"
#include "WulforUtil.hh"

using namespace std;
using namespace dcpp;

FavoriteUsers::FavoriteUsers():
	BookEntry(Entry::FAVORITE_USERS, _("Favorite Users"), "favoriteusers.glade")
{
	// Configure the dialog
	gtk_dialog_set_alternative_button_order(GTK_DIALOG(getWidget("descriptionDialog")), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1);
	gtk_window_set_transient_for(GTK_WINDOW(getWidget("descriptionDialog")), GTK_WINDOW(WulforManager::get()->getMainWindow()->getContainer()));

	// Initialize favorite users list treeview
	favoriteUserView.setView(GTK_TREE_VIEW(getWidget("favoriteUserView")), TRUE, "favoriteusers");
	favoriteUserView.insertColumn(N_("Auto Grant Slot"), G_TYPE_BOOLEAN, TreeView::BOOL, 120);
	favoriteUserView.insertColumn(N_("User"), G_TYPE_STRING, TreeView::ICON_STRING, 120, "Icon");
	favoriteUserView.insertColumn(N_("Most Recent Hub"), G_TYPE_STRING, TreeView::STRING, 230);
	favoriteUserView.insertColumn(N_("Time Last Seen"), G_TYPE_STRING, TreeView::STRING, 120);
	favoriteUserView.insertColumn(N_("Description"), G_TYPE_STRING, TreeView::STRING, 150);
	favoriteUserView.insertColumn(N_("CID"), G_TYPE_STRING, TreeView::STRING, 350);
	favoriteUserView.insertHiddenColumn("URL", G_TYPE_STRING);
	favoriteUserView.insertHiddenColumn("Icon", G_TYPE_STRING);
	favoriteUserView.finalize();

	favoriteUserStore = gtk_list_store_newv(favoriteUserView.getColCount(), favoriteUserView.getGTypes());
	gtk_tree_view_set_model(favoriteUserView.get(), GTK_TREE_MODEL(favoriteUserStore));
	g_object_unref(favoriteUserStore);

	favoriteUserSelection = gtk_tree_view_get_selection(favoriteUserView.get());
	gtk_tree_selection_set_mode(favoriteUserSelection, GTK_SELECTION_MULTIPLE);
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(favoriteUserStore), favoriteUserView.col("User"), GTK_SORT_ASCENDING);
	gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(favoriteUserView.get(), favoriteUserView.col("User")), TRUE);
	gtk_tree_view_set_fixed_height_mode(favoriteUserView.get(), TRUE);

	GList *list = gtk_tree_view_column_get_cell_renderers(gtk_tree_view_get_column(favoriteUserView.get(),
		favoriteUserView.col("Auto Grant Slot")));
	GObject *renderer = (GObject *)g_list_nth_data(list, 0);
	g_signal_connect(renderer, "toggled", G_CALLBACK(onAutoGrantSlotToggled_gui), (gpointer)this);
	g_list_free(list);

	g_signal_connect(getWidget("browseItem"), "activate", G_CALLBACK(onBrowseItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("matchQueueItem"), "activate", G_CALLBACK(onMatchQueueItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("sendPMItem"), "activate", G_CALLBACK(onSendPMItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("grantSlotItem"), "activate", G_CALLBACK(onGrantSlotItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("connectItem"), "activate", G_CALLBACK(onConnectItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("removeFromQueueItem"), "activate", G_CALLBACK(onRemoveFromQueueItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("descriptionItem"), "activate", G_CALLBACK(onDescriptionItemClicked_gui), (gpointer)this);
	g_signal_connect(getWidget("removeItem"), "activate", G_CALLBACK(onRemoveItemClicked_gui), (gpointer)this);
	g_signal_connect(favoriteUserView.get(), "button-press-event", G_CALLBACK(onButtonPressed_gui), (gpointer)this);
	g_signal_connect(favoriteUserView.get(), "button-release-event", G_CALLBACK(onButtonReleased_gui), (gpointer)this);
	g_signal_connect(favoriteUserView.get(), "key-release-event", G_CALLBACK(onKeyReleased_gui), (gpointer)this);
}

FavoriteUsers::~FavoriteUsers()
{
	FavoriteManager::getInstance()->removeListener(this);

	gtk_widget_destroy(getWidget("descriptionDialog"));
}

void FavoriteUsers::show()
{
	// Initialize favorite users list
	FavoriteManager::FavoriteMap map = FavoriteManager::getInstance()->getFavoriteUsers();
	FavoriteManager::FavoriteMap::const_iterator it;

	for (it = map.begin(); it != map.end(); ++it)
	{
		GtkTreeIter iter;
		const FavoriteUser &user = it->second;
		bool online = user.getUser()->isOnline();
		string hub = online ? WulforUtil::getHubNames(user.getUser()) : user.getUrl();
		string seen = online ? C_("User", "Online") : Util::formatTime("%Y-%m-%d %H:%M", user.getLastSeen());
		string cid = user.getUser()->getCID().toBase32();

		gtk_list_store_append(favoriteUserStore, &iter);
		gtk_list_store_set(favoriteUserStore, &iter,
			favoriteUserView.col("Auto Grant Slot"), user.isSet(FavoriteUser::FLAG_GRANTSLOT) ? TRUE : FALSE,
			favoriteUserView.col("User"), user.getNick().c_str(),
			favoriteUserView.col("Most Recent Hub"), hub.c_str(),
			favoriteUserView.col("Time Last Seen"), seen.c_str(),
			favoriteUserView.col("Description"), user.getDescription().c_str(),
			favoriteUserView.col("CID"), cid.c_str(),
			favoriteUserView.col("URL"), user.getUrl().c_str(),
			favoriteUserView.col("Icon"), "linuxdcpp-normal",
			-1);

		userIters.insert(UserIters::value_type(cid, iter));
	}
	FavoriteManager::getInstance()->addListener(this);
}

gboolean FavoriteUsers::onKeyReleased_gui(GtkWidget *widget, GdkEventKey *event, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		if (event->keyval == GDK_Delete || event->keyval == GDK_BackSpace)
		{
			fu->onRemoveItemClicked_gui(NULL, data);
		}
		else if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter)
		{
			fu->onDescriptionItemClicked_gui(NULL, data);
		}
		else if (event->keyval == GDK_Menu || (event->keyval == GDK_F10 && event->state & GDK_SHIFT_MASK))
		{
			gtk_menu_popup(GTK_MENU(fu->getWidget("menu")), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
		}
	}

	return FALSE;
}

gboolean FavoriteUsers::onButtonPressed_gui(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;
	fu->previous = event->type;

	if (event->button == 3)
	{
		GtkTreePath *path;

		if (gtk_tree_view_get_path_at_pos(fu->favoriteUserView.get(), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL))
		{
			bool selected = gtk_tree_selection_path_is_selected(fu->favoriteUserSelection, path);
			gtk_tree_path_free(path);

			if (selected)
				return TRUE;
		}
	}
	return FALSE;
}

gboolean FavoriteUsers::onButtonReleased_gui(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		if (event->button == 3 && event->type == GDK_BUTTON_RELEASE)
		{
			gtk_menu_popup(GTK_MENU(fu->getWidget("menu")), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
		}
	}

	return FALSE;
}

void FavoriteUsers::onBrowseItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		GtkTreeIter iter;
		GtkTreePath *path;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
		typedef Func3<FavoriteUsers, string, string, bool> F3;

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				F3 *func = new F3(fu, &FavoriteUsers::getFileList_client,
					fu->favoriteUserView.getString(&iter, "CID"),
					fu->favoriteUserView.getString(&iter, "URL"),
					FALSE);
				WulforManager::get()->dispatchClientFunc(func);
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);
	}
}

void FavoriteUsers::onMatchQueueItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		GtkTreeIter iter;
		GtkTreePath *path;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
		typedef Func3<FavoriteUsers, string, string, bool> F3;

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				F3 *func = new F3(fu, &FavoriteUsers::getFileList_client,
					fu->favoriteUserView.getString(&iter, "CID"),
					fu->favoriteUserView.getString(&iter, "URL"),
					TRUE);
				WulforManager::get()->dispatchClientFunc(func);
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);
	}
}

void FavoriteUsers::onSendPMItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		GtkTreeIter iter;
		GtkTreePath *path;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				string cid = fu->favoriteUserView.getString(&iter, "CID");
				string url = fu->favoriteUserView.getString(&iter, "URL");
  				WulforManager::get()->getMainWindow()->addPrivateMessage_gui(cid, url);
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);
	}
}

void FavoriteUsers::onGrantSlotItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		GtkTreeIter iter;
		GtkTreePath *path;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
		typedef Func2<FavoriteUsers, string, string> F2;

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				string cid = fu->favoriteUserView.getString(&iter, "CID");
				string url = fu->favoriteUserView.getString(&iter, "URL");
				F2 *func = new F2(fu, &FavoriteUsers::grantSlot_client, cid, url);
				WulforManager::get()->dispatchClientFunc(func);
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);
	}
}

void FavoriteUsers::onConnectItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		GtkTreeIter iter;
		GtkTreePath *path;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				string url = fu->favoriteUserView.getString(&iter, "URL");
				WulforManager::get()->getMainWindow()->showHub_gui(url);
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);
	}
}

void FavoriteUsers::onRemoveFromQueueItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		GtkTreeIter iter;
		GtkTreePath *path;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
		typedef Func1<FavoriteUsers, string> F1;

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				string cid = fu->favoriteUserView.getString(&iter, "CID");
				F1 *func = new F1(fu, &FavoriteUsers::removeUserFromQueue_client, cid);
				WulforManager::get()->dispatchClientFunc(func);
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);
	}
}

void FavoriteUsers::onDescriptionItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) == 1)
	{
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);

		if (list != NULL)
		{
			GtkTreeIter iter;
			GtkTreePath *path = (GtkTreePath *) list->data;
			string description, nick, cid;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				description = fu->favoriteUserView.getString(&iter, "Description");
				nick = fu->favoriteUserView.getString(&iter, "User");
				cid = fu->favoriteUserView.getString(&iter, "CID");
			}
			gtk_tree_path_free(path);
			g_list_free(list);

			gtk_window_set_title(GTK_WINDOW(fu->getWidget("descriptionDialog")), nick.c_str());
			gtk_entry_set_text(GTK_ENTRY(fu->getWidget("descriptionEntry")), description.c_str());
			gint response = gtk_dialog_run(GTK_DIALOG(fu->getWidget("descriptionDialog")));

			// Fix crash, if the dialog gets programmatically destroyed.
			if (response == GTK_RESPONSE_NONE)
			{
				return;
			}

			gtk_widget_hide(fu->getWidget("descriptionDialog"));

			if (response != GTK_RESPONSE_OK)
				return;

			if (fu->findUser_gui(cid, &iter))
			{
				description = gtk_entry_get_text(GTK_ENTRY(fu->getWidget("descriptionEntry")));
				gtk_list_store_set(fu->favoriteUserStore, &iter, fu->favoriteUserView.col("Description"), description.c_str(), -1);

				typedef Func2<FavoriteUsers, string, string> F2;
				F2 *func = new F2(fu, &FavoriteUsers::setUserDescription_client, cid, description);
				WulforManager::get()->dispatchClientFunc(func);
			}
		}
	}
}

void FavoriteUsers::onRemoveItemClicked_gui(GtkMenuItem *item, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;

	if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
	{
		ParamMap params;
		GtkTreeIter iter;
		GtkTreePath *path;
		typedef Func1<FavoriteUsers, string> F1;
		GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);

		for (GList *i = list; i; i = i->next)
		{
			path = (GtkTreePath *)i->data;

			if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
			{
				string cid = fu->favoriteUserView.getString(&iter, "CID");
				string nick = fu->favoriteUserView.getString(&iter, "User");
				params.insert(ParamMap::value_type(cid, nick));
			}
			gtk_tree_path_free(path);
		}
		g_list_free(list);

		if (BOOLSETTING(CONFIRM_USER_REMOVAL))
		{
			GtkWindow* parent = GTK_WINDOW(WulforManager::get()->getMainWindow()->getContainer());
			GtkWidget* dialog = gtk_message_dialog_new(parent,
				GTK_DIALOG_DESTROY_WITH_PARENT,
				GTK_MESSAGE_WARNING,
				GTK_BUTTONS_NONE,
				_("Are you sure you want to delete the selected favorite users?"));
			gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_REMOVE,
				GTK_RESPONSE_YES, NULL);
			gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_YES, GTK_RESPONSE_CANCEL, -1);
			gint response = gtk_dialog_run(GTK_DIALOG(dialog));

			// Widget failed if the dialog gets programmatically destroyed.
			if (response == GTK_RESPONSE_NONE)
				return;

			gtk_widget_hide(dialog);

			if (response != GTK_RESPONSE_YES)
				return;
		}

		for (ParamMap::const_iterator it = params.begin(); it != params.end(); ++it)
		{
			F1 *func = new F1(fu, &FavoriteUsers::removeFavoriteUser_client, it->first);
			WulforManager::get()->dispatchClientFunc(func);
		}
	}
}

void FavoriteUsers::onAutoGrantSlotToggled_gui(GtkCellRendererToggle *cell, gchar *path, gpointer data)
{
	FavoriteUsers *fu = (FavoriteUsers *)data;
	GtkTreeIter iter;

	if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
	{
		string cid = fu->favoriteUserView.getString(&iter, "CID");
		gboolean grant = fu->favoriteUserView.getValue<gboolean>(&iter, "Auto Grant Slot");
		grant = !grant;
		gtk_list_store_set(fu->favoriteUserStore, &iter, fu->favoriteUserView.col("Auto Grant Slot"), grant, -1);

		typedef Func2<FavoriteUsers, string, bool> F2;
		F2 *func = new F2(fu, &FavoriteUsers::setAutoGrantSlot_client, cid, grant);
		WulforManager::get()->dispatchClientFunc(func);
	}
}

void FavoriteUsers::getFileList_client(const string cid, const string hubUrl, bool match)
{
	try
	{
		UserPtr user = ClientManager::getInstance()->findUser(CID(cid));

		if (user)
		{
			if (match)

				QueueManager::getInstance()->addList(user, hubUrl, QueueItem::FLAG_MATCH_QUEUE);
			else
				QueueManager::getInstance()->addList(user, hubUrl, QueueItem::FLAG_CLIENT_VIEW);
		}
	}
	catch (const Exception& e)
	{
		typedef Func1<FavoriteUsers, string> F1;
		F1 *func = new F1(this, &FavoriteUsers::setStatus_gui, e.getError());
		WulforManager::get()->dispatchGuiFunc(func);
	}
}

void FavoriteUsers::grantSlot_client(const string cid, const string hubUrl)
{
	UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
	if (user)
	{
		string message = _("Slot granted to ") + WulforUtil::getNicks(user);
		UploadManager::getInstance()->reserveSlot(user, hubUrl);
		typedef Func1<FavoriteUsers, string> F1;
		F1 *func = new F1(this, &FavoriteUsers::setStatus_gui, message);
		WulforManager::get()->dispatchGuiFunc(func);
	}
}

void FavoriteUsers::removeUserFromQueue_client(const string cid)
{
	if (!cid.empty())
	{
		UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
		if (user)
			QueueManager::getInstance()->removeSource(user, QueueItem::Source::FLAG_REMOVED);
	}
}

void FavoriteUsers::setAutoGrantSlot_client(const string cid, bool grant)
{
	UserPtr user = ClientManager::getInstance()->findUser(CID(cid));

	if (user)
	{
		FavoriteManager::getInstance()->setAutoGrant(user, grant);
	}
}

void FavoriteUsers::removeFavoriteUser_client(const string cid)
{
	UserPtr user = ClientManager::getInstance()->findUser(CID(cid));

	if (user)
	{
		FavoriteManager::getInstance()->removeFavoriteUser(user);
	}
}

void FavoriteUsers::setUserDescription_client(const string cid, const string description)
{
	UserPtr user = ClientManager::getInstance()->findUser(CID(cid));

	if (user)
	{
		FavoriteManager::getInstance()->setUserDescription(user, description);
	}
}

bool FavoriteUsers::findUser_gui(const string &cid, GtkTreeIter *iter)
{
	UserIters::const_iterator it = userIters.find(cid);

	if (it != userIters.end())
	{
		if (iter)
			*iter = it->second;

		return TRUE;
	}

	return FALSE;
}

void FavoriteUsers::updateFavoriteUser_gui(ParamMap params)
{
	const string &cid = params["CID"];
	GtkTreeIter iter;

	if (findUser_gui(cid, &iter))
	{
		gtk_list_store_set(favoriteUserStore, &iter, favoriteUserView.col("Time Last Seen"), params["Time"].c_str(), -1);
	}
	else
	{
		gtk_list_store_append(favoriteUserStore, &iter);
		gtk_list_store_set(favoriteUserStore, &iter,
			favoriteUserView.col("User"), params["User"].c_str(),
			favoriteUserView.col("Most Recent Hub"), params["Hub"].c_str(),
			favoriteUserView.col("Time Last Seen"), params["Time"].c_str(),
			favoriteUserView.col("Description"), params["Description"].c_str(),
			favoriteUserView.col("CID"), cid.c_str(),
			favoriteUserView.col("URL"), params["URL"].c_str(),
			favoriteUserView.col("Icon"), "linuxdcpp-normal",
			-1);

		userIters.insert(UserIters::value_type(cid, iter));
	}
}

void FavoriteUsers::removeFavoriteUser_gui(const string cid)
{
	GtkTreeIter iter;

	if (findUser_gui(cid, &iter))
	{
		gtk_list_store_remove(favoriteUserStore, &iter);
		userIters.erase(cid);
	}
}

void FavoriteUsers::setStatus_gui(const string text)
{
	if (!text.empty())
	{
		string status = "[" + Util::getShortTimeString() + "] " + text;
		gtk_statusbar_pop(GTK_STATUSBAR(getWidget("status")), 0);
		gtk_statusbar_push(GTK_STATUSBAR(getWidget("status")), 0, status.c_str());
	}
}

void FavoriteUsers::on(FavoriteManagerListener::UserAdded, const FavoriteUser &user) throw()
{
	ParamMap params;
	bool online = user.getUser()->isOnline();
	params.insert(ParamMap::value_type("User", user.getNick()));
	params.insert(ParamMap::value_type("Hub", online ? WulforUtil::getHubNames(user.getUser()) : user.getUrl()));
	params.insert(ParamMap::value_type("Time", online ? C_("User", "Online") : Util::formatTime("%Y-%m-%d %H:%M", user.getLastSeen())));
	params.insert(ParamMap::value_type("Description", user.getDescription()));
	params.insert(ParamMap::value_type("CID", user.getUser()->getCID().toBase32()));
	params.insert(ParamMap::value_type("URL", user.getUrl()));

	Func1<FavoriteUsers, ParamMap> *func = new Func1<FavoriteUsers, ParamMap>(this, &FavoriteUsers::updateFavoriteUser_gui, params);
	WulforManager::get()->dispatchGuiFunc(func);
}

void FavoriteUsers::on(FavoriteManagerListener::UserRemoved, const FavoriteUser &user) throw()
{
	string cid = user.getUser()->getCID().toBase32();
	typedef Func1<FavoriteUsers, string> F1;
	F1 *func = new F1(this, &FavoriteUsers::removeFavoriteUser_gui, cid);
	WulforManager::get()->dispatchGuiFunc(func);
}

void FavoriteUsers::on(FavoriteManagerListener::StatusChanged, const UserPtr &user) throw()
{
	ParamMap params;
	string seen;
	string cid = user->getCID().toBase32();

	if (user->isOnline())
	{
		seen = C_("User", "Online");
	}
	else
	{
		time_t time = FavoriteManager::getInstance()->getLastSeen(user);
		seen = Util::formatTime("%Y-%m-%d %H:%M", time);
	}

	params.insert(ParamMap::value_type("Time", seen));
	params.insert(ParamMap::value_type("CID", cid));

	typedef Func1<FavoriteUsers, ParamMap> F1;
	F1 *func = new F1(this, &FavoriteUsers::updateFavoriteUser_gui, params);
	WulforManager::get()->dispatchGuiFunc(func);
}

