/*
 * Copyright (C) 2009, Pino Toscano <pino@kde.org>
 * Copyright (C) 2015, Tamas Szekeres <szekerest@gmail.com>
 * Copyright (C) 2018, Adam Reichold <adam.reichold@t-online.de>
 *
 * 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-font.h
 */
#include "poppler-font.h"

#include "poppler-document-private.h"

#include "FontInfo.h"

#include <algorithm>

using namespace poppler;

class poppler::font_info_private
{
public:
    font_info_private()
        : type(font_info::unknown)
        , is_embedded(false)
        , is_subset(false)
    {
    }
    font_info_private(FontInfo *fi)
        : type((font_info::type_enum)fi->getType())
        , is_embedded(fi->getEmbedded())
        , is_subset(fi->getSubset())
    {
        if (fi->getName()) {
            font_name = fi->getName()->c_str();
        }
        if (fi->getFile()) {
            font_file = fi->getFile()->c_str();
        }
    }

    std::string font_name;
    std::string font_file;
    font_info::type_enum type : 5;
    bool is_embedded : 1;
    bool is_subset : 1;
};


class poppler::font_iterator_private
{
public:
    font_iterator_private(int start_page, document_private *dd)
        : font_info_scanner(dd->doc, start_page)
        , total_pages(dd->doc->getNumPages())
        , current_page((std::max)(start_page, 0))
    {
    }
    ~font_iterator_private()
    {
    }

    FontInfoScanner font_info_scanner;
    int total_pages;
    int current_page;
};

/**
 \class poppler::font_info poppler-font.h "poppler/cpp/poppler-font.h"

 The information about a font used in a PDF %document.
 */

/**
 \enum poppler::font_info::type_enum

 The various types of fonts available in a PDF %document.
*/


/**
 Constructs an invalid font information.
 */
font_info::font_info()
    : d(new font_info_private())
{
}

font_info::font_info(font_info_private &dd)
    : d(&dd)
{
}

/**
 Copy constructor.
 */
font_info::font_info(const font_info &fi)
    : d(new font_info_private(*fi.d))
{
}

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

/**
 \returns the name of the font
 */
std::string font_info::name() const
{
    return d->font_name;
}

/**
 \returns the file name of the font, in case the font is not embedded nor subset
 */
std::string font_info::file() const
{
    return d->font_file;
}

/**
 \returns whether the font is totally embedded in the %document
 */
bool font_info::is_embedded() const
{
    return d->is_embedded;
}

/**
 \returns whether there is a subset of the font embedded in the %document
 */
bool font_info::is_subset() const
{
    return d->is_subset;
}

/**
 \returns the type of the font
 */
font_info::type_enum font_info::type() const
{
    return d->type;
}

/**
 Assignment operator.
 */
font_info& font_info::operator=(const font_info &fi)
{
    if (this != &fi) {
        *d = *fi.d;
    }
    return *this;
}

/**
 \class poppler::font_iterator poppler-font.h "poppler/cpp/poppler-font.h"

 Reads the fonts in the PDF %document page by page.

 font_iterator is the way to collect the list of the fonts used in a PDF
 %document, reading them incrementally page by page.

 A typical usage of this might look like:
 \code
poppler::font_iterator *it = doc->create_font_iterator();
while (it->has_next()) {
    std::vector<poppler::font_info> fonts = it->next();
    // do domething with the fonts
}
// after we are done with the iterator, it must be deleted
delete it;
\endcode
 */


font_iterator::font_iterator(int start_page, document_private *dd)
    : d(new font_iterator_private(start_page, dd))
{
}

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

/**
 Returns the fonts of the current page and advances to the next one.
 */
std::vector<font_info> font_iterator::next()
{
    if (!has_next()) {
        return std::vector<font_info>();
    }

    ++d->current_page;

    GooList *items = d->font_info_scanner.scan(1);
    if (!items) {
        return std::vector<font_info>();
    }
    std::vector<font_info> fonts(items->getLength());
    for (int i = 0; i < items->getLength(); ++i) {
        fonts[i] = font_info(*new font_info_private((FontInfo *)items->get(i)));
    }
    deleteGooList<FontInfo>(items);
    return fonts;
}

/**
 \returns whether the iterator has more pages to advance to
*/
bool font_iterator::has_next() const
{
    return d->current_page < d->total_pages;
}

/**
 \returns the current page
*/
int font_iterator::current_page() const
{
    return d->current_page;
}
