#include <QtTest/QtTest>

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

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='jabber: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"
