/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include <QtTest/QtTest>

#include <qtextdocument.h>
#include <qtextdocumentfragment.h>
#include <qtextlist.h>
#include <qabstracttextdocumentlayout.h>
#include <qtextcursor.h>
#include "../qtextdocument/common.h"

class tst_QTextList : public QObject
{
    Q_OBJECT

private slots:
    void init();
    void cleanup();
    void item();
    void autoNumbering();
    void autoNumberingRTL();
    void autoNumberingPrefixAndSuffix();
    void autoNumberingPrefixAndSuffixRTL();
    void autoNumberingPrefixAndSuffixHtmlExportImport();
    void romanNumbering();
    void romanNumberingLimit();
    void formatChange();
    void cursorNavigation();
    void partialRemoval();
    void formatReferenceChange();
    void ensureItemOrder();
    void add();
    void defaultIndent();
    void blockUpdate();
    void numbering_data();
    void numbering();

private:
    QTextDocument *doc;
    QTextCursor cursor;
    QTestDocumentLayout *layout;
};

void tst_QTextList::init()
{
    doc = new QTextDocument();
    layout = new QTestDocumentLayout(doc);
    doc->setDocumentLayout(layout);
    cursor = QTextCursor(doc);
}

void tst_QTextList::cleanup()
{
    cursor = QTextCursor();
    delete doc;
    doc = 0;
}

void tst_QTextList::item()
{
    // this is basically a test for the key() + 1 in QTextList::item.
    QTextList *list = cursor.createList(QTextListFormat());
    QVERIFY(list->item(0).blockFormat().objectIndex() != -1);
}

void tst_QTextList::autoNumbering()
{
    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListLowerAlpha);
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    for (int i = 0; i < 27; ++i)
        cursor.insertBlock();

    QCOMPARE(list->count(), 28);

    QVERIFY(cursor.currentList());
    QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 27);
    QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("ab."));
}

void tst_QTextList::autoNumberingPrefixAndSuffix()
{
    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListLowerAlpha);
    fmt.setNumberPrefix("-");
    fmt.setNumberSuffix(")");
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    for (int i = 0; i < 27; ++i)
        cursor.insertBlock();

    QCOMPARE(list->count(), 28);

    QVERIFY(cursor.currentList());
    QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 27);
    QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("-ab)"));
}

void tst_QTextList::autoNumberingPrefixAndSuffixRTL()
{
    QTextBlockFormat bfmt;
    bfmt.setLayoutDirection(Qt::RightToLeft);
    cursor.setBlockFormat(bfmt);

    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListUpperAlpha);
    fmt.setNumberPrefix("-");
    fmt.setNumberSuffix("*");
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    cursor.insertBlock();

    QCOMPARE(list->count(), 2);

    QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("*B-"));
}

void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport()
{
    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListLowerAlpha);
    fmt.setNumberPrefix("\"");
    fmt.setNumberSuffix("#");
    fmt.setIndent(10);
    // FIXME: Would like to test "'" but there's a problem in the css parser (Scanner::preprocess
    // is called before the values are being parsed), so the quoting does not work.
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    for (int i = 0; i < 27; ++i)
        cursor.insertBlock();

    QCOMPARE(list->count(), 28);

    QString htmlExport = doc->toHtml();
    QTextDocument importDoc;
    importDoc.setHtml(htmlExport);

    QTextCursor importCursor(&importDoc);
    for (int i = 0; i < 27; ++i)
        importCursor.movePosition(QTextCursor::NextBlock);

    QVERIFY(importCursor.currentList());
    QCOMPARE(importCursor.currentList()->itemNumber(importCursor.block()), 27);
    QCOMPARE(importCursor.currentList()->itemText(importCursor.block()), QLatin1String("\"ab#"));
    QCOMPARE(importCursor.currentList()->format().indent(), 10);
}

void tst_QTextList::autoNumberingRTL()
{
    QTextBlockFormat bfmt;
    bfmt.setLayoutDirection(Qt::RightToLeft);
    cursor.setBlockFormat(bfmt);

    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListUpperAlpha);
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    cursor.insertBlock();

    QCOMPARE(list->count(), 2);

    QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String(".B"));
}

void tst_QTextList::romanNumbering()
{
    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListUpperRoman);
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    for (int i = 0; i < 4998; ++i)
      cursor.insertBlock();

    QCOMPARE(list->count(), 4999);

    QVERIFY(cursor.currentList());
    QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 4998);
    QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("MMMMCMXCIX."));
}

void tst_QTextList::romanNumberingLimit()
{
    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::ListLowerRoman);
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    for (int i = 0; i < 4999; ++i)
      cursor.insertBlock();

    QCOMPARE(list->count(), 5000);

    QVERIFY(cursor.currentList());
    QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 4999);
    QCOMPARE(cursor.currentList()->itemText(cursor.block()), QLatin1String("?."));
}

void tst_QTextList::formatChange()
{
    // testing the formatChanged slot in QTextListManager

    /* <initial block>
     * 1.
     * 2.
     */
    QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
    QTextList *firstList = list;
    cursor.insertBlock();

    QVERIFY(list && list->count() == 2);

    QTextBlockFormat bfmt = cursor.blockFormat();
//     QCOMPARE(bfmt.object(), list);

    bfmt.setObjectIndex(-1);
    cursor.setBlockFormat(bfmt);

    QCOMPARE(firstList->count(), 1);
}

void tst_QTextList::cursorNavigation()
{
    // testing some cursor list methods

    /* <initial block>
     * 1.
     * 2.
     */
    cursor.insertList(QTextListFormat::ListDecimal);
    cursor.insertBlock();

    cursor.movePosition(QTextCursor::Start);
    cursor.movePosition(QTextCursor::NextBlock);
    cursor.movePosition(QTextCursor::NextBlock);
    QVERIFY(cursor.currentList());
    cursor.movePosition(QTextCursor::PreviousBlock);
    QVERIFY(cursor.currentList());
    QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), 0);
}

void tst_QTextList::partialRemoval()
{
    /* this is essentially a test for PieceTable::removeBlock to not miss any
       blocks with the blockChanged signal emission that actually get removed.

       It creates two lists, like this:

       1. Hello World
       a. Foobar

       and then removes from within the 'Hello World' into the 'Foobar' .
       There used to be no emission for the removal of the second (a.) block,
       causing list inconsistencies.

       */

    QTextList *firstList = cursor.insertList(QTextListFormat::ListDecimal);

    QTextCursor selStart = cursor;
    selStart.movePosition(QTextCursor::PreviousCharacter);

    cursor.insertText("Hello World");

    // position it well into the 'hello world' text.
    selStart.movePosition(QTextCursor::NextCharacter);
    selStart.movePosition(QTextCursor::NextCharacter);
    selStart.clearSelection();

    QPointer<QTextList> secondList = cursor.insertList(QTextListFormat::ListCircle);
    cursor.insertText("Foobar");

    // position it into the 'foo bar' text.
    cursor.movePosition(QTextCursor::PreviousCharacter);
    QTextCursor selEnd = cursor;

    // this creates a selection that includes parts of both text-fragments and also the list item of the second list.
    QTextCursor selection = selStart;
    selection.setPosition(selEnd.position(),  QTextCursor::KeepAnchor);

    selection.deleteChar(); // deletes the second list

    QVERIFY(!secondList);
    QVERIFY(firstList->count() > 0);

    doc->undo();
}

void tst_QTextList::formatReferenceChange()
{
    QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
    cursor.insertText("Some Content...");
    cursor.insertBlock(QTextBlockFormat());

    cursor.setPosition(list->item(0).position());
    int listItemStartPos = cursor.position();
    cursor.movePosition(QTextCursor::NextBlock);
    int listItemLen = cursor.position() - listItemStartPos;
    layout->expect(listItemStartPos, listItemLen, listItemLen);

    QTextListFormat fmt = list->format();
    fmt.setStyle(QTextListFormat::ListCircle);
    list->setFormat(fmt);

    QVERIFY(layout->called);
    QVERIFY(!layout->error);
}

void tst_QTextList::ensureItemOrder()
{
    /*
     * Insert a new list item before the first one and verify the blocks
     * are sorted after that.
     */
    QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);

    QTextBlockFormat fmt = cursor.blockFormat();
    cursor.movePosition(QTextCursor::Start);
    cursor.insertBlock(fmt);

    QCOMPARE(list->item(0).position(), 1);
    QCOMPARE(list->item(1).position(), 2);
}

void tst_QTextList::add()
{
    QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
    cursor.insertBlock(QTextBlockFormat());
    QCOMPARE(list->count(), 1);
    cursor.insertBlock(QTextBlockFormat());
    list->add(cursor.block());
    QCOMPARE(list->count(), 2);
}

// Task #72036
void tst_QTextList::defaultIndent()
{
    QTextListFormat fmt;
    QCOMPARE(fmt.indent(), 1);
}

void tst_QTextList::blockUpdate()
{
    // three items
    QTextList *list = cursor.insertList(QTextListFormat::ListDecimal);
    cursor.insertBlock();
    cursor.insertBlock();

    // remove second, needs also update on the third
    // since the numbering might have changed
    const int len = cursor.position() + cursor.block().length() - 1;
    layout->expect(1, len, len);
    list->remove(list->item(1));
    QVERIFY(!layout->error);
}

void tst_QTextList::numbering_data()
{
    QTest::addColumn<int>("format");
    QTest::addColumn<int>("number");
    QTest::addColumn<QString>("result");

    QTest::newRow("E.") << int(QTextListFormat::ListUpperAlpha) << 5 << "E.";
    QTest::newRow("abc.") << int(QTextListFormat::ListLowerAlpha) << (26 + 2) * 26 + 3 << "abc.";
    QTest::newRow("12.") << int(QTextListFormat::ListDecimal) << 12 << "12.";
    QTest::newRow("XXIV.") << int(QTextListFormat::ListUpperRoman) << 24 << "XXIV.";
    QTest::newRow("VIII.") << int(QTextListFormat::ListUpperRoman) << 8 << "VIII.";
    QTest::newRow("xxx.") << int(QTextListFormat::ListLowerRoman) << 30 << "xxx.";
    QTest::newRow("xxix.") << int(QTextListFormat::ListLowerRoman) << 29 << "xxix.";
//    QTest::newRow("xxx. alpha") << int(QTextListFormat::ListLowerAlpha) << (24 * 26 + 24) * 26 + 24  << "xxx."; //Too slow
}

void tst_QTextList::numbering()
{
    QFETCH(int, format);
    QFETCH(int, number);
    QFETCH(QString, result);


    QTextListFormat fmt;
    fmt.setStyle(QTextListFormat::Style(format));
    QTextList *list = cursor.createList(fmt);
    QVERIFY(list);

    for (int i = 1; i < number; ++i)
        cursor.insertBlock();

    QCOMPARE(list->count(), number);

    QVERIFY(cursor.currentList());
    QCOMPARE(cursor.currentList()->itemNumber(cursor.block()), number - 1);
    QCOMPARE(cursor.currentList()->itemText(cursor.block()), result);
}

QTEST_MAIN(tst_QTextList)
#include "tst_qtextlist.moc"
