/*
 * Copyright (C) 2009-2010, Pino Toscano <pino@kde.org>
 * Copyright (C) 2017-2020, Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2017, Jason Alan Palmer <jalanpalmer@gmail.com>
 * Copyright (C) 2018, 2020, Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
 * Copyright (C) 2018, 2020, Adam Reichold <adam.reichold@t-online.de>
 * Copyright (C) 2018, Zsombor Hollay-Horvath <hollay.horvath@gmail.com>
 * Copyright (C) 2018, Aleksey Nikolaev <nae202@gmail.com>
 * Copyright (C) 2020, Jiri Jakes <freedesktop@jirijakes.eu>
 *
 * 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.
 */

/**
 \file poppler-page.h
 */
#include "poppler-page.h"
#include "poppler-page-transition.h"

#include "poppler-document-private.h"
#include "poppler-page-private.h"
#include "poppler-private.h"
#include "poppler-font-private.h"
#include "poppler-font.h"

#include "TextOutputDev.h"

#include <algorithm>
#include <memory>
#include <utility>

using namespace poppler;

page_private::page_private(document_private *_doc, int _index) : doc(_doc), page(doc->doc->getCatalog()->getPage(_index + 1)), index(_index), transition(nullptr), font_info_cache_initialized(false) { }

page_private::~page_private()
{
    delete transition;
}

void page_private::init_font_info_cache()
{
    if (font_info_cache_initialized) {
        return;
    }

    poppler::font_iterator it(index, doc);

    if (it.has_next()) {
        font_info_cache = it.next();
    }

    font_info_cache_initialized = true;
    return;
}

/**
 \class poppler::page poppler-page.h "poppler/cpp/poppler-page.h"

 A page in a PDF %document.
 */

/**
 \enum poppler::page::orientation_enum

 The possible orientation of a page.
*/

/**
 \enum poppler::page::search_direction_enum

 The direction/action to follow when performing a text search.
*/

/**
 \enum poppler::page::text_layout_enum

 A layout of the text of a page.
*/

page::page(document_private *doc, int index) : d(new page_private(doc, index)) { }

/**
 Destructor.
 */
page::~page()
{
    delete d;
}

/**
 \returns the orientation of the page
 */
page::orientation_enum page::orientation() const
{
    const int rotation = d->page->getRotate();
    switch (rotation) {
    case 90:
        return landscape;
        break;
    case 180:
        return upside_down;
        break;
    case 270:
        return seascape;
        break;
    default:
        return portrait;
    }
}

/**
 The eventual duration the page can be hinted to be shown in a presentation.

 If this value is positive (usually different than -1) then a PDF viewer, when
 showing the page in a presentation, should show the page for at most for this
 number of seconds, and then switch to the next page (if any). Note this is
 purely a presentation attribute, it has no influence on the behaviour.

 \returns the duration time (in seconds) of the page
 */
double page::duration() const
{
    return d->page->getDuration();
}

/**
 Returns the size of one rect of the page.

 \returns the size of the specified page rect
 */
rectf page::page_rect(page_box_enum box) const
{
    const PDFRectangle *r = nullptr;
    switch (box) {
    case media_box:
        r = d->page->getMediaBox();
        break;
    case crop_box:
        r = d->page->getCropBox();
        break;
    case bleed_box:
        r = d->page->getBleedBox();
        break;
    case trim_box:
        r = d->page->getTrimBox();
        break;
    case art_box:
        r = d->page->getArtBox();
        break;
    }
    if (r) {
        return detail::pdfrectangle_to_rectf(*r);
    }
    return rectf();
}

/**
 \returns the label of the page, if any
 */
ustring page::label() const
{
    GooString goo;
    if (!d->doc->doc->getCatalog()->indexToLabel(d->index, &goo)) {
        return ustring();
    }

    return detail::unicode_GooString_to_ustring(&goo);
}

/**
 The transition from this page to the next one.

 If it is set, then a PDF viewer in a presentation should perform the
 specified transition effect when switching from this page to the next one.

 \returns the transition effect for the switch to the next page, if any
 */
page_transition *page::transition() const
{
    if (!d->transition) {
        Object o = d->page->getTrans();
        if (o.isDict()) {
            d->transition = new page_transition(&o);
        }
    }
    return d->transition;
}

/**
 Search the page for some text.

 \param text the text to search
 \param[in,out] r the area where to start search, which will be set to the area
                  of the match (if any)
 \param direction in which direction search for text
 \param case_sensitivity whether search in a case sensitive way
 \param rotation the rotation assumed for the page
 */
bool page::search(const ustring &text, rectf &r, search_direction_enum direction, case_sensitivity_enum case_sensitivity, rotation_enum rotation) const
{
    const size_t len = text.length();

    if (len == 0) {
        return false;
    }

    std::vector<Unicode> u(len);
    for (size_t i = 0; i < len; ++i) {
        u[i] = text[i];
    }

    const bool sCase = case_sensitivity == case_sensitive;
    const int rotation_value = (int)rotation * 90;

    bool found = false;
    double rect_left = r.left();
    double rect_top = r.top();
    double rect_right = r.right();
    double rect_bottom = r.bottom();

    TextOutputDev td(nullptr, true, 0, false, false);
    d->doc->doc->displayPage(&td, d->index + 1, 72, 72, rotation_value, false, true, false);
    TextPage *text_page = td.takeText();

    switch (direction) {
    case search_from_top:
        found = text_page->findText(&u[0], len, true, true, false, false, sCase, false, false, &rect_left, &rect_top, &rect_right, &rect_bottom);
        break;
    case search_next_result:
        found = text_page->findText(&u[0], len, false, true, true, false, sCase, false, false, &rect_left, &rect_top, &rect_right, &rect_bottom);
        break;
    case search_previous_result:
        found = text_page->findText(&u[0], len, false, true, true, false, sCase, true, false, &rect_left, &rect_top, &rect_right, &rect_bottom);
        break;
    }

    text_page->decRefCnt();
    r.set_left(rect_left);
    r.set_top(rect_top);
    r.set_right(rect_right);
    r.set_bottom(rect_bottom);

    return found;
}

/**
 Returns the text in the page, in its physical layout.

 \param r if not empty, it will be extracted the text in it; otherwise, the
          text of the whole page

 \returns the text of the page in the specified rect or in the whole page
 */
ustring page::text(const rectf &r) const
{
    return text(r, physical_layout);
}

static void appendToGooString(void *stream, const char *text, int len)
{
    ((GooString *)stream)->append(text, len);
}

/**
 Returns the text in the page.

 \param rect if not empty, it will be extracted the text in it; otherwise, the
             text of the whole page
 \param layout_mode the layout of the text

 \returns the text of the page in the specified rect or in the whole page

 \since 0.16
 */
ustring page::text(const rectf &r, text_layout_enum layout_mode) const
{
    std::unique_ptr<GooString> out(new GooString());
    const bool use_raw_order = (layout_mode == raw_order_layout);
    const bool use_physical_layout = (layout_mode == physical_layout);
    TextOutputDev td(&appendToGooString, out.get(), use_physical_layout, 0, use_raw_order, false);
    if (r.is_empty()) {
        d->doc->doc->displayPage(&td, d->index + 1, 72, 72, 0, false, true, false);
    } else {
        d->doc->doc->displayPageSlice(&td, d->index + 1, 72, 72, 0, false, true, false, r.left(), r.top(), r.width(), r.height());
    }
    return ustring::from_utf8(out->c_str());
}

/*
 * text_box_font_info object for text_box
 */
text_box_font_info_data::~text_box_font_info_data() = default;

/*
 * text_box object for page::text_list()
 */
text_box_data::~text_box_data() = default;

text_box::~text_box() = default;

text_box &text_box::operator=(text_box &&a) noexcept = default;
text_box::text_box(text_box &&a) noexcept = default;

text_box::text_box(text_box_data *data) : m_data { data } { }

ustring text_box::text() const
{
    return m_data->text;
}

rectf text_box::bbox() const
{
    return m_data->bbox;
}

int text_box::rotation() const
{
    return m_data->rotation;
}

rectf text_box::char_bbox(size_t i) const
{
    if (i < m_data->char_bboxes.size()) {
        return m_data->char_bboxes[i];
    }
    return rectf(0, 0, 0, 0);
}

bool text_box::has_space_after() const
{
    return m_data->has_space_after;
}

bool text_box::has_font_info() const
{
    return (m_data->text_box_font != nullptr);
}

text_box::writing_mode_enum text_box::get_wmode(int i) const
{
    if (this->has_font_info()) {
        return m_data->text_box_font->wmodes[i];
    } else {
        return text_box::invalid_wmode;
    }
}

double text_box::get_font_size() const
{
    if (this->has_font_info()) {
        return m_data->text_box_font->font_size;
    } else {
        return -1;
    }
}

std::string text_box::get_font_name(int i) const
{
    if (!this->has_font_info()) {
        return std::string("*ignored*");
    }

    int j = m_data->text_box_font->glyph_to_cache_index[i];
    if (j < 0) {
        return std::string("");
    }
    return m_data->text_box_font->font_info_cache[j].name();
}

std::vector<text_box> page::text_list(int opt_flag) const
{
    std::vector<text_box> output_list;

    /* config values are same with Qt5 Page::TextList() */
    auto output_dev = std::make_unique<TextOutputDev>(nullptr, /* char* fileName */
                                                      false, /* bool physLayoutA */
                                                      0, /* double fixedPitchA */
                                                      false, /* bool rawOrderA */
                                                      false /* bool append */
    );

    /*
     * config values are same with Qt5 Page::TextList(),
     * but rotation is fixed to zero.
     * Few people use non-zero values.
     */
    d->doc->doc->displayPageSlice(output_dev.get(), d->index + 1, /* page */
                                  72, 72, 0, /* hDPI, vDPI, rot */
                                  false, false, false, /* useMediaBox, crop, printing */
                                  -1, -1, -1, -1, /* sliceX, sliceY, sliceW, sliceH */
                                  nullptr, nullptr, /* abortCheckCbk(), abortCheckCbkData */
                                  nullptr, nullptr, /* annotDisplayDecideCbk(), annotDisplayDecideCbkData */
                                  true); /* copyXRef */

    if (std::unique_ptr<TextWordList> word_list { output_dev->makeWordList() }) {

        output_list.reserve(word_list->getLength());
        for (int i = 0; i < word_list->getLength(); i++) {
            TextWord *word = word_list->get(i);

            std::unique_ptr<GooString> gooWord { word->getText() };
            ustring ustr = ustring::from_utf8(gooWord->c_str());

            double xMin, yMin, xMax, yMax;
            word->getBBox(&xMin, &yMin, &xMax, &yMax);

            text_box tb { new text_box_data { ustr, { xMin, yMin, xMax - xMin, yMax - yMin }, word->getRotation(), {}, word->hasSpaceAfter() == true, nullptr } };

            std::unique_ptr<text_box_font_info_data> tb_font_info = nullptr;
            if (opt_flag & page::text_list_include_font) {
                d->init_font_info_cache();

                std::unique_ptr<text_box_font_info_data> tb_font { new text_box_font_info_data {
                        word->getFontSize(), // double font_size
                        {}, // std::vector<text_box::writing_mode> wmodes;
                        d->font_info_cache, // std::vector<font_info> font_info_cache;
                        {} // std::vector<int> glyph_to_cache_index;
                } };

                tb_font_info = std::move(tb_font);
            };

            tb.m_data->char_bboxes.reserve(word->getLength());
            for (int j = 0; j < word->getLength(); j++) {
                word->getCharBBox(j, &xMin, &yMin, &xMax, &yMax);
                tb.m_data->char_bboxes.emplace_back(xMin, yMin, xMax - xMin, yMax - yMin);
            }

            if (tb_font_info && d->font_info_cache_initialized) {
                tb_font_info->glyph_to_cache_index.reserve(word->getLength());
                for (int j = 0; j < word->getLength(); j++) {
                    const TextFontInfo *cur_text_font_info = word->getFontInfo(j);

                    // filter-out the invalid WMode value here.
                    switch (cur_text_font_info->getWMode()) {
                    case 0:
                        tb_font_info->wmodes.push_back(text_box::horizontal_wmode);
                        break;
                    case 1:
                        tb_font_info->wmodes.push_back(text_box::vertical_wmode);
                        break;
                    default:
                        tb_font_info->wmodes.push_back(text_box::invalid_wmode);
                    };

                    tb_font_info->glyph_to_cache_index.push_back(-1);
                    for (size_t k = 0; k < tb_font_info->font_info_cache.size(); k++) {
                        if (cur_text_font_info->matches(&(tb_font_info->font_info_cache[k].d->ref))) {
                            tb_font_info->glyph_to_cache_index[j] = k;
                            break;
                        }
                    }
                }
                tb.m_data->text_box_font = std::move(tb_font_info);
            }

            output_list.push_back(std::move(tb));
        }
    }

    return output_list;
}

std::vector<text_box> page::text_list() const
{
    return text_list(0);
}
