CardInfo *CardDatabase::getCardFromMap(CardNameMap &cardMap, const QString &cardName, bool createIfNotFound) {
    if (cardName.isEmpty())
        return noCard;
    else if (cardMap.contains(cardName))
        return cardMap.value(cardName);
    else if (createIfNotFound) {
        CardInfo *newCard = new CardInfo(this, cardName, true);
        newCard->addToSet(getSet(CardDatabase::TOKENS_SETNAME));
        cardMap.insert(cardName, newCard);
        return newCard;
    } else
        return 0;
}
CardInfo *CardDatabase::getCardFromMap(CardNameMap &cardMap, const QString &cardName, bool createIfNotFound) {
    CardInfo *foundCard;

    if (cardName.isEmpty())
        return noCard;
    else if (cardMap.contains(cardName))
        return cardMap.value(cardName);
    else if ((foundCard = cardMap.findByPrefix(cardName.toStdString())))
        return foundCard;
    else if (createIfNotFound) {
        CardInfo *newCard = new CardInfo(this, cardName, true);
        newCard->addToSet(getSet("TK"));
        cardMap.insert(cardName, newCard);
        return newCard;
    } else
        return 0;
}
void DlgEditTokens::actAddToken()
{
    QString name;
    bool askAgain;
    do {
        name = QInputDialog::getText(this, tr("Add token"), tr("Please enter the name of the token:"));
        if (!name.isEmpty() && cardDatabaseModel->getDatabase()->getCard(name, false)) {
            QMessageBox::critical(this, tr("Error"), tr("The chosen name conflicts with an existing card or token."));
            askAgain = true;
        } else
            askAgain = false;
    } while (askAgain);
    
    if (name.isEmpty())
        return;
    
    CardInfo *card = new CardInfo(cardDatabaseModel->getDatabase(), name, true);
    card->addToSet(cardDatabaseModel->getDatabase()->getSet("TK"));
    card->setCardType("Token");
    cardDatabaseModel->getDatabase()->addCard(card);
}
int OracleImporter::importTextSpoiler(CardSet *set, const QByteArray &data)
{
	int cards = 0;
	QString bufferContents(data);
	
	// Workaround for ampersand bug in text spoilers
	int index = -1;
	while ((index = bufferContents.indexOf('&', index + 1)) != -1) {
		int semicolonIndex = bufferContents.indexOf(';', index);
		if (semicolonIndex > 5) {
			bufferContents.insert(index + 1, "amp;");
			index += 4;
		}
	}
	
	QDomDocument doc;
	QString errorMsg;
	int errorLine, errorColumn;
	if (!doc.setContent(bufferContents, &errorMsg, &errorLine, &errorColumn))
		qDebug() << "error:" << errorMsg << "line:" << errorLine << "column:" << errorColumn;

	QDomNodeList divs = doc.elementsByTagName("div");
	for (int i = 0; i < divs.size(); ++i) {
		QDomElement div = divs.at(i).toElement();
		QDomNode divClass = div.attributes().namedItem("class");
		if (divClass.nodeValue() == "textspoiler") {
			QString cardName, cardCost, cardType, cardPT, cardText;
			int cardId = 0;
			int cardLoyalty = 0;
			
			QDomNodeList trs = div.elementsByTagName("tr");
			for (int j = 0; j < trs.size(); ++j) {
				QDomElement tr = trs.at(j).toElement();
				QDomNodeList tds = tr.elementsByTagName("td");
				if (tds.size() != 2) {
					QStringList cardTextSplit = cardText.split("\n");
					for (int i = 0; i < cardTextSplit.size(); ++i)
						cardTextSplit[i] = cardTextSplit[i].trimmed();
					
					CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardTextSplit);
					if (!set->contains(card)) {
						card->addToSet(set);
						cards++;
					}
					cardName = cardCost = cardType = cardPT = cardText = QString();
				} else {
					QString v1 = tds.at(0).toElement().text().simplified();
					QString v2 = tds.at(1).toElement().text().replace(trUtf8("—"), "-");
					
					if (v1 == "Name") {
						QDomElement a = tds.at(1).toElement().elementsByTagName("a").at(0).toElement();
						QString href = a.attributes().namedItem("href").nodeValue();
						cardId = href.mid(href.indexOf("multiverseid=") + 13).toInt();
						cardName = v2.simplified();
					} else if (v1 == "Cost:")
						cardCost = v2.simplified();
					else if (v1 == "Type:")
						cardType = v2.simplified();
					else if (v1 == "Pow/Tgh:")
						cardPT = v2.simplified().remove('(').remove(')');
					else if (v1 == "Rules Text:")
						cardText = v2.trimmed();
					else if (v1 == "Loyalty:")
						cardLoyalty = v2.trimmed().remove('(').remove(')').toInt();
				}
			}
			break;
		}
	}
	return cards;
}
int OracleImporter::importTextSpoiler(CardSet *set, const QVariant &data)
{
    int cards = 0;

    QListIterator<QVariant> it(data.toList());
    QVariantMap map;
    QString cardName;
    QString cardCost;
    QString cardType;
    QString cardPT;
    QString cardText;
    int cardId;
    int cardLoyalty;
    QMap<int, QVariantMap> splitCards;

    while (it.hasNext()) {
        map = it.next().toMap();
        if(0 == QString::compare(map.value("layout").toString(), QString("split"), Qt::CaseInsensitive))
        {
            // Split card handling
            cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
            if(splitCards.contains(cardId))
            {
                // merge two split cards
                QVariantMap tmpMap = splitCards.take(cardId);
                QVariantMap * card1 = 0, * card2 = 0;
                // same cardid
                cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
                // this is currently an integer; can't accept 2 values
                cardLoyalty = 0;

                // determine which subcard is the first one in the split
                QStringList names=map.contains("names") ? map.value("names").toStringList() : QStringList("");
                if(names.count()>0 &&
                        map.contains("name") &&
                        0 == QString::compare(map.value("name").toString(), names.at(0)))
                {
                    // map is the left part of the split card, tmpMap is right part
                    card1 = &map;
                    card2 = &tmpMap;
                } else {
                    //tmpMap is the left part of the split card, map is right part
                    card1 = &tmpMap;
                    card2 = &map;
                }

                // add first card's data
                cardName = card1->contains("name") ? card1->value("name").toString() : QString("");
                cardCost = card1->contains("manaCost") ? card1->value("manaCost").toString() : QString("");
                cardType = card1->contains("type") ? card1->value("type").toString() : QString("");
                cardPT = card1->contains("power") || card1->contains("toughness") ? card1->value("power").toString() + QString('/') + card1->value("toughness").toString() : QString("");
                cardText = card1->contains("text") ? card1->value("text").toString() : QString("");

                // add second card's data
                cardName += card2->contains("name") ? QString(" // ") + card2->value("name").toString() : QString("");
                cardCost += card2->contains("manaCost") ? QString(" // ") + card2->value("manaCost").toString() : QString("");
                cardType += card2->contains("type") ? QString(" // ") + card2->value("type").toString() : QString("");
                cardPT += card2->contains("power") || card2->contains("toughness") ? QString(" // ") + card2->value("power").toString() + QString('/') + card2->value("toughness").toString() : QString("");
                cardText += card2->contains("text") ? QString("\n\n---\n\n") + card2->value("text").toString() : QString("");
            } else {
                // first card od a pair; enqueue for later merging
                splitCards.insert(cardId, map);
                continue;
            }
        } else {
            // normal cards handling
            cardName = map.contains("name") ? map.value("name").toString() : QString("");
            cardCost = map.contains("manaCost") ? map.value("manaCost").toString() : QString("");
            cardType = map.contains("type") ? map.value("type").toString() : QString("");
            cardPT = map.contains("power") || map.contains("toughness") ? map.value("power").toString() + QString('/') + map.value("toughness").toString() : QString("");
            cardText = map.contains("text") ? map.value("text").toString() : QString("");
            cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0;
            cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0;
        }

        CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardText.split("\n"));

        if (!set->contains(card)) {
            card->addToSet(set);
            cards++;
        }
    }

    return cards;
}