#include "anim.h"
#include "iconset.h"

#include <QtTest/QtTest>

class TestIconset : public QObject {
    Q_OBJECT
private:
    Iconset *iconset;

private slots:
    void initTestCase()
    {
        iconset = new Iconset();
        QVERIFY(iconset->load("iconsets/roster/default.jisp"));
        iconset->addToFactory();
    }

    void cleanupTestCase()
    {
        iconset->clear();
        QCOMPARE(iconset->count(), 0);

        delete iconset;
    }

    void testIconsetData()
    {
        // verify metadata
        QCOMPARE(iconset->name(), QString("Stellar (default)"));
        QCOMPARE(iconset->version(), QString("1.0"));
        QCOMPARE(iconset->authors().count(), 2);
        QCOMPARE(iconset->authors()[0],
                 QString("Jason Kim<br>&nbsp;&nbsp;Email: <a href='mailto:jmkim@uci.edu'>jmkim@uci.edu</a>"));
        QCOMPARE(
            iconset->authors()[1],
            QString("Michail Pishchagin (icondef.xml)<br>&nbsp;&nbsp;Email: <a "
                    "href='mailto:mblsha@users.sourceforge.net'>mblsha@users.sourceforge.net</a><br>&nbsp;&nbsp;JID: "
                    "<a href='xmpp:mblsha@jabber.ru'>mblsha@jabber.ru</a><br>&nbsp;&nbsp;WWW: <a "
                    "href='http://maz.sf.net'>http://maz.sf.net</a>"));
        QCOMPARE(iconset->creation(), QString("2003-07-08"));
        QCOMPARE(iconset->description(), QString("Default Psi 0.9.1 iconset"));

        // verify icons
        QCOMPARE(iconset->count(), 19);
    }

    void testIterator()
    {
        QStringList              iconNames;
        QListIterator<PsiIcon *> it = iconset->iterator();
        while (it.hasNext()) {
            PsiIcon *icon = it.next();
            iconNames << icon->name();
        }
        QCOMPARE(iconNames.count(), iconset->count());
    }

    void testHeadlineIcon()
    {
        const PsiIcon *messageHeadline = IconsetFactory::iconPtr("psi/headline");
        QVERIFY(messageHeadline != 0);
        QCOMPARE(messageHeadline->name(), QString("psi/headline"));
        QCOMPARE(messageHeadline->isAnimated(), false);
        QCOMPARE(messageHeadline->frameNumber(), 0);
        QCOMPARE(messageHeadline->anim(), (const Anim *)0);
        QVERIFY(!messageHeadline->impix().isNull());
        QVERIFY(!messageHeadline->pixmap().isNull());
        QCOMPARE(messageHeadline->impix().image().width(), 16);
        QCOMPARE(messageHeadline->impix().image().height(), 16);
        QCOMPARE(messageHeadline->impix().pixmap().width(), 16);
        QCOMPARE(messageHeadline->impix().pixmap().height(), 16);
        QCOMPARE(messageHeadline->pixmap().width(), 16);
        QCOMPARE(messageHeadline->pixmap().height(), 16);
    }

    void testAnim()
    {
        const PsiIcon *chat = IconsetFactory::iconPtr("psi/chat");
        QVERIFY(chat->anim() != 0);

        const Anim *anim  = chat->anim();
        Anim *      copy1 = new Anim(*anim);
        Anim *      copy2 = new Anim(*copy1);
        Anim *      copy3 = new Anim(*copy2);

        // at first, all animations should contain 15 frames
        QCOMPARE(copy3->numFrames(), 15);

        copy3->stripFirstFrame();
        QCOMPARE(copy3->numFrames(), 14);
        QCOMPARE(copy2->numFrames(), 15);
        QCOMPARE(copy1->numFrames(), 15);
        QCOMPARE(anim->numFrames(), 15);

        int i;
        for (i = 0; i < 2; i++)
            copy2->stripFirstFrame();
        QCOMPARE(copy3->numFrames(), 14);
        QCOMPARE(copy2->numFrames(), 13);
        QCOMPARE(copy1->numFrames(), 15);
        QCOMPARE(anim->numFrames(), 15);

        for (i = 0; i < 5; i++)
            copy1->stripFirstFrame();
        QCOMPARE(copy3->numFrames(), 14);
        QCOMPARE(copy2->numFrames(), 13);
        QCOMPARE(copy1->numFrames(), 10);
        QCOMPARE(anim->numFrames(), 15);

        delete copy3;
        delete copy2;
        delete copy1;
    }

    void testIconStripping()
    {
        const PsiIcon *chat = IconsetFactory::iconPtr("psi/chat");
        QVERIFY(chat != 0);

        QVERIFY(chat->isAnimated() == true);
        QCOMPARE(chat->anim()->numFrames(), 15);

        PsiIcon *stripping = new PsiIcon(*chat);
        QCOMPARE(chat->name(), QString("psi/chat"));
        QCOMPARE(stripping->name(), QString("psi/chat"));

        stripping->stripFirstAnimFrame();
        QCOMPARE(stripping->anim()->numFrames(), 14);
        QCOMPARE(chat->anim()->numFrames(), 15);

        stripping->setName("yohimbo");
        QCOMPARE(chat->name(), QString("psi/chat"));
        QCOMPARE(stripping->name(), QString("yohimbo"));

        delete stripping;
    }

    void testIconsetFactory()
    {
        QCOMPARE(IconsetFactory::icons().count(), 19);
        QVERIFY(IconsetFactory::iconPtr("psi/message"));
    }

    void testCombineIconsets()
    {
        Iconset *is = new Iconset();
        QVERIFY(is->load("iconsets/roster/small.jisp"));

        Iconset *combined = new Iconset(*is);
        QCOMPARE(combined->count(), is->count());

        *combined += *is;
        QCOMPARE(combined->count(), is->count());

        QListIterator<PsiIcon *> it = is->iterator();
        while (it.hasNext()) {
            PsiIcon *icon = new PsiIcon(*it.next());
            icon->setName(icon->name() + '2');
            combined->setIcon(icon->name(), *icon);
            delete icon;
        }
        QCOMPARE(combined->count(), 4);

        combined->clear();
        QCOMPARE(combined->count(), 0);
        QCOMPARE(is->count(), 2);

        delete combined;
        delete is;
    }

    void testLoadGifIconset()
    {
        Iconset *is = new Iconset();
        QVERIFY(is->load("iconsets/emoticons/puz.jisp"));
        QVERIFY(is->count() > 0);
        delete is;
    }

    void testMultipleIconTextStrings()
    {
        // all puz iconset icons contain multiple
        // text strings. we need to verify that.
        Iconset *is = new Iconset();
        QVERIFY(is->load("iconsets/emoticons/puz.jisp"));
        QVERIFY(is->count() > 0);

        QListIterator<PsiIcon *> it = is->iterator();
        while (it.hasNext()) {
            const QList<PsiIcon::IconText> text = it.next()->text();
            QVERIFY(text.count() > 1);
        }

        delete is;
    }

    void testCreateQIcon()
    {
        const PsiIcon *chat = IconsetFactory::iconPtr("psi/chat");
        QVERIFY(chat != 0);

        QIcon icon = chat->icon();
        QVERIFY(!icon.isNull());
    }
};

QTEST_MAIN(TestIconset)
#include "testiconset.moc"
