/**
 * @file ui_update.c GUI update monitor
 * 
 * Copyright (C) 2006-2026 Lars Windolf <lars.windolf@gmx.de>
 * 
 * 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 
 */

#include "ui/ui_update.h" 

#include "common.h"
#include "feedlist.h"
#include "node.h"
#include "subscription.h"
#include "update.h"
#include "ui/liferea_dialog.h"

enum {
	UM_FAVICON,
	UM_REQUEST_TITLE,
	UM_LEN
};

static GtkWidget *umdialog = NULL;
static GtkTreeStore *um1store = NULL;
static GtkTreeStore *um2store = NULL;
static GHashTable *um1hash = NULL;
static GHashTable *um2hash = NULL;

static void
ui_update_remove_request (Node *node, GtkTreeStore *store, GHashTable *hash)
{
	GtkTreeIter	*iter;

	iter = (GtkTreeIter *)g_hash_table_lookup (hash, node->id);
	if (iter) {
		gtk_tree_store_remove (store, iter);
		g_hash_table_remove (hash, (gpointer)node->id);
	}
}

static void
ui_update_merge_request (Node *node, GtkTreeStore *store, GHashTable *hash)
{
	GtkTreeIter	*iter;
        gchar           *title;

	if (NULL != (iter = (GtkTreeIter *)g_hash_table_lookup (hash, (gpointer)node->id)))
		return;

	iter = g_new0 (GtkTreeIter, 1);
	gtk_tree_store_append (store, iter, NULL);
        title = g_markup_escape_text (node_get_title (node), -1);
	gtk_tree_store_set (store, iter, UM_REQUEST_TITLE, title,
	                                UM_FAVICON, node_get_icon (node),
	                                -1);
	g_hash_table_insert (hash, (gpointer)node->id, (gpointer)iter);

        g_free (title);
}

static void
ui_update_find_requests (Node *node) {

	if (node->children)
		node_foreach_child (node, ui_update_find_requests);

	if (!node->subscription)
		return;
		
	if (node->subscription->updateJob) {
		gint state = update_job_get_state (node->subscription->updateJob);
		if (JOB_STATE_PROCESSING == state ||
		    JOB_STATE_FILTERING == state ||
		    JOB_STATE_FINISHED == state) {
			ui_update_merge_request (node, um1store, um1hash);
			ui_update_remove_request (node, um2store, um2hash);
			return;
		}

		if (JOB_STATE_PENDING == update_job_get_state (node->subscription->updateJob)) {
			ui_update_merge_request (node, um2store, um2hash);
			return;
		}
	}
			
	ui_update_remove_request (node, um1store, um1hash);
	ui_update_remove_request (node, um2store, um2hash);
}

static
gboolean ui_update_monitor_update (void *data) {

	if (umdialog) {
		feedlist_foreach (ui_update_find_requests);
		return TRUE;
	} else {
		return FALSE;
	}	
}

static void
ui_update_cancel (Node *node)
{
	if (node->children)
		node_foreach_child (node, ui_update_cancel);

	if (!node->subscription)
		return;
		
	subscription_cancel_update (node->subscription);
}

void
on_cancel_all_requests_clicked (GtkButton *button, gpointer user_data)
{
	feedlist_foreach (ui_update_cancel);
}

static void
on_update_monitor_destroyed_cb(GtkWidget *widget, void *data)
{
	g_hash_table_destroy (um1hash);
	g_hash_table_destroy (um2hash);
	g_object_unref (um1store);
	g_object_unref (um2store);
	um1hash = NULL;
	um2hash = NULL;
	um1store = NULL;
	um2store = NULL;
	umdialog = NULL;
}

void
on_close_update_monitor_clicked(GtkButton *button, gpointer user_data)
{
	gtk_widget_destroy(umdialog);
}
 
void
on_menu_show_update_monitor(GSimpleAction *action, GVariant *parameter, gpointer user_data) {
	GtkCellRenderer		*textRenderer, *iconRenderer;	
	GtkTreeViewColumn 	*column;
	GtkTreeView		*view;

	if (!umdialog) {
		umdialog = liferea_dialog_new ("update_monitor");
		g_signal_connect (G_OBJECT (umdialog), "destroy", G_CALLBACK (on_update_monitor_destroyed_cb), NULL);
		
		/* Set up left store and view */
		view = GTK_TREE_VIEW(liferea_dialog_lookup(umdialog, "left"));
		um1store = gtk_tree_store_new(UM_LEN, G_TYPE_ICON, G_TYPE_STRING);
		gtk_tree_view_set_model(view, GTK_TREE_MODEL(um1store));

		textRenderer = gtk_cell_renderer_text_new();
		iconRenderer = gtk_cell_renderer_pixbuf_new();
		column = gtk_tree_view_column_new();
	
		gtk_tree_view_column_pack_start(column, iconRenderer, FALSE);
		gtk_tree_view_column_pack_start(column, textRenderer, TRUE);
		gtk_tree_view_column_add_attribute(column, iconRenderer, "gicon", UM_FAVICON);
		gtk_tree_view_column_add_attribute(column, textRenderer, "markup", UM_REQUEST_TITLE);
		gtk_tree_view_append_column(view, column);
		
		/* Set up right store and view */
		view = GTK_TREE_VIEW(liferea_dialog_lookup(umdialog, "right"));
		um2store = gtk_tree_store_new(UM_LEN, G_TYPE_ICON, G_TYPE_STRING);
		gtk_tree_view_set_model(view, GTK_TREE_MODEL(um2store));

		textRenderer = gtk_cell_renderer_text_new();
		iconRenderer = gtk_cell_renderer_pixbuf_new();
		column = gtk_tree_view_column_new();
	
		gtk_tree_view_column_pack_start(column, iconRenderer, FALSE);
		gtk_tree_view_column_pack_start(column, textRenderer, TRUE);
		gtk_tree_view_column_add_attribute(column, iconRenderer, "gicon", UM_FAVICON);
		gtk_tree_view_column_add_attribute(column, textRenderer, "markup", UM_REQUEST_TITLE);
		gtk_tree_view_append_column(view, column);		
		
		/* Fill in data */
		um1hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
		um2hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
		ui_update_monitor_update (NULL);
	 	(void)g_timeout_add_seconds (1, ui_update_monitor_update, NULL);

		gtk_widget_show_all (umdialog);
	}

	gtk_window_present (GTK_WINDOW (umdialog));
}
