/*
 * 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 <stdio.h>
#include <unistd.h>
#include <time.h>

#include "utils.h"

void
pgd_table_add_property_with_custom_widget (GtkGrid     *table,
					   const gchar *markup,
					   GtkWidget   *widget,
					   gint        *row)
{
	GtkWidget *label;

	label = gtk_label_new (NULL);
	g_object_set (G_OBJECT (label), "xalign", 0.0, NULL);
	gtk_label_set_markup (GTK_LABEL (label), markup);
	gtk_grid_attach (GTK_GRID (table), label, 0, *row, 1, 1);
	gtk_widget_show (label);

	gtk_grid_attach (GTK_GRID (table), widget, 1, *row, 1, 1);
        gtk_widget_set_hexpand (widget, TRUE);
	gtk_widget_show (widget);

	*row += 1;
}

void
pgd_table_add_property_with_value_widget (GtkGrid     *table,
					  const gchar *markup,
					  GtkWidget  **value_widget,
					  const gchar *value,
					  gint        *row)
{
	GtkWidget *label;

	*value_widget = label = gtk_label_new (value);
	g_object_set (G_OBJECT (label),
		      "xalign", 0.0,
		      "selectable", TRUE,
		      "ellipsize", PANGO_ELLIPSIZE_END,
		      NULL);
	pgd_table_add_property_with_custom_widget (table, markup, label, row);
}

void
pgd_table_add_property (GtkGrid     *table,
			const gchar *markup,
			const gchar *value,
			gint        *row)
{
	GtkWidget *label;

	pgd_table_add_property_with_value_widget (table, markup, &label, value, row);
}

GtkWidget *
pgd_action_view_new (PopplerDocument *document)
{
	GtkWidget  *frame, *label;

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
	label = gtk_label_new (NULL);
	gtk_label_set_markup (GTK_LABEL (label), "<b>Action Properties</b>");
	gtk_frame_set_label_widget (GTK_FRAME (frame), label);
	gtk_widget_show (label);

	g_object_set_data (G_OBJECT (frame), "document", document);

	return frame;
}

static void
pgd_action_view_add_destination (GtkWidget   *action_view,
				 GtkGrid     *table,
				 PopplerDest *dest,
				 gboolean     remote,
				 gint        *row)
{
	PopplerDocument *document;
	GEnumValue      *enum_value;
	gchar           *str;
	
	pgd_table_add_property (table, "<b>Type:</b>", "Destination", row);
	
	enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (POPPLER_TYPE_DEST_TYPE), dest->type);
	pgd_table_add_property (table, "<b>Destination Type:</b>", enum_value->value_name, row);

	document = g_object_get_data (G_OBJECT (action_view), "document");
	
	if (dest->type != POPPLER_DEST_NAMED) {
		str = NULL;
		
		if (document && !remote) {
			PopplerPage *poppler_page;
			gchar       *page_label;
			
			poppler_page = poppler_document_get_page (document, MAX (0, dest->page_num - 1));
			
			g_object_get (G_OBJECT (poppler_page),
				      "label", &page_label,
				      NULL);
			if (page_label) {
				str = g_strdup_printf ("%d (%s)", dest->page_num, page_label);
				g_free (page_label);
			}
		}
		
		if (!str)
			str = g_strdup_printf ("%d", dest->page_num);
		pgd_table_add_property (table, "<b>Page:</b>", str, row);
		g_free (str);
		
		str = g_strdup_printf ("%.2f", dest->left);
		pgd_table_add_property (table, "<b>Left:</b>", str, row);
		g_free (str);
		
		str = g_strdup_printf ("%.2f", dest->right);
		pgd_table_add_property (table, "<b>Right:</b>", str, row);
		g_free (str);
		
		str = g_strdup_printf ("%.2f", dest->top);
		pgd_table_add_property (table, "<b>Top:</b>", str, row);
		g_free (str);
	
		str = g_strdup_printf ("%.2f", dest->bottom);
		pgd_table_add_property (table, "<b>Bottom:</b>", str, row);
		g_free (str);
	
		str = g_strdup_printf ("%.2f", dest->zoom);
		pgd_table_add_property (table, "<b>Zoom:</b>", str, row);
		g_free (str);
	} else {
		pgd_table_add_property (table, "<b>Named Dest:</b>", dest->named_dest, row);

		if (document && !remote) {
			PopplerDest *new_dest;

			new_dest = poppler_document_find_dest (document, dest->named_dest);
			if (new_dest) {
				GtkWidget *new_table;
				gint       new_row = 0;

				new_table = gtk_grid_new ();
				gtk_widget_set_margin_top (new_table, 5);
				gtk_widget_set_margin_bottom (new_table, 5);
#if GTK_CHECK_VERSION(3, 12, 0)
				gtk_widget_set_margin_start (new_table, 12);
				gtk_widget_set_margin_end (new_table, 5);
#else
				gtk_widget_set_margin_left (new_table, 12);
				gtk_widget_set_margin_right (new_table, 5);
#endif
				gtk_grid_set_column_spacing (GTK_GRID (new_table), 6);
				gtk_grid_set_row_spacing (GTK_GRID (new_table), 6);
				
				pgd_action_view_add_destination (action_view, GTK_GRID (new_table),
								 new_dest, FALSE, &new_row);
				poppler_dest_free (new_dest);

				gtk_grid_attach (GTK_GRID(table), new_table, 0, *row, 1, 1);
				gtk_widget_show (new_table);

				*row += 1;
			}
		}
	}
}

static const gchar *
get_movie_op (PopplerActionMovieOperation op)
{
	switch (op) {
	case POPPLER_ACTION_MOVIE_PLAY:
		return "Play";
	case POPPLER_ACTION_MOVIE_PAUSE:
		return "Pause";
	case POPPLER_ACTION_MOVIE_RESUME:
		return "Resume";
	case POPPLER_ACTION_MOVIE_STOP:
		return "Stop";
	}
	return NULL;
}

static void
free_tmp_file (GFile *tmp_file)
{

	g_file_delete (tmp_file, NULL, NULL);
	g_object_unref (tmp_file);
}

static gboolean
save_helper (const gchar  *buf,
	     gsize         count,
	     gpointer      data,
	     GError      **error)
{
	gint fd = GPOINTER_TO_INT (data);

	return write (fd, buf, count) == count;
}

static void
pgd_action_view_play_rendition (GtkWidget    *button,
				PopplerMedia *media)
{
	GFile *file = NULL;
	gchar *uri;

	if (poppler_media_is_embedded (media)) {
		gint   fd;
		gchar *tmp_filename = NULL;

		fd = g_file_open_tmp (NULL, &tmp_filename, NULL);
		if (fd != -1) {
			if (poppler_media_save_to_callback (media, save_helper, GINT_TO_POINTER (fd), NULL)) {
				file = g_file_new_for_path (tmp_filename);
				g_object_set_data_full (G_OBJECT (media),
							"tmp-file", g_object_ref (file),
							(GDestroyNotify)free_tmp_file);
			} else {
				g_free (tmp_filename);
			}
			close (fd);
		} else if (tmp_filename) {
			g_free (tmp_filename);
		}

	} else {
		const gchar *filename;

		filename = poppler_media_get_filename (media);
		if (g_path_is_absolute (filename)) {
			file = g_file_new_for_path (filename);
		} else if (g_strrstr (filename, "://")) {
			file = g_file_new_for_uri (filename);
		} else {
			gchar *cwd;
			gchar *path;

			// FIXME: relative to doc uri, not cwd
			cwd = g_get_current_dir ();
			path = g_build_filename (cwd, filename, NULL);
			g_free (cwd);

			file = g_file_new_for_path (path);
			g_free (path);
		}
	}

	if (file) {
		uri = g_file_get_uri (file);
		g_object_unref (file);
		if (uri) {
#if GTK_CHECK_VERSION(3, 22, 0)
			GtkWidget *toplevel;

			toplevel = gtk_widget_get_toplevel (button);
			gtk_show_uri_on_window (gtk_widget_is_toplevel (toplevel) ? GTK_WINDOW (toplevel) : NULL,
						uri, GDK_CURRENT_TIME, NULL);
#else
			gtk_show_uri (gtk_widget_get_screen (button),
				      uri, GDK_CURRENT_TIME, NULL);
#endif
			g_free (uri);
		}
	}
}

static void
pgd_action_view_do_action_layer (GtkWidget *button,
				 GList     *state_list)
{
	GList *l, *m;

	for (l = state_list; l; l = g_list_next (l)) {
		PopplerActionLayer *action_layer = (PopplerActionLayer *)l->data;

		for (m = action_layer->layers; m; m = g_list_next (m)) {
			PopplerLayer *layer = (PopplerLayer *)m->data;

			switch (action_layer->action) {
			case POPPLER_ACTION_LAYER_ON:
				poppler_layer_show (layer);
				break;
			case POPPLER_ACTION_LAYER_OFF:
				poppler_layer_hide (layer);
				break;
			case POPPLER_ACTION_LAYER_TOGGLE:
				if (poppler_layer_is_visible (layer))
					poppler_layer_hide (layer);
				else
					poppler_layer_show (layer);
				break;
			}
		}
	}
}

void
pgd_action_view_set_action (GtkWidget     *action_view,
			    PopplerAction *action)
{
	GtkWidget  *table;
	gint        row = 0;

	table = gtk_bin_get_child (GTK_BIN (action_view));
	if (table) {
		gtk_container_remove (GTK_CONTAINER (action_view), table);
	}

	if (!action)
		return;

	table = gtk_grid_new ();
	gtk_widget_set_margin_top (table, 5);
	gtk_widget_set_margin_bottom (table, 5);
#if GTK_CHECK_VERSION(3, 12, 0)
	gtk_widget_set_margin_start (table, 12);
	gtk_widget_set_margin_end (table, 5);
#else
	gtk_widget_set_margin_left (table, 12);
	gtk_widget_set_margin_right (table, 5);
#endif
	gtk_grid_set_column_spacing (GTK_GRID (table), 6);
	gtk_grid_set_row_spacing (GTK_GRID (table), 6);

	pgd_table_add_property (GTK_GRID (table), "<b>Title:</b>", action->any.title, &row);
	
	switch (action->type) {
	case POPPLER_ACTION_UNKNOWN:
		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "Unknown", &row);
		break;
	case POPPLER_ACTION_NONE:
		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "None", &row);
		break;
	case POPPLER_ACTION_GOTO_DEST:
		pgd_action_view_add_destination (action_view, GTK_GRID (table), action->goto_dest.dest, FALSE, &row);
		break;
	case POPPLER_ACTION_GOTO_REMOTE:
		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "Remote Destination", &row);
		pgd_table_add_property (GTK_GRID (table), "<b>Filename:</b>", action->goto_remote.file_name, &row);
		pgd_action_view_add_destination (action_view, GTK_GRID (table), action->goto_remote.dest, TRUE, &row);
		break;
	case POPPLER_ACTION_LAUNCH:
		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "Launch", &row);
		pgd_table_add_property (GTK_GRID (table), "<b>Filename:</b>", action->launch.file_name, &row);
		pgd_table_add_property (GTK_GRID (table), "<b>Params:</b>", action->launch.params, &row);
		break;
	case POPPLER_ACTION_URI:
		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "External URI", &row);
		pgd_table_add_property (GTK_GRID (table), "<b>URI</b>", action->uri.uri, &row);
		break;
	case POPPLER_ACTION_NAMED:
		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "Named Action", &row);
		pgd_table_add_property (GTK_GRID (table), "<b>Name:</b>", action->named.named_dest, &row);
		break;
	case POPPLER_ACTION_MOVIE: {
		GtkWidget *movie_view = pgd_movie_view_new ();

		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "Movie", &row);
		pgd_table_add_property (GTK_GRID (table), "<b>Operation:</b>", get_movie_op (action->movie.operation), &row);
		pgd_movie_view_set_movie (movie_view, action->movie.movie);
		pgd_table_add_property_with_custom_widget (GTK_GRID (table), "<b>Movie:</b>", movie_view, &row);
	}
		break;
	case POPPLER_ACTION_RENDITION: {
		gchar *text;

		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "Rendition", &row);
		text = g_strdup_printf ("%d", action->rendition.op);
		pgd_table_add_property (GTK_GRID (table), "<b>Operation:</b>", text, &row);
		g_free (text);
		if (action->rendition.media) {
			gboolean   embedded = poppler_media_is_embedded (action->rendition.media);
			GtkWidget *button;

			pgd_table_add_property (GTK_GRID (table), "<b>Embedded:</b>", embedded ? "Yes": "No", &row);
			if (embedded) {
				const gchar *mime_type = poppler_media_get_mime_type (action->rendition.media);
				pgd_table_add_property (GTK_GRID (table), "<b>Mime type:</b>",
							mime_type ? mime_type : "",
							&row);
			} else {
				pgd_table_add_property (GTK_GRID (table), "<b>Filename:</b>",
							poppler_media_get_filename (action->rendition.media),
							&row);
			}

			button = gtk_button_new_with_mnemonic ("_Play");
			g_signal_connect (button, "clicked",
					  G_CALLBACK (pgd_action_view_play_rendition),
					  action->rendition.media);
			pgd_table_add_property_with_custom_widget (GTK_GRID (table), NULL, button, &row);
			gtk_widget_show (button);
		}
	}
		break;
	case POPPLER_ACTION_OCG_STATE: {
		GList     *l;
		GtkWidget *button;

		pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "OCGState", &row);

		for (l = action->ocg_state.state_list; l; l = g_list_next (l)) {
			PopplerActionLayer *action_layer = (PopplerActionLayer *)l->data;
			gchar *text = NULL;
			gint   n_layers = g_list_length (action_layer->layers);

			switch (action_layer->action) {
			case POPPLER_ACTION_LAYER_ON:
				text = g_strdup_printf ("%d layers On", n_layers);
				break;
			case POPPLER_ACTION_LAYER_OFF:
				text = g_strdup_printf ("%d layers Off", n_layers);
				break;
			case POPPLER_ACTION_LAYER_TOGGLE:
				text = g_strdup_printf ("%d layers Toggle", n_layers);
				break;
			}
			pgd_table_add_property (GTK_GRID (table), "<b>Action:</b>", text, &row);
			g_free (text);
		}

		button = gtk_button_new_with_label ("Do action");
		g_signal_connect (button, "clicked",
				  G_CALLBACK (pgd_action_view_do_action_layer),
				  action->ocg_state.state_list);
		pgd_table_add_property_with_custom_widget (GTK_GRID (table), NULL, button, &row);
		gtk_widget_show (button);
	}
		break;
        case POPPLER_ACTION_JAVASCRIPT: {
                GtkTextBuffer *buffer;
                GtkWidget     *textview;
                GtkWidget     *swindow;

                pgd_table_add_property (GTK_GRID (table), "<b>Type:</b>", "JavaScript", &row);

                buffer = gtk_text_buffer_new (NULL);
                if (action->javascript.script)
                        gtk_text_buffer_set_text (buffer, action->javascript.script, -1);

                textview = gtk_text_view_new_with_buffer (buffer);
                gtk_text_view_set_editable (GTK_TEXT_VIEW (textview), FALSE);
                g_object_unref (buffer);

                swindow = gtk_scrolled_window_new (NULL, NULL);
                gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
                                                GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
                gtk_container_add (GTK_CONTAINER (swindow), textview);
                gtk_widget_show (textview);

                pgd_table_add_property_with_custom_widget (GTK_GRID (table), NULL, swindow, &row);
                gtk_widget_show (swindow);
        }
                break;
	default:
		g_assert_not_reached ();
	}

	gtk_container_add (GTK_CONTAINER (action_view), table);
	gtk_widget_show (table);
}

gchar *
pgd_format_date (time_t utime)
{
	time_t time = (time_t) utime;
	char s[256];
	const char *fmt_hack = "%c";
	size_t len;
	struct tm t;
	if (time == 0 || !localtime_r (&time, &t)) return NULL;
	len = strftime (s, sizeof (s), fmt_hack, &t);

	if (len == 0 || s[0] == '\0') return NULL;

	return g_locale_to_utf8 (s, -1, NULL, NULL, NULL);
}

GtkWidget *
pgd_movie_view_new (void)
{
	GtkWidget  *frame, *label;

	frame = gtk_frame_new (NULL);
	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
	label = gtk_label_new (NULL);
	gtk_label_set_markup (GTK_LABEL (label), "<b>Movie Properties</b>");
	gtk_frame_set_label_widget (GTK_FRAME (frame), label);
	gtk_widget_show (label);

	return frame;
}

static void
pgd_movie_view_play_movie (GtkWidget    *button,
			   PopplerMovie *movie)
{
	const gchar *filename;
	GFile       *file;
	gchar       *uri;

	filename = poppler_movie_get_filename (movie);
	if (g_path_is_absolute (filename)) {
		file = g_file_new_for_path (filename);
	} else if (g_strrstr (filename, "://")) {
		file = g_file_new_for_uri (filename);
	} else {
		gchar *cwd;
		gchar *path;

		// FIXME: relative to doc uri, not cwd
		cwd = g_get_current_dir ();
		path = g_build_filename (cwd, filename, NULL);
		g_free (cwd);

		file = g_file_new_for_path (path);
		g_free (path);
	}

	uri = g_file_get_uri (file);
	g_object_unref (file);
	if (uri) {
#if GTK_CHECK_VERSION(3, 22, 0)
		GtkWidget *toplevel;

		toplevel = gtk_widget_get_toplevel (button);
		gtk_show_uri_on_window (gtk_widget_is_toplevel (toplevel) ? GTK_WINDOW (toplevel) : NULL,
		uri, GDK_CURRENT_TIME, NULL);
#else
		gtk_show_uri (gtk_widget_get_screen (button),
			      uri, GDK_CURRENT_TIME, NULL);
#endif
		g_free (uri);
	}
}

void
pgd_movie_view_set_movie (GtkWidget    *movie_view,
			  PopplerMovie *movie)
{
	GtkWidget  *table;
	GtkWidget  *button;
        GEnumValue *enum_value;
	gint        row = 0;

	table = gtk_bin_get_child (GTK_BIN (movie_view));
	if (table) {
		gtk_container_remove (GTK_CONTAINER (movie_view), table);
	}

	if (!movie)
		return;

	table = gtk_grid_new ();
	gtk_widget_set_margin_top (table, 5);
	gtk_widget_set_margin_bottom (table, 5);
#if GTK_CHECK_VERSION(3, 12, 0)
	gtk_widget_set_margin_start (table, 12);
	gtk_widget_set_margin_end (table, 5);
#else
	gtk_widget_set_margin_left (table, 12);
	gtk_widget_set_margin_right (table, 5);
#endif
	gtk_grid_set_column_spacing (GTK_GRID (table), 6);
	gtk_grid_set_row_spacing (GTK_GRID (table), 6);

	pgd_table_add_property (GTK_GRID (table), "<b>Filename:</b>", poppler_movie_get_filename (movie), &row);
	pgd_table_add_property (GTK_GRID (table), "<b>Need Poster:</b>", poppler_movie_need_poster (movie) ? "Yes" : "No", &row);
	pgd_table_add_property (GTK_GRID (table), "<b>Show Controls:</b>", poppler_movie_show_controls (movie) ? "Yes" : "No", &row);
        enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (POPPLER_TYPE_MOVIE_PLAY_MODE), poppler_movie_get_play_mode (movie));
        pgd_table_add_property (GTK_GRID (table), "<b>Play mode:</b>", enum_value->value_name, &row);

	button = gtk_button_new_with_mnemonic ("_Play");
	g_signal_connect (button, "clicked",
			  G_CALLBACK (pgd_movie_view_play_movie),
			  movie);
	pgd_table_add_property_with_custom_widget (GTK_GRID (table), NULL, button, &row);
	gtk_widget_show (button);

	gtk_container_add (GTK_CONTAINER (movie_view), table);
	gtk_widget_show (table);
}

GdkPixbuf *
pgd_pixbuf_new_for_color (PopplerColor *poppler_color)
{
        GdkPixbuf *pixbuf;
	gint num, x;
	guchar *pixels;

        if (!poppler_color)
                return NULL;

        pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
                                 FALSE, 8,
                                 64, 16);

	pixels = gdk_pixbuf_get_pixels (pixbuf);
	num = gdk_pixbuf_get_width (pixbuf) * gdk_pixbuf_get_height (pixbuf);

	for (x = 0; x < num; x++) {
                pixels[0] = poppler_color->red;
                pixels[1] = poppler_color->green;
                pixels[2] = poppler_color->blue;
                pixels += 3;
	}

        return pixbuf;
}
