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

enum
{
    TITLE_COLUMN,
    X1_COLUMN,
    Y1_COLUMN,
    X2_COLUMN,
    Y2_COLUMN,

    VISIBLE_COLUMN,
    PAGE_COLUMN,
    PAGE_RECT,
    N_COLUMNS
};

typedef struct
{
    PopplerDocument *doc;

    GtkWidget *treeview;
    GtkWidget *darea;
    GtkWidget *entry;
    GtkWidget *progress;

    PopplerFindFlags options;
    gint n_pages;
    gint page_index;

    guint idle_id;

    cairo_surface_t *surface;
    gint selected_page;
    GdkRectangle selected_match;
} PgdFindDemo;

static void pgd_find_free(PgdFindDemo *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;
    }

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

    g_free(demo);
}

static void pgd_find_update_progress(PgdFindDemo *demo, gint scanned)
{
    gchar *str;

    str = g_strdup_printf("Searching ... (%d%%)", MIN(scanned * 100 / demo->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 / demo->n_pages, 1.0));
    g_free(str);
}

static void pgd_find_append_match(PgdFindDemo *demo, GtkTreeModel *model, GtkTreeIter *iter_child, PopplerRectangle *rect, int match_id)
{
    char *x1, *y1, *x2, *y2, *str;
    str = g_strdup_printf("Match %d", match_id + 1);
    x1 = g_strdup_printf("%.2f", rect->x1);
    y1 = g_strdup_printf("%.2f", rect->y1);
    x2 = g_strdup_printf("%.2f", rect->x2);
    y2 = g_strdup_printf("%.2f", rect->y2);
    gtk_tree_store_set(GTK_TREE_STORE(model), iter_child, TITLE_COLUMN, str, X1_COLUMN, x1, Y1_COLUMN, y1, X2_COLUMN, x2, Y2_COLUMN, y2, VISIBLE_COLUMN, TRUE, PAGE_COLUMN, demo->page_index, PAGE_RECT, rect, -1);
    g_free(str);
    g_free(x1);
    g_free(y1);
    g_free(x2);
    g_free(y2);
    g_object_weak_ref(G_OBJECT(model), (GWeakNotify)poppler_rectangle_free, rect);
}

static gboolean pgd_find_find_text(PgdFindDemo *demo)
{
    PopplerPage *page;
    GList *matches;
    GTimer *timer;
    GtkTreeModel *model;

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

    model = gtk_tree_view_get_model(GTK_TREE_VIEW(demo->treeview));
    timer = g_timer_new();
    matches = poppler_page_find_text_with_options(page, gtk_entry_get_text(GTK_ENTRY(demo->entry)), demo->options);
    g_timer_stop(timer);
    if (matches) {
        GtkTreeIter iter, iter_child;
        gchar *str;
        GList *l;
        gdouble height;
        gint n_match = 0;

        gtk_tree_store_append(GTK_TREE_STORE(model), &iter, NULL);
        poppler_page_get_size(page, NULL, &height);
        for (l = matches; l && l->data; l = g_list_next(l)) {
            PopplerRectangle *rect = (PopplerRectangle *)l->data;
            gdouble tmp;
            tmp = rect->y1;
            rect->y1 = height - rect->y2;
            rect->y2 = height - tmp;
            gtk_tree_store_append(GTK_TREE_STORE(model), &iter_child, &iter);
            pgd_find_append_match(demo, model, &iter_child, rect, n_match);
            if (!poppler_rectangle_find_get_match_continued(rect)) {
                ++n_match;
            }
        }
        g_list_free(matches);

        str = g_strdup_printf("%d matches found on page %d in %.4f seconds", n_match, demo->page_index + 1, g_timer_elapsed(timer, NULL));

        gtk_tree_store_set(GTK_TREE_STORE(model), &iter, TITLE_COLUMN, str, VISIBLE_COLUMN, FALSE, PAGE_COLUMN, demo->page_index, -1);
        g_free(str);
    }

    g_timer_destroy(timer);
    g_object_unref(page);

    demo->page_index++;
    pgd_find_update_progress(demo, demo->page_index);

    return demo->page_index < demo->n_pages;
}

static void find_text_idle_finish(PgdFindDemo *demo)
{
    demo->idle_id = 0;
}

static cairo_surface_t *pgd_find_render_page(PgdFindDemo *demo)
{
    cairo_t *cr;
    PopplerPage *page;
    gdouble width, height;
    cairo_surface_t *surface = NULL;

    page = poppler_document_get_page(demo->doc, demo->selected_page);
    if (!page) {
        return NULL;
    }

    poppler_page_get_size(page, &width, &height);
    gtk_widget_set_size_request(demo->darea, width, height);

    surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
    cr = cairo_create(surface);

    cairo_save(cr);
    cairo_set_source_rgb(cr, 1, 1, 1);
    cairo_rectangle(cr, 0, 0, width, height);
    cairo_fill(cr);
    cairo_restore(cr);

    cairo_save(cr);
    poppler_page_render(page, cr);
    cairo_restore(cr);

    cairo_destroy(cr);
    g_object_unref(page);

    return surface;
}

static gboolean pgd_find_viewer_drawing_area_draw(GtkWidget *area, cairo_t *cr, PgdFindDemo *demo)
{
    if (demo->selected_page == -1) {
        return FALSE;
    }

    if (!demo->surface) {
        demo->surface = pgd_find_render_page(demo);
        if (!demo->surface) {
            return FALSE;
        }
    }

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

    if (demo->selected_match.width > 0 && demo->selected_match.height > 0) {
        cairo_set_source_rgb(cr, 1., 1., 0.);
        cairo_set_operator(cr, CAIRO_OPERATOR_MULTIPLY);
        gdk_cairo_rectangle(cr, &demo->selected_match);
        cairo_fill(cr);
    }

    return TRUE;
}

static gboolean pgd_find_viewer_redraw(PgdFindDemo *demo)
{
    cairo_surface_destroy(demo->surface);
    demo->surface = NULL;

    gtk_widget_queue_draw(demo->darea);

    return FALSE;
}

static void pgd_find_viewer_queue_redraw(PgdFindDemo *demo)
{
    g_idle_add((GSourceFunc)pgd_find_viewer_redraw, demo);
}

static GtkTreeModel *pgd_find_create_model()
{
    return GTK_TREE_MODEL(gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_POINTER));
}

static void pgd_find_button_clicked(GtkButton *button, PgdFindDemo *demo)
{
    GtkTreeModel *model;

    /* Delete the model and create a new one instead of
     * just clearing it to make sure rectangle are free.
     * This is a workaround because GtkTreeModel doesn't
     * support boxed types and we have to store rectangles
     * as pointers that are freed when the model is deleted.
     */
    model = pgd_find_create_model();
    gtk_tree_view_set_model(GTK_TREE_VIEW(demo->treeview), model);
    g_object_unref(model);

    demo->selected_page = -1;
    pgd_find_viewer_queue_redraw(demo);

    demo->page_index = 0;
    pgd_find_update_progress(demo, demo->page_index);
    if (demo->idle_id > 0) {
        g_source_remove(demo->idle_id);
    }
    demo->idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, (GSourceFunc)pgd_find_find_text, demo, (GDestroyNotify)find_text_idle_finish);
}

static void pgd_find_button_sensitivity_cb(GtkWidget *button, GtkEntry *entry)
{
    const gchar *text;

    text = gtk_entry_get_text(entry);
    gtk_widget_set_sensitive(button, text != NULL && text[0] != '\0');
}

static void pgd_find_selection_changed(GtkTreeSelection *treeselection, PgdFindDemo *demo)
{
    GtkTreeModel *model;
    GtkTreeIter iter;

    if (gtk_tree_selection_get_selected(treeselection, &model, &iter)) {
        guint page_index;
        PopplerRectangle *rect;

        gtk_tree_model_get(model, &iter, PAGE_COLUMN, &page_index, PAGE_RECT, &rect, -1);

        if (rect) {
            demo->selected_match.x = rect->x1;
            demo->selected_match.y = rect->y1;
            demo->selected_match.width = rect->x2 - rect->x1;
            demo->selected_match.height = rect->y2 - rect->y1;
        } else {
            demo->selected_match.width = 0;
            demo->selected_match.height = 0;
        }

        if (page_index != demo->selected_page) {
            demo->selected_page = page_index;
            pgd_find_viewer_queue_redraw(demo);
        } else {
            gtk_widget_queue_draw(demo->darea);
        }
    }
}

static void pgd_find_case_sensitive_toggled(GtkToggleButton *togglebutton, PgdFindDemo *demo)
{
    if (gtk_toggle_button_get_active(togglebutton)) {
        demo->options |= POPPLER_FIND_CASE_SENSITIVE;
    } else {
        demo->options &= ~POPPLER_FIND_CASE_SENSITIVE;
    }
}

static void pgd_find_backwards_toggled(GtkToggleButton *togglebutton, PgdFindDemo *demo)
{
    if (gtk_toggle_button_get_active(togglebutton)) {
        demo->options |= POPPLER_FIND_BACKWARDS;
    } else {
        demo->options &= ~POPPLER_FIND_BACKWARDS;
    }
}

static void pgd_find_multiline_toggled(GtkToggleButton *togglebutton, PgdFindDemo *demo)
{
    if (gtk_toggle_button_get_active(togglebutton)) {
        demo->options |= POPPLER_FIND_MULTILINE;
    } else {
        demo->options &= ~POPPLER_FIND_MULTILINE;
    }
}

static void pgd_find_ignore_diacritics_toggled(GtkToggleButton *togglebutton, PgdFindDemo *demo)
{
    if (gtk_toggle_button_get_active(togglebutton)) {
        demo->options |= POPPLER_FIND_IGNORE_DIACRITICS;
    } else {
        demo->options &= ~POPPLER_FIND_IGNORE_DIACRITICS;
    }
}

static void pgd_find_whole_words_toggled(GtkToggleButton *togglebutton, PgdFindDemo *demo)
{
    if (gtk_toggle_button_get_active(togglebutton)) {
        demo->options |= POPPLER_FIND_WHOLE_WORDS_ONLY;
    } else {
        demo->options &= ~POPPLER_FIND_WHOLE_WORDS_ONLY;
    }
}

GtkWidget *pgd_find_create_widget(PopplerDocument *document)
{
    PgdFindDemo *demo;
    GtkWidget *vbox, *hbox;
    GtkWidget *button;
    GtkWidget *swindow;
    GtkWidget *checkbutton;
    GtkTreeModel *model;
    GtkWidget *treeview;
    GtkCellRenderer *renderer;
    GtkWidget *hpaned;
    GtkTreeSelection *selection;

    demo = g_new0(PgdFindDemo, 1);

    demo->doc = g_object_ref(document);

    demo->n_pages = poppler_document_get_n_pages(document);
    demo->selected_page = -1;
    demo->options = POPPLER_FIND_DEFAULT;

    hpaned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_paned_set_position(GTK_PANED(hpaned), 300);

    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);

    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    checkbutton = gtk_check_button_new_with_label("Multi-line");
    g_signal_connect(checkbutton, "toggled", G_CALLBACK(pgd_find_multiline_toggled), demo);
    gtk_box_pack_start(GTK_BOX(hbox), checkbutton, FALSE, FALSE, 0);
    gtk_widget_show(checkbutton);

    checkbutton = gtk_check_button_new_with_label("Ignore diacritics");
    g_signal_connect(checkbutton, "toggled", G_CALLBACK(pgd_find_ignore_diacritics_toggled), demo);
    gtk_box_pack_start(GTK_BOX(hbox), checkbutton, FALSE, FALSE, 0);
    gtk_widget_show(checkbutton);

    demo->entry = gtk_entry_new();
    gtk_box_pack_start(GTK_BOX(hbox), demo->entry, FALSE, TRUE, 0);
    gtk_widget_show(demo->entry);

    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("Find");
    gtk_widget_set_sensitive(button, FALSE);
    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pgd_find_button_clicked), (gpointer)demo);
    g_signal_connect_swapped(G_OBJECT(demo->entry), "changed", G_CALLBACK(pgd_find_button_sensitivity_cb), (gpointer)button);
    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);

    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);

    checkbutton = gtk_check_button_new_with_label("Case sensitive");
    g_signal_connect(checkbutton, "toggled", G_CALLBACK(pgd_find_case_sensitive_toggled), demo);
    gtk_box_pack_start(GTK_BOX(hbox), checkbutton, FALSE, FALSE, 0);
    gtk_widget_show(checkbutton);

    checkbutton = gtk_check_button_new_with_label("Backwards");
    g_signal_connect(checkbutton, "toggled", G_CALLBACK(pgd_find_backwards_toggled), demo);
    gtk_box_pack_start(GTK_BOX(hbox), checkbutton, FALSE, FALSE, 0);
    gtk_widget_show(checkbutton);

    checkbutton = gtk_check_button_new_with_label("Whole words only");
    g_signal_connect(checkbutton, "toggled", G_CALLBACK(pgd_find_whole_words_toggled), demo);
    gtk_box_pack_start(GTK_BOX(hbox), checkbutton, FALSE, FALSE, 0);
    gtk_widget_show(checkbutton);

    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
    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 = pgd_find_create_model();
    treeview = gtk_tree_view_new_with_model(model);
    g_object_unref(model);
    demo->treeview = treeview;
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
    g_signal_connect(selection, "changed", G_CALLBACK(pgd_find_selection_changed), demo);

    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), TITLE_COLUMN, "Matches", renderer, "text", TITLE_COLUMN, NULL);

    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), X1_COLUMN, "X1", renderer, "text", X1_COLUMN, "visible", VISIBLE_COLUMN, NULL);
    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), Y1_COLUMN, "Y1", renderer, "text", Y1_COLUMN, "visible", VISIBLE_COLUMN, NULL);
    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), X2_COLUMN, "X2", renderer, "text", X2_COLUMN, "visible", VISIBLE_COLUMN, NULL);
    renderer = gtk_cell_renderer_text_new();
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), Y2_COLUMN, "Y2", renderer, "text", Y2_COLUMN, "visible", VISIBLE_COLUMN, NULL);
    gtk_container_add(GTK_CONTAINER(swindow), treeview);
    gtk_widget_show(treeview);

    gtk_paned_add1(GTK_PANED(hpaned), swindow);
    gtk_widget_show(swindow);

    demo->darea = gtk_drawing_area_new();
    g_signal_connect(demo->darea, "draw", G_CALLBACK(pgd_find_viewer_drawing_area_draw), demo);

    swindow = gtk_scrolled_window_new(NULL, NULL);
#if GTK_CHECK_VERSION(3, 7, 8)
    gtk_container_add(GTK_CONTAINER(swindow), demo->darea);
#else
    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swindow), demo->darea);
#endif
    gtk_widget_show(demo->darea);

    gtk_paned_add2(GTK_PANED(hpaned), swindow);
    gtk_widget_show(swindow);

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

    g_object_weak_ref(G_OBJECT(vbox), (GWeakNotify)pgd_find_free, (gpointer)demo);

    return vbox;
}
