/*
 * Copyright (C) 2007 Carlos Garcia Campos  <carlosgc@gnome.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <gtk/gtk.h>

#include "fonts.h"

enum {
	FONTS_NAME_COLUMN,
	FONTS_DETAILS_COLUMN,
	N_COLUMNS
};

typedef struct {
	PopplerDocument *doc;
	
	GtkWidget       *treeview;
	GtkWidget       *progress;

	guint            idle_id;
} PgdFontsDemo;

static void
pgd_fonts_free (PgdFontsDemo *demo)
{
	if (!demo)
		return;

	if (demo->idle_id > 0) {
		g_source_remove (demo->idle_id);
		demo->idle_id = 0;
	}
	
	if (demo->doc) {
		g_object_unref (demo->doc);
		demo->doc = NULL;
	}

	g_free (demo);
}

static void
pdg_fonts_cell_data_func (GtkTreeViewColumn *col,
			  GtkCellRenderer   *renderer,
			  GtkTreeModel      *model,
			  GtkTreeIter       *iter,
			  gpointer           user_data)
{
	char *name;
	char *details;
	char *markup;

	gtk_tree_model_get (model, iter,
			    FONTS_NAME_COLUMN, &name,
			    FONTS_DETAILS_COLUMN, &details,
			    -1);

	if (details) {
		markup = g_strdup_printf ("<b><big>%s</big></b>\n<small>%s</small>",
					  name, details);
	} else {
		markup = g_strdup_printf ("<b><big>%s</big></b>", name);
	}

	g_object_set (renderer, "markup", markup, NULL);

	g_free (markup);
	g_free (details);
	g_free (name);
}

static const gchar *
font_type_to_string (PopplerFontType type)
{
	switch (type) {
	case POPPLER_FONT_TYPE_TYPE1:
		return "Type 1";
	case POPPLER_FONT_TYPE_TYPE1C:
		return "Type 1C";
	case POPPLER_FONT_TYPE_TYPE3:
		return "Type 3";
	case POPPLER_FONT_TYPE_TRUETYPE:
		return "TrueType";
	case POPPLER_FONT_TYPE_CID_TYPE0:
		return "Type 1 (CID)";
	case POPPLER_FONT_TYPE_CID_TYPE0C:
		return "Type 1C (CID)";
	case POPPLER_FONT_TYPE_CID_TYPE2:
		return "TrueType (CID)";
	default:
		return "Unknown font type";
	}
}

static void
pgd_fonts_update_progress (PgdFontsDemo *demo,
			   gint          n_pages,
			   gint          scanned)
{
	gchar *str;

	str = g_strdup_printf ("Scanning fonts (%d%%)",
			       MIN (scanned * 100 / n_pages, 100));
	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (demo->progress), str);
	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (demo->progress),
				       MIN ((gdouble)scanned / n_pages, 1.0));
	g_free (str);
}

static gboolean
pgd_fonts_fill_model (PgdFontsDemo *demo)
{
	GtkTreeModel     *model;
	PopplerFontInfo  *font_info;
	PopplerFontsIter *fonts_iter;
	gint              n_pages, scanned = 0;

	n_pages = poppler_document_get_n_pages (demo->doc);
	
	model = gtk_tree_view_get_model (GTK_TREE_VIEW (demo->treeview));
	g_object_ref (model);

	gtk_list_store_clear (GTK_LIST_STORE (model));

	font_info = poppler_font_info_new (demo->doc);

	while (poppler_font_info_scan (font_info, 20, &fonts_iter)) {
		pgd_fonts_update_progress (demo, n_pages, scanned);
		
		while (gtk_events_pending ())
			gtk_main_iteration ();

		scanned += 20;
		
		if (!fonts_iter)
			continue;
		
		do {
			GtkTreeIter iter;
			const gchar *name;
			const gchar *type;
			const gchar *embedded;
			const gchar *substitute;
			const gchar *filename;
			const gchar *encoding;
			gchar       *details;

			name = poppler_fonts_iter_get_name (fonts_iter);
			if (!name)
				name = "No name";

			encoding = poppler_fonts_iter_get_encoding (fonts_iter);
			if (!encoding)
				encoding = "None";

			type = font_type_to_string (poppler_fonts_iter_get_font_type (fonts_iter));
			
			if (poppler_fonts_iter_is_embedded (fonts_iter)) {
				if (poppler_fonts_iter_is_subset (fonts_iter))
					embedded = "Embedded subset";
				else
					embedded = "Embedded";
			} else {
				embedded = "Not embedded";
			}

			substitute = poppler_fonts_iter_get_substitute_name (fonts_iter);
			filename = poppler_fonts_iter_get_file_name (fonts_iter);

			if (substitute && filename)
				details = g_markup_printf_escaped ("%s\nEncoding: %s\n%s, substituting with <b>%s</b>\n(%s)", type, encoding, embedded, substitute, filename);
			else
				details = g_markup_printf_escaped ("%s\nEncoding: %s\n%s", type, encoding, embedded);

			gtk_list_store_append (GTK_LIST_STORE (model), &iter);
			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
					    FONTS_NAME_COLUMN, name,
					    FONTS_DETAILS_COLUMN, details,
					    -1);
			
			g_free (details);
		} while (poppler_fonts_iter_next (fonts_iter));
		poppler_fonts_iter_free (fonts_iter);
	}

	pgd_fonts_update_progress (demo, n_pages, scanned);
	
	g_object_unref (font_info);
	g_object_unref (model);

	return FALSE;
}

static void
pgd_fonts_scan_button_clicked (GtkButton    *button,
			       PgdFontsDemo *demo)
{
	demo->idle_id = g_idle_add ((GSourceFunc)pgd_fonts_fill_model, demo);
}

GtkWidget *
pgd_fonts_create_widget (PopplerDocument *document)
{
	PgdFontsDemo      *demo;
	GtkWidget         *vbox;
	GtkListStore      *model;
	GtkCellRenderer   *renderer;
	GtkTreeViewColumn *column;
	GtkWidget         *swindow;
	GtkWidget         *hbox, *button;

	demo = g_new0 (PgdFontsDemo, 1);

	demo->doc = g_object_ref (document);
	
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);

	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
	
	demo->progress = gtk_progress_bar_new ();
	gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (demo->progress),
					PANGO_ELLIPSIZE_END);
	gtk_box_pack_start (GTK_BOX (hbox), demo->progress, TRUE, TRUE, 0);
	gtk_widget_show (demo->progress);

	button = gtk_button_new_with_label ("Scan");
	g_signal_connect (G_OBJECT (button), "clicked",
			  G_CALLBACK (pgd_fonts_scan_button_clicked),
			  (gpointer)demo);
	gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
	gtk_widget_show (button);

	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6);
	gtk_widget_show (hbox);
	
	swindow = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

	model = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
	demo->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (demo->treeview), FALSE);
	gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (demo->treeview)),
				     GTK_SELECTION_NONE);
	g_object_unref (model);

	column = gtk_tree_view_column_new ();
	gtk_tree_view_append_column (GTK_TREE_VIEW (demo->treeview), column);
	
	renderer = gtk_cell_renderer_text_new ();
	gtk_tree_view_column_pack_start (GTK_TREE_VIEW_COLUMN (column), renderer, FALSE);
	gtk_tree_view_column_set_cell_data_func (column, renderer,
						 pdg_fonts_cell_data_func,
						 NULL, NULL);

	gtk_container_add (GTK_CONTAINER (swindow), demo->treeview);
	gtk_widget_show (demo->treeview);

	gtk_box_pack_start (GTK_BOX (vbox), swindow, TRUE, TRUE, 0);
	gtk_widget_show (swindow);

	g_object_weak_ref (G_OBJECT (swindow),
			   (GWeakNotify)pgd_fonts_free,
			   (gpointer)demo);

	return vbox;
}
