/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications 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 "distancefieldmodel.h"
#include "distancefieldmodelworker.h"

#include <QThread>
#include <QMetaEnum>

QT_BEGIN_NAMESPACE

DistanceFieldModel::DistanceFieldModel(QObject *parent)
    : QAbstractListModel(parent)
    , m_glyphCount(0)
{
    int index = metaObject()->indexOfEnumerator("UnicodeRange");
    Q_ASSERT(index >= 0);

    m_rangeEnum = metaObject()->enumerator(index);

    m_workerThread.reset(new QThread);

    m_worker = new DistanceFieldModelWorker;
    m_worker->moveToThread(m_workerThread.data());
    connect(m_workerThread.data(), &QThread::finished,
            m_worker, &QObject::deleteLater);

    connect(m_worker, &DistanceFieldModelWorker::fontLoaded,
            this, &DistanceFieldModel::startGeneration);
    connect(m_worker, &DistanceFieldModelWorker::fontLoaded,
            this, &DistanceFieldModel::reserveSpace);
    connect(m_worker, &DistanceFieldModelWorker::distanceFieldGenerated,
            this, &DistanceFieldModel::addDistanceField);
    connect(m_worker, &DistanceFieldModelWorker::fontGenerated,
            this, &DistanceFieldModel::stopGeneration);
    connect(m_worker, &DistanceFieldModelWorker::distanceFieldGenerated,
            this, &DistanceFieldModel::distanceFieldGenerated);
    connect(m_worker, &DistanceFieldModelWorker::error,
            this, &DistanceFieldModel::error);

    m_workerThread->start();
}

DistanceFieldModel::~DistanceFieldModel()
{
    m_workerThread->quit();
    m_workerThread->wait();
}

QVariant DistanceFieldModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_UNUSED(section);
    Q_UNUSED(orientation);
    Q_UNUSED(role);
    return QVariant();
}

int DistanceFieldModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    else
        return m_glyphCount;
}

QVariant DistanceFieldModel::data(const QModelIndex &index, int role) const
{
    static QPixmap defaultImage;
    if (defaultImage.isNull()) {
        defaultImage = QPixmap(64, 64);
        defaultImage.fill(Qt::white);
    }

    if (!index.isValid())
        return QVariant();

    if (role == Qt::DecorationRole) {
        if (index.row() < m_distanceFields.size()) {
            return QPixmap::fromImage(m_distanceFields.at(index.row()).scaled(64, 64));
        } else {
            return defaultImage;
        }

    }

    return QVariant();
}

void DistanceFieldModel::setFont(const QString &fileName)
{
    QMetaObject::invokeMethod(m_worker,
                              [this, fileName] { m_worker->loadFont(fileName); },
                              Qt::QueuedConnection);
}

void DistanceFieldModel::reserveSpace(quint16 glyphCount,
                                      bool doubleResolution,
                                      qreal pixelSize)
{
    beginResetModel();
    m_glyphsPerUnicodeRange.clear();
    m_distanceFields.clear();
    m_glyphCount = glyphCount;
    if (glyphCount > 0)
        m_distanceFields.reserve(glyphCount);
    endResetModel();

    m_doubleGlyphResolution = doubleResolution;
    m_pixelSize = pixelSize;

    QMetaObject::invokeMethod(m_worker,
                              [this] { m_worker->generateOneDistanceField(); },
                              Qt::QueuedConnection);
}

DistanceFieldModel::UnicodeRange DistanceFieldModel::unicodeRangeForUcs4(quint32 ucs4) const
{
    int index = metaObject()->indexOfEnumerator("UnicodeRange");
    Q_ASSERT(index >= 0);

    QMetaEnum range = metaObject()->enumerator(index);
    for (int i = 0; i < range.keyCount() - 1; ++i) {
        int rangeStart = range.value(i);
        int rangeEnd = range.value(i + 1);
        if (quint32(rangeStart) <= ucs4 && quint32(rangeEnd) >= ucs4)
            return UnicodeRange(rangeStart);
    }

    return Other;
}

QList<DistanceFieldModel::UnicodeRange> DistanceFieldModel::unicodeRanges() const
{
    return m_glyphsPerUnicodeRange.uniqueKeys();
}

QList<glyph_t> DistanceFieldModel::glyphIndexesForUnicodeRange(UnicodeRange range) const
{
    return m_glyphsPerUnicodeRange.values(range);
}

QString DistanceFieldModel::nameForUnicodeRange(UnicodeRange range) const
{
    return QString::fromLatin1(m_rangeEnum.valueToKey(int(range)));
}

void DistanceFieldModel::addDistanceField(const QImage &distanceField,
                                          const QPainterPath &path,
                                          glyph_t glyphId,
                                          quint32 ucs4)
{
    if (glyphId >= quint16(m_distanceFields.size()))
        m_distanceFields.resize(glyphId + 1);
    m_distanceFields[glyphId] = distanceField;
    if (glyphId >= quint16(m_paths.size()))
        m_paths.resize(glyphId + 1);
    m_paths[glyphId] = path;

    if (ucs4 != 0) {
        UnicodeRange range = unicodeRangeForUcs4(ucs4);
        m_glyphsPerUnicodeRange.insert(range, glyphId);
        m_glyphsPerUcs4.insert(ucs4, glyphId);
    }

    emit dataChanged(createIndex(glyphId, 0), createIndex(glyphId, 0));

    QMetaObject::invokeMethod(m_worker,
                             [this] { m_worker->generateOneDistanceField(); },
                             Qt::QueuedConnection);
}

glyph_t DistanceFieldModel::glyphIndexForUcs4(quint32 ucs4) const
{
    return m_glyphsPerUcs4.value(ucs4);
}

QT_END_NAMESPACE
