#include <QtTest/QtTest>

#include <poppler-qt4.h>

#include <memory>

class TestFontsData: public QObject
{
    Q_OBJECT
private slots:
    void checkNoFonts();
    void checkType1();
    void checkType3();
    void checkTrueType();
    void checkFontIterator();
    void checkSecondDocumentQuery();
    void checkMultipleIterations();
    void checkScanForFonts();
};


static QList<Poppler::FontInfo> loadFontsViaIterator( Poppler::Document *doc, int from = 0, int count = -1 )
{
    int num = count == -1 ? doc->numPages() - from : count;
    QList<Poppler::FontInfo> list;
    std::unique_ptr< Poppler::FontIterator > it( doc->newFontIterator( from ) );
    while ( it->hasNext() && num )
    {
        list += it->next();
        --num;
    }
    return list;
}

namespace Poppler
{
static bool operator==( const FontInfo &f1, const FontInfo &f2 )
{
    if ( f1.name() != f2.name() )
        return false;
    if ( f1.file() != f2.file() )
        return false;
    if ( f1.isEmbedded() != f2.isEmbedded() )
        return false;
    if ( f1.isSubset() != f2.isSubset() )
        return false;
    if ( f1.type() != f2.type() )
        return false;
    if ( f1.typeName() != f2.typeName() )
        return false;
    return true;
}
}

void TestFontsData::checkNoFonts()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/image.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = doc->fonts();
    QCOMPARE( listOfFonts.size(), 0 );

    delete doc;
}

void TestFontsData::checkType1()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/text.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = doc->fonts();
    QCOMPARE( listOfFonts.size(), 1 );
    QCOMPARE( listOfFonts.at(0).name(), QString("Helvetica") );
    QCOMPARE( listOfFonts.at(0).type(), Poppler::FontInfo::Type1 );
    QCOMPARE( listOfFonts.at(0).typeName(), QString("Type 1") );

    QCOMPARE( listOfFonts.at(0).isEmbedded(), false );
    QCOMPARE( listOfFonts.at(0).isSubset(), false );

    delete doc;
}

void TestFontsData::checkType3()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/type3.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = doc->fonts();
    QCOMPARE( listOfFonts.size(), 2 );
    QCOMPARE( listOfFonts.at(0).name(), QString("Helvetica") );
    QCOMPARE( listOfFonts.at(0).type(), Poppler::FontInfo::Type1 );
    QCOMPARE( listOfFonts.at(0).typeName(), QString("Type 1") );

    QCOMPARE( listOfFonts.at(0).isEmbedded(), false );
    QCOMPARE( listOfFonts.at(0).isSubset(), false );

    QCOMPARE( listOfFonts.at(1).name(), QString("") );
    QCOMPARE( listOfFonts.at(1).type(), Poppler::FontInfo::Type3 );
    QCOMPARE( listOfFonts.at(1).typeName(), QString("Type 3") );

    QCOMPARE( listOfFonts.at(1).isEmbedded(), true );
    QCOMPARE( listOfFonts.at(1).isSubset(), false );

    delete doc;
}

void TestFontsData::checkTrueType()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/unittestcases/truetype.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = doc->fonts();
    QCOMPARE( listOfFonts.size(), 2 );
    QCOMPARE( listOfFonts.at(0).name(), QString("Arial-BoldMT") );
    QCOMPARE( listOfFonts.at(0).type(), Poppler::FontInfo::TrueType );
    QCOMPARE( listOfFonts.at(0).typeName(), QString("TrueType") );

    QCOMPARE( listOfFonts.at(0).isEmbedded(), false );
    QCOMPARE( listOfFonts.at(0).isSubset(), false );

    QCOMPARE( listOfFonts.at(1).name(), QString("ArialMT") );
    QCOMPARE( listOfFonts.at(1).type(), Poppler::FontInfo::TrueType );
    QCOMPARE( listOfFonts.at(1).typeName(), QString("TrueType") );

    QCOMPARE( listOfFonts.at(1).isEmbedded(), false );
    QCOMPARE( listOfFonts.at(1).isSubset(), false );

    delete doc;
}

void TestFontsData::checkFontIterator()
{
    // loading a 1-page document
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/type3.pdf");
    QVERIFY( doc );
    // loading a 6-pages document
    Poppler::Document *doc6 = Poppler::Document::load(TESTDATADIR "/tests/cropbox.pdf");
    QVERIFY( doc6 );

    std::unique_ptr< Poppler::FontIterator > it;

    // some tests with the 1-page document:
    // - check a default iterator
    it.reset( doc->newFontIterator() );
    QVERIFY( it->hasNext() );
    // - check an iterator for negative pages to behave as 0
    it.reset( doc->newFontIterator( -1 ) );
    QVERIFY( it->hasNext() );
    // - check an iterator for pages out of the page limit
    it.reset( doc->newFontIterator( 1 ) );
    QVERIFY( !it->hasNext() );
    // - check that it reaches the end after 1 iteration
    it.reset( doc->newFontIterator() );
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( !it->hasNext() );

    // some tests with the 6-page document:
    // - check a default iterator
    it.reset( doc6->newFontIterator() );
    QVERIFY( it->hasNext() );
    // - check an iterator for pages out of the page limit
    it.reset( doc6->newFontIterator( 6 ) );
    QVERIFY( !it->hasNext() );
    // - check that it reaches the end after 6 iterations
    it.reset( doc6->newFontIterator() );
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( it->hasNext() );
    it->next();
    QVERIFY( !it->hasNext() );

    delete doc;
    delete doc6;
}

void TestFontsData::checkSecondDocumentQuery()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/type3.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = doc->fonts();
    QCOMPARE( listOfFonts.size(), 2 );
    // check we get the very same result when calling fonts() again (#19405)
    QList<Poppler::FontInfo> listOfFonts2 = doc->fonts();
    QCOMPARE( listOfFonts, listOfFonts2 );

    delete doc;
}

void TestFontsData::checkMultipleIterations()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/type3.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = loadFontsViaIterator( doc );
    QCOMPARE( listOfFonts.size(), 2 );
    QList<Poppler::FontInfo> listOfFonts2 = loadFontsViaIterator( doc );
    QCOMPARE( listOfFonts, listOfFonts2 );

    delete doc;
}

void TestFontsData::checkScanForFonts()
{
    Poppler::Document *doc;
    doc = Poppler::Document::load(TESTDATADIR "/tests/fonts.pdf");
    QVERIFY( doc );

    QList<Poppler::FontInfo> listOfFonts = doc->fonts();
    QCOMPARE( listOfFonts.size(), 3 );
    // check we get the very same result when gatering fonts using scanForFonts
    QList<Poppler::FontInfo> listOfFonts2;
    for ( int i = 0; i < doc->numPages(); ++i )
    {
        doc->scanForFonts( 1, &listOfFonts2 );
    }
    QCOMPARE( listOfFonts, listOfFonts2 );

   // check doing a second scanForFonts gives no result
    QList<Poppler::FontInfo> listOfFonts3;
    for ( int i = 0; i < doc->numPages(); ++i )
    {
        doc->scanForFonts( 1, &listOfFonts3 );
    }
    QVERIFY( listOfFonts3.isEmpty() );

    delete doc;
}

QTEST_MAIN(TestFontsData)
#include "check_fonts.moc"

