/*
 * Copyright (C) 2010 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 "config.h"

#include <gtk/gtk.h>
#include <cairo.h>

#include "selections.h"

typedef struct
{
    PopplerDocument *doc;

    /* Properties */
    gint page_index;
    gdouble scale;

    GtkWidget *swindow;
    GtkWidget *darea;
    GtkWidget *fg_color_button;
    GtkWidget *bg_color_button;
    GtkWidget *copy_button;

    PopplerPage *page;
    cairo_surface_t *surface;

    GdkPoint start;
    GdkPoint stop;
    PopplerRectangle doc_area;
    cairo_surface_t *selection_surface;
    PopplerSelectionStyle style;
    PopplerColor glyph_color;
    PopplerColor background_color;
    guint selections_idle;
    cairo_region_t *selection_region;
    cairo_region_t *selected_region;
    GdkCursorType cursor;
    gchar *selected_text;
} PgdSelectionsDemo;

static void pgd_selections_clear_selections(PgdSelectionsDemo *demo)
{
    demo->start.x = -1;

    if (demo->selection_surface) {
        cairo_surface_destroy(demo->selection_surface);
        demo->selection_surface = NULL;
    }

    if (demo->selection_region) {
        cairo_region_destroy(demo->selection_region);
        demo->selection_region = NULL;
    }

    if (demo->selected_text) {
        g_free(demo->selected_text);
        demo->selected_text = NULL;
    }

    if (demo->selected_region) {
        cairo_region_destroy(demo->selected_region);
        demo->selected_region = NULL;
    }
}

static void pgd_selections_free(PgdSelectionsDemo *demo)
{
    if (!demo) {
        return;
    }

    if (demo->selections_idle > 0) {
        g_source_remove(demo->selections_idle);
        demo->selections_idle = 0;
    }

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

    if (demo->page) {
        g_object_unref(demo->page);
        demo->page = NULL;
    }

    if (demo->surface) {
        cairo_surface_destroy(demo->surface);
        demo->surface = NULL;
    }

    pgd_selections_clear_selections(demo);

    g_free(demo);
}

static void pgd_selections_update_selection_region(PgdSelectionsDemo *demo)
{
    PopplerRectangle area = { 0, 0, 0, 0 };

    if (demo->selection_region) {
        cairo_region_destroy(demo->selection_region);
    }

    poppler_page_get_size(demo->page, &area.x2, &area.y2);
    demo->selection_region = poppler_page_get_selected_region(demo->page, 1.0, POPPLER_SELECTION_GLYPH, &area);
}

static void pgd_selections_update_selected_text(PgdSelectionsDemo *demo)
{
    gchar *text;

    if (demo->selected_region) {
        cairo_region_destroy(demo->selected_region);
    }
    demo->selected_region = poppler_page_get_selected_region(demo->page, 1.0, demo->style, &demo->doc_area);
    if (demo->selected_text) {
        g_free(demo->selected_text);
    }
    demo->selected_text = NULL;

    text = poppler_page_get_selected_text(demo->page, demo->style, &demo->doc_area);
    if (text) {
        /* For copying text from the document to the clipboard, we want a normalization
         * that preserves 'canonical equivalence' i.e. that text after normalization
         * is not visually different than the original text. Issue #724 */
        demo->selected_text = g_utf8_normalize(text, -1, G_NORMALIZE_NFC);
        g_free(text);
        gtk_widget_set_sensitive(demo->copy_button, TRUE);
    }
}

static void pgd_selections_update_cursor(PgdSelectionsDemo *demo, GdkCursorType cursor_type)
{
    GdkWindow *window = gtk_widget_get_window(demo->darea);
    GdkCursor *cursor = NULL;

    if (cursor_type == demo->cursor) {
        return;
    }

    if (cursor_type != GDK_LAST_CURSOR) {
        cursor = gdk_cursor_new_for_display(gtk_widget_get_display(demo->darea), cursor_type);
    }

    demo->cursor = cursor_type;

    gdk_window_set_cursor(window, cursor);
    gdk_display_flush(gtk_widget_get_display(demo->darea));
    if (cursor) {
        g_object_unref(cursor);
    }
}

static gboolean pgd_selections_render_selections(PgdSelectionsDemo *demo)
{
    PopplerRectangle doc_area;
    gdouble page_width, page_height;
    cairo_t *cr;

    if (!demo->page || demo->start.x == -1) {
        demo->selections_idle = 0;

        return FALSE;
    }

    poppler_page_get_size(demo->page, &page_width, &page_height);
    page_width *= demo->scale;
    page_height *= demo->scale;

    doc_area.x1 = demo->start.x / demo->scale;
    doc_area.y1 = demo->start.y / demo->scale;
    doc_area.x2 = demo->stop.x / demo->scale;
    doc_area.y2 = demo->stop.y / demo->scale;

    if (demo->selection_surface) {
        cairo_surface_destroy(demo->selection_surface);
    }
    demo->selection_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, page_width, page_height);
    cr = cairo_create(demo->selection_surface);
    if (demo->scale != 1.0) {
        cairo_scale(cr, demo->scale, demo->scale);
    }
    poppler_page_render_selection(demo->page, cr, &doc_area, &demo->doc_area, demo->style, &demo->glyph_color, &demo->background_color);
    cairo_destroy(cr);

    demo->doc_area = doc_area;
    gtk_widget_queue_draw(demo->darea);

    demo->selections_idle = 0;

    return FALSE;
}

static gboolean pgd_selections_drawing_area_draw(GtkWidget *area, cairo_t *cr, PgdSelectionsDemo *demo)
{
    if (!demo->surface) {
        return FALSE;
    }

    cairo_save(cr);
    cairo_set_source_surface(cr, demo->surface, 0, 0);
    cairo_paint(cr);
    cairo_restore(cr);

    if (demo->selection_surface) {
        cairo_set_source_surface(cr, demo->selection_surface, 0, 0);
        cairo_paint(cr);
    }

    return TRUE;
}

static gboolean pgd_selections_drawing_area_button_press(GtkWidget *area, GdkEventButton *event, PgdSelectionsDemo *demo)
{
    if (!demo->page) {
        return FALSE;
    }

    if (event->button != 1) {
        return FALSE;
    }

    demo->start.x = event->x;
    demo->start.y = event->y;
    demo->stop = demo->start;

    switch (event->type) {
    case GDK_2BUTTON_PRESS:
        demo->style = POPPLER_SELECTION_WORD;
        break;
    case GDK_3BUTTON_PRESS:
        demo->style = POPPLER_SELECTION_LINE;
        break;
    default:
        demo->style = POPPLER_SELECTION_GLYPH;
    }

    pgd_selections_render_selections(demo);

    return TRUE;
}

static gboolean pgd_selections_drawing_area_motion_notify(GtkWidget *area, GdkEventMotion *event, PgdSelectionsDemo *demo)
{
    if (!demo->page) {
        return FALSE;
    }

    if (demo->start.x != -1) {
        demo->stop.x = event->x;
        demo->stop.y = event->y;
        if (demo->selections_idle == 0) {
            demo->selections_idle = g_idle_add((GSourceFunc)pgd_selections_render_selections, demo);
        }
    } else {
        gboolean over_text;

        over_text = cairo_region_contains_point(demo->selection_region, event->x / demo->scale, event->y / demo->scale);
        pgd_selections_update_cursor(demo, over_text ? GDK_XTERM : GDK_LAST_CURSOR);
    }

    return TRUE;
}

static gboolean pgd_selections_drawing_area_button_release(GtkWidget *area, GdkEventButton *event, PgdSelectionsDemo *demo)
{
    if (!demo->page) {
        return FALSE;
    }

    if (event->button != 1) {
        return FALSE;
    }

    if (demo->start.x != -1) {
        pgd_selections_update_selected_text(demo);
    }

    demo->start.x = -1;

    if (demo->selections_idle > 0) {
        g_source_remove(demo->selections_idle);
        demo->selections_idle = 0;
    }

    return TRUE;
}

static void pgd_selections_drawing_area_realize(GtkWidget *area, PgdSelectionsDemo *demo)
{
    GtkStyleContext *style_context = gtk_widget_get_style_context(area);
    GdkRGBA rgba;

    gtk_widget_add_events(area, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
    g_object_set(area, "has-tooltip", TRUE, NULL);

    gtk_style_context_get_color(style_context, GTK_STATE_FLAG_SELECTED, &rgba);
    gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(demo->fg_color_button), &rgba);
    gtk_style_context_get(style_context, GTK_STATE_FLAG_SELECTED, "background-color", &rgba, NULL);
    gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(demo->bg_color_button), &rgba);
}

static gboolean pgd_selections_drawing_area_query_tooltip(GtkWidget *area, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, PgdSelectionsDemo *demo)
{
    gboolean over_selection;

    if (!demo->selected_text) {
        return FALSE;
    }

    over_selection = cairo_region_contains_point(demo->selected_region, x / demo->scale, y / demo->scale);

    if (over_selection) {
        GdkRectangle selection_area;

        cairo_region_get_extents(demo->selected_region, (cairo_rectangle_int_t *)&selection_area);
        selection_area.x *= demo->scale;
        selection_area.y *= demo->scale;
        selection_area.width *= demo->scale;
        selection_area.height *= demo->scale;

        gtk_tooltip_set_text(tooltip, demo->selected_text);
        gtk_tooltip_set_tip_area(tooltip, &selection_area);

        return TRUE;
    }

    return FALSE;
}

static void pgd_selections_render(GtkButton *button, PgdSelectionsDemo *demo)
{
    gdouble page_width, page_height;
    cairo_t *cr;

    if (!demo->page) {
        demo->page = poppler_document_get_page(demo->doc, demo->page_index);
    }

    if (!demo->page) {
        return;
    }

    pgd_selections_clear_selections(demo);
    pgd_selections_update_selection_region(demo);
    gtk_widget_set_sensitive(demo->copy_button, FALSE);

    if (demo->surface) {
        cairo_surface_destroy(demo->surface);
    }
    demo->surface = NULL;

    poppler_page_get_size(demo->page, &page_width, &page_height);
    page_width *= demo->scale;
    page_height *= demo->scale;

    demo->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, page_width, page_height);
    cr = cairo_create(demo->surface);

    cairo_save(cr);

    if (demo->scale != 1.0) {
        cairo_scale(cr, demo->scale, demo->scale);
    }

    poppler_page_render(demo->page, cr);
    cairo_restore(cr);

    cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER);
    cairo_set_source_rgb(cr, 1., 1., 1.);
    cairo_paint(cr);

    cairo_destroy(cr);

    gtk_widget_set_size_request(demo->darea, page_width, page_height);
    gtk_widget_queue_draw(demo->darea);
}

static void pgd_selections_copy(GtkButton *button, PgdSelectionsDemo *demo)
{
    GtkClipboard *clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(), GDK_SELECTION_CLIPBOARD);
    gtk_clipboard_set_text(clipboard, demo->selected_text, -1);
}

static void pgd_selections_page_selector_value_changed(GtkSpinButton *spinbutton, PgdSelectionsDemo *demo)
{
    demo->page_index = (gint)gtk_spin_button_get_value(spinbutton) - 1;
    if (demo->page) {
        g_object_unref(demo->page);
    }
    demo->page = NULL;
}

static void pgd_selections_scale_selector_value_changed(GtkSpinButton *spinbutton, PgdSelectionsDemo *demo)
{
    demo->scale = gtk_spin_button_get_value(spinbutton);
}

static void pgd_selections_fg_color_changed(GtkColorButton *button, GParamSpec *pspec, PgdSelectionsDemo *demo)
{
    GdkRGBA color;

    gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(button), &color);
    demo->glyph_color.red = CLAMP((guint)(color.red * 65535), 0, 65535);
    demo->glyph_color.green = CLAMP((guint)(color.green * 65535), 0, 65535);
    demo->glyph_color.blue = CLAMP((guint)(color.blue * 65535), 0, 65535);
}

static void pgd_selections_bg_color_changed(GtkColorButton *button, GParamSpec *pspec, PgdSelectionsDemo *demo)
{
    GdkRGBA color;

    gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(button), &color);
    demo->background_color.red = CLAMP((guint)(color.red * 65535), 0, 65535);
    demo->background_color.green = CLAMP((guint)(color.green * 65535), 0, 65535);
    demo->background_color.blue = CLAMP((guint)(color.blue * 65535), 0, 65535);
}

GtkWidget *pgd_selections_properties_selector_create(PgdSelectionsDemo *demo)
{
    GtkWidget *hbox, *vbox;
    GtkWidget *label;
    GtkWidget *page_hbox, *page_selector;
    GtkWidget *scale_hbox, *scale_selector;
    GtkWidget *rotate_hbox, *rotate_selector;
    GtkWidget *color_hbox;
    GtkWidget *button;
    gint n_pages;
    gchar *str;

    n_pages = poppler_document_get_n_pages(demo->doc);

    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);

    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
    gtk_widget_show(hbox);

    page_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    label = gtk_label_new("Page:");
    gtk_box_pack_start(GTK_BOX(page_hbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);

    page_selector = gtk_spin_button_new_with_range(1, n_pages, 1);
    g_signal_connect(G_OBJECT(page_selector), "value-changed", G_CALLBACK(pgd_selections_page_selector_value_changed), (gpointer)demo);
    gtk_box_pack_start(GTK_BOX(page_hbox), page_selector, TRUE, TRUE, 0);
    gtk_widget_show(page_selector);

    str = g_strdup_printf("of %d", n_pages);
    label = gtk_label_new(str);
    gtk_box_pack_start(GTK_BOX(page_hbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);
    g_free(str);

    gtk_box_pack_start(GTK_BOX(hbox), page_hbox, FALSE, TRUE, 0);
    gtk_widget_show(page_hbox);

    scale_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    label = gtk_label_new("Scale:");
    gtk_box_pack_start(GTK_BOX(scale_hbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);

    scale_selector = gtk_spin_button_new_with_range(0, 10.0, 0.1);
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(scale_selector), 1.0);
    g_signal_connect(G_OBJECT(scale_selector), "value-changed", G_CALLBACK(pgd_selections_scale_selector_value_changed), (gpointer)demo);
    gtk_box_pack_start(GTK_BOX(scale_hbox), scale_selector, TRUE, TRUE, 0);
    gtk_widget_show(scale_selector);

    gtk_box_pack_start(GTK_BOX(hbox), scale_hbox, FALSE, TRUE, 0);
    gtk_widget_show(scale_hbox);

    rotate_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    label = gtk_label_new("Rotate:");
    gtk_box_pack_start(GTK_BOX(rotate_hbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);

    rotate_selector = gtk_combo_box_text_new();
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rotate_selector), "0");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rotate_selector), "90");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rotate_selector), "180");
    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(rotate_selector), "270");
    gtk_combo_box_set_active(GTK_COMBO_BOX(rotate_selector), 0);
#if 0
	g_signal_connect (G_OBJECT (rotate_selector), "changed",
			  G_CALLBACK (pgd_selections_rotate_selector_changed),
			  (gpointer)demo);
#endif
    gtk_box_pack_start(GTK_BOX(rotate_hbox), rotate_selector, TRUE, TRUE, 0);
    gtk_widget_show(rotate_selector);

    gtk_box_pack_start(GTK_BOX(hbox), rotate_hbox, FALSE, TRUE, 0);
    gtk_widget_show(rotate_hbox);

    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
    gtk_widget_show(hbox);

    color_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    label = gtk_label_new("Foreground Color:");
    gtk_box_pack_start(GTK_BOX(color_hbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);

    demo->fg_color_button = gtk_color_button_new();
    g_signal_connect(demo->fg_color_button, "notify::color", G_CALLBACK(pgd_selections_fg_color_changed), (gpointer)demo);
    gtk_box_pack_start(GTK_BOX(color_hbox), demo->fg_color_button, TRUE, TRUE, 0);
    gtk_widget_show(demo->fg_color_button);

    gtk_box_pack_start(GTK_BOX(hbox), color_hbox, FALSE, TRUE, 0);
    gtk_widget_show(color_hbox);

    color_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    label = gtk_label_new("Background Color:");
    gtk_box_pack_start(GTK_BOX(color_hbox), label, TRUE, TRUE, 0);
    gtk_widget_show(label);

    demo->bg_color_button = gtk_color_button_new();
    g_signal_connect(demo->bg_color_button, "notify::color", G_CALLBACK(pgd_selections_bg_color_changed), (gpointer)demo);
    gtk_box_pack_start(GTK_BOX(color_hbox), demo->bg_color_button, TRUE, TRUE, 0);
    gtk_widget_show(demo->bg_color_button);

    gtk_box_pack_start(GTK_BOX(hbox), color_hbox, FALSE, TRUE, 0);
    gtk_widget_show(color_hbox);

    demo->copy_button = gtk_button_new_with_label("Copy");
    g_signal_connect(G_OBJECT(demo->copy_button), "clicked", G_CALLBACK(pgd_selections_copy), (gpointer)demo);
    gtk_box_pack_end(GTK_BOX(hbox), demo->copy_button, FALSE, TRUE, 0);
    gtk_widget_set_sensitive(demo->copy_button, FALSE);
    gtk_widget_show(demo->copy_button);

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

    return vbox;
}

GtkWidget *pgd_selections_create_widget(PopplerDocument *document)
{
    PgdSelectionsDemo *demo;
    GtkWidget *vbox, *hbox;

    demo = g_new0(PgdSelectionsDemo, 1);

    demo->doc = g_object_ref(document);
    demo->scale = 1.0;
    demo->cursor = GDK_LAST_CURSOR;

    pgd_selections_clear_selections(demo);

    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);

    hbox = pgd_selections_properties_selector_create(demo);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 6);
    gtk_widget_show(hbox);

    demo->darea = gtk_drawing_area_new();
    g_signal_connect(demo->darea, "realize", G_CALLBACK(pgd_selections_drawing_area_realize), (gpointer)demo);
    g_signal_connect(demo->darea, "draw", G_CALLBACK(pgd_selections_drawing_area_draw), (gpointer)demo);
    g_signal_connect(demo->darea, "button_press_event", G_CALLBACK(pgd_selections_drawing_area_button_press), (gpointer)demo);
    g_signal_connect(demo->darea, "motion_notify_event", G_CALLBACK(pgd_selections_drawing_area_motion_notify), (gpointer)demo);
    g_signal_connect(demo->darea, "button_release_event", G_CALLBACK(pgd_selections_drawing_area_button_release), (gpointer)demo);
    g_signal_connect(demo->darea, "query_tooltip", G_CALLBACK(pgd_selections_drawing_area_query_tooltip), (gpointer)demo);
    demo->swindow = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(demo->swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION(3, 7, 8)
    gtk_container_add(GTK_CONTAINER(demo->swindow), demo->darea);
#else
    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(demo->swindow), demo->darea);
#endif
    gtk_widget_show(demo->darea);

    gtk_box_pack_start(GTK_BOX(vbox), demo->swindow, TRUE, TRUE, 0);
    gtk_widget_show(demo->swindow);

    g_object_weak_ref(G_OBJECT(demo->swindow), (GWeakNotify)pgd_selections_free, (gpointer)demo);

    return vbox;
}
