/****************************************************************************
**
** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** 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-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtextureatlas_p.h"
#include "qtextureatlas_p_p.h"
#include <Qt3DRender/qtexturedata.h>
#include <Qt3DRender/qabstracttextureimage.h>

QT_BEGIN_NAMESPACE

using namespace Qt3DCore;

namespace Qt3DExtras {

QTextureAtlasData::QTextureAtlasData(int w, int h, QImage::Format fmt)
    : m_image(w, h, fmt)
{
    m_image.fill(0);
}

QTextureAtlasData::~QTextureAtlasData()
{
}

void QTextureAtlasData::addImage(const AtlasTexture &texture, const QImage &image)
{
    QMutexLocker lock(&m_mutex);

    Update update;
    update.textureInfo = texture;
    update.image = image;
    m_updates << update;
}

QByteArray QTextureAtlasData::createUpdatedImageData()
{
    m_mutex.lock();
    const QVector<Update> updates = std::move(m_updates);
    m_mutex.unlock();

    // copy sub-images into the actual texture image
    for (const Update &update : updates) {
        const QImage &image = update.image;

        const int padding = update.textureInfo.padding;
        const QRect imgRect = update.textureInfo.position;
        const QRect alloc = imgRect.adjusted(-padding, -padding, padding, padding);

        // bytes per pixel
        if (image.depth() != m_image.depth()) {
            qWarning() << "[QTextureAtlas] Image depth does not match. Original =" << m_image.depth() << ", Sub-Image =" << image.depth();
            continue;
        }
        int bpp = image.depth() / 8;

        // copy image contents into texture image
        // use image border pixels to fill the padding region
        for (int y = alloc.top(); y <= alloc.bottom(); y++) {
            uchar *dstLine = m_image.scanLine(y);

            uchar *dstPadL = &dstLine[bpp * alloc.left()];
            uchar *dstPadR = &dstLine[bpp * imgRect.right()];
            uchar *dstImg  = &dstLine[bpp * imgRect.left()];

            // do padding with 0 in the upper/lower padding parts around the actual image
            if (y < imgRect.top() || y > imgRect.bottom()) {
                memset(dstPadL, 0, bpp * (imgRect.width() + 2 * padding));
                continue;
            }

            // copy left and right padding pixels
            memset(dstPadL, 0, bpp * padding);
            memset(dstPadR, 0, bpp * padding);

            // copy image scanline
            const int ySrc = qBound(0, y - imgRect.top(), image.height()-1);
            memcpy(dstImg, image.scanLine(ySrc), bpp * imgRect.width());
        }
    }

    return QByteArray(reinterpret_cast<const char*>(m_image.constBits()), m_image.sizeInBytes());
}

QTextureAtlasPrivate::QTextureAtlasPrivate()
    : Qt3DRender::QAbstractTexturePrivate()
{
    m_target = Qt3DRender::QAbstractTexture::TargetAutomatic;
    m_format = Qt3DRender::QAbstractTexture::RGBA8_UNorm;
    m_width = 256;
    m_height = 256;
    m_depth = 1;
}

QTextureAtlasPrivate::~QTextureAtlasPrivate()
{
}

QTextureAtlasGenerator::QTextureAtlasGenerator(const QTextureAtlasPrivate *texAtlas)
    : m_data(texAtlas->m_data)
    , m_format(texAtlas->m_format)
    , m_pixelFormat(texAtlas->m_pixelFormat)
    , m_generation(texAtlas->m_currGen)
    , m_atlasId(texAtlas->m_id)
{
}

QTextureAtlasGenerator::~QTextureAtlasGenerator()
{
}

Qt3DRender::QTextureDataPtr QTextureAtlasGenerator::operator()()
{
    Qt3DRender::QTextureImageDataPtr texImage = Qt3DRender::QTextureImageDataPtr::create();
    texImage->setTarget(QOpenGLTexture::Target2D);
    texImage->setWidth(m_data->width());
    texImage->setHeight(m_data->height());
    texImage->setDepth(1);
    texImage->setFaces(1);
    texImage->setLayers(1);
    texImage->setMipLevels(1);
    texImage->setFormat(static_cast<QOpenGLTexture::TextureFormat>(m_format));
    texImage->setPixelFormat(m_pixelFormat);
    texImage->setPixelType(QOpenGLTexture::UInt8);

    const QByteArray bytes = m_data->createUpdatedImageData();
    texImage->setData(bytes, 1);

    Qt3DRender::QTextureDataPtr generatedData = Qt3DRender::QTextureDataPtr::create();
    generatedData->setTarget(Qt3DRender::QAbstractTexture::Target2D);
    generatedData->setFormat(m_format);
    generatedData->setWidth(m_data->width());
    generatedData->setHeight(m_data->height());
    generatedData->setDepth(1);
    generatedData->setLayers(1);
    generatedData->addImageData(texImage);

    return generatedData;
}

bool QTextureAtlasGenerator::operator==(const QTextureGenerator &other) const
{
    const QTextureAtlasGenerator *otherFunctor = Qt3DRender::functor_cast<QTextureAtlasGenerator>(&other);
    return (otherFunctor != nullptr
            && otherFunctor->m_data == m_data
            && otherFunctor->m_atlasId == m_atlasId
            && otherFunctor->m_generation == m_generation);
}

QTextureAtlas::QTextureAtlas(Qt3DCore::QNode *parent)
    : QAbstractTexture(*new QTextureAtlasPrivate(), parent)
{
}

QOpenGLTexture::PixelFormat QTextureAtlas::pixelFormat() const
{
    Q_D(const QTextureAtlas);
    return d->m_pixelFormat;
}

void QTextureAtlas::setPixelFormat(QOpenGLTexture::PixelFormat fmt)
{
    Q_D(QTextureAtlas);
    d->m_pixelFormat = fmt;
}

QTextureAtlas::~QTextureAtlas()
{
}

QTextureAtlas::TextureId QTextureAtlas::addImage(const QImage &image, int padding)
{
    Q_D(QTextureAtlas);

    // lazily create image and allocator to allow setWidth/setHeight after object construction
    if (!d->m_allocator) {
        Q_ASSERT(d->m_data.isNull());

        d->m_allocator.reset(new AreaAllocator(QSize(width(), height())));
        d->m_data = QTextureAtlasDataPtr::create(width(), height(), image.format());
    }

    const QSize allocSz = image.size() + QSize(2 * padding, 2 * padding);

    // try to allocate space within image space
    const QRect alloc = d->m_allocator->allocate(allocSz);
    if (alloc.isEmpty())
        return InvalidTexture;

    const QRect imgRect = alloc.adjusted(padding, padding, -padding, -padding);
    AtlasTexture tex;
    tex.position = imgRect;
    tex.padding = padding;

    // store texture
    TextureId id = d->m_currId++;
    d->m_textures[id] = tex;
    d->m_data->addImage(tex, image);

    // update data functor
    d->m_currGen++;
    d->setDataFunctor(QTextureAtlasGeneratorPtr::create(d));

    return id;
}

void QTextureAtlas::removeImage(TextureId id)
{
    Q_D(QTextureAtlas);
    auto it = d->m_textures.find(id);
    if (it != d->m_textures.end()) {
        QRect imgRect = it->position;
        imgRect.adjust(-it->padding, -it->padding, 2*it->padding, 2*it->padding);

        if (d->m_allocator)
            d->m_allocator->deallocate(imgRect);
        d->m_textures.erase(it);
    }
}

bool QTextureAtlas::hasImage(TextureId id) const
{
    Q_D(const QTextureAtlas);
    return d->m_textures.contains(id);
}

int QTextureAtlas::imageCount() const
{
    Q_D(const QTextureAtlas);
    return d->m_textures.size();
}

QRect QTextureAtlas::imagePosition(TextureId id) const
{
    Q_D(const QTextureAtlas);
    const auto it = d->m_textures.find(id);
    return (it != d->m_textures.cend()) ? it->position : QRect();
}

QRectF QTextureAtlas::imageTexCoords(TextureId id) const
{
    Q_D(const QTextureAtlas);
    const auto it = d->m_textures.find(id);
    if (it != d->m_textures.cend()) {
        const float w = d->m_data->width();
        const float h = d->m_data->height();
        return QRectF(static_cast<float>(it->position.x()) / w,
                      static_cast<float>(it->position.y()) / h,
                      static_cast<float>(it->position.width()) / w,
                      static_cast<float>(it->position.height()) / h);
    }
    return QRectF();
}

int QTextureAtlas::imagePadding(TextureId id) const
{
    Q_D(const QTextureAtlas);
    const auto it = d->m_textures.find(id);
    return (it != d->m_textures.cend()) ? it->padding : -1;
}

} // namespace Qt3DExtras

QT_END_NAMESPACE
