/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick 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 "qquickshadereffectmesh_p.h"
#include <QtQuick/qsggeometry.h>
#include "qquickshadereffect_p.h"
#include "qquickscalegrid_p_p.h"
#include "qquickborderimage_p_p.h"
#include <QtQuick/private/qsgbasicinternalimagenode_p.h>

QT_BEGIN_NAMESPACE

static const char qt_position_attribute_name[] = "qt_Vertex";
static const char qt_texcoord_attribute_name[] = "qt_MultiTexCoord0";

const char *qtPositionAttributeName()
{
    return qt_position_attribute_name;
}

const char *qtTexCoordAttributeName()
{
    return qt_texcoord_attribute_name;
}

QQuickShaderEffectMesh::QQuickShaderEffectMesh(QObject *parent)
    : QObject(parent)
{
}

QQuickShaderEffectMesh::QQuickShaderEffectMesh(QObjectPrivate &dd, QObject *parent)
    : QObject(dd, parent)
{
}

/*!
    \qmltype GridMesh
    \instantiates QQuickGridMesh
    \inqmlmodule QtQuick
    \since 5.0
    \ingroup qtquick-effects
    \brief Defines a mesh with vertices arranged in a grid.

    GridMesh defines a rectangular mesh consisting of vertices arranged in an
    evenly spaced grid. It is used to generate \l{QSGGeometry}{geometry}.
    The grid resolution is specified with the \l resolution property.
*/

QQuickGridMesh::QQuickGridMesh(QObject *parent)
    : QQuickShaderEffectMesh(parent)
    , m_resolution(1, 1)
{
}

bool QQuickGridMesh::validateAttributes(const QVector<QByteArray> &attributes, int *posIndex)
{
    const int attrCount = attributes.count();
    int positionIndex = attributes.indexOf(qtPositionAttributeName());
    int texCoordIndex = attributes.indexOf(qtTexCoordAttributeName());

    switch (attrCount) {
    case 0:
        m_log = QLatin1String("Error: No attributes specified.");
        return false;
    case 1:
        if (positionIndex != 0) {
            m_log = QLatin1String("Error: Missing \'") + QLatin1String(qtPositionAttributeName())
                    + QLatin1String("\' attribute.\n");
            return false;
        }
        break;
    case 2:
        if (positionIndex == -1 || texCoordIndex == -1) {
            m_log.clear();
            if (positionIndex == -1) {
                m_log = QLatin1String("Error: Missing \'") + QLatin1String(qtPositionAttributeName())
                        + QLatin1String("\' attribute.\n");
            }
            if (texCoordIndex == -1) {
                m_log += QLatin1String("Error: Missing \'") + QLatin1String(qtTexCoordAttributeName())
                         + QLatin1String("\' attribute.\n");
            }
            return false;
        }
        break;
    default:
        m_log = QLatin1String("Error: Too many attributes specified.");
        return false;
    }

    if (posIndex)
        *posIndex = positionIndex;

    return true;
}

QSGGeometry *QQuickGridMesh::updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex,
                                            const QRectF &srcRect, const QRectF &dstRect)
{
    int vmesh = m_resolution.height();
    int hmesh = m_resolution.width();

    if (!geometry) {
        Q_ASSERT(attrCount == 1 || attrCount == 2);
        geometry = new QSGGeometry(attrCount == 1
                                   ? QSGGeometry::defaultAttributes_Point2D()
                                   : QSGGeometry::defaultAttributes_TexturedPoint2D(),
                                   (vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2),
                                   QSGGeometry::UnsignedShortType);

    } else {
        geometry->allocate((vmesh + 1) * (hmesh + 1), vmesh * 2 * (hmesh + 2));
    }

    QSGGeometry::Point2D *vdata = static_cast<QSGGeometry::Point2D *>(geometry->vertexData());

    for (int iy = 0; iy <= vmesh; ++iy) {
        float fy = iy / float(vmesh);
        float y = float(dstRect.top()) + fy * float(dstRect.height());
        float ty = float(srcRect.top()) + fy * float(srcRect.height());
        for (int ix = 0; ix <= hmesh; ++ix) {
            float fx = ix / float(hmesh);
            for (int ia = 0; ia < attrCount; ++ia) {
                if (ia == posIndex) {
                    vdata->x = float(dstRect.left()) + fx * float(dstRect.width());
                    vdata->y = y;
                    ++vdata;
                } else {
                    vdata->x = float(srcRect.left()) + fx * float(srcRect.width());
                    vdata->y = ty;
                    ++vdata;
                }
            }
        }
    }

    quint16 *indices = (quint16 *)geometry->indexDataAsUShort();
    int i = 0;
    for (int iy = 0; iy < vmesh; ++iy) {
        *(indices++) = i + hmesh + 1;
        for (int ix = 0; ix <= hmesh; ++ix, ++i) {
            *(indices++) = i + hmesh + 1;
            *(indices++) = i;
        }
        *(indices++) = i - 1;
    }

    return geometry;
}

/*!
    \qmlproperty size QtQuick::GridMesh::resolution

    This property holds the grid resolution. The resolution's width and height
    specify the number of cells or spacings between vertices horizontally and
    vertically respectively. The minimum and default is 1x1, which corresponds
    to four vertices in total, one in each corner.
    For non-linear vertex transformations, you probably want to set the
    resolution higher.

    \table
    \row
    \li \image declarative-gridmesh.png
    \li \qml
        import QtQuick 2.0

        ShaderEffect {
            width: 200
            height: 200
            mesh: GridMesh {
                resolution: Qt.size(20, 20)
            }
            property variant source: Image {
                source: "qt-logo.png"
                sourceSize { width: 200; height: 200 }
            }
            vertexShader: "
                uniform highp mat4 qt_Matrix;
                attribute highp vec4 qt_Vertex;
                attribute highp vec2 qt_MultiTexCoord0;
                varying highp vec2 qt_TexCoord0;
                uniform highp float width;
                void main() {
                    highp vec4 pos = qt_Vertex;
                    highp float d = .5 * smoothstep(0., 1., qt_MultiTexCoord0.y);
                    pos.x = width * mix(d, 1.0 - d, qt_MultiTexCoord0.x);
                    gl_Position = qt_Matrix * pos;
                    qt_TexCoord0 = qt_MultiTexCoord0;
                }"
        }
        \endqml
    \endtable
*/

void QQuickGridMesh::setResolution(const QSize &res)
{
    if (res == m_resolution)
        return;
    if (res.width() < 1 || res.height() < 1) {
        return;
    }
    m_resolution = res;
    emit resolutionChanged();
    emit geometryChanged();
}

QSize QQuickGridMesh::resolution() const
{
    return m_resolution;
}

/*!
    \qmltype BorderImageMesh
    \instantiates QQuickBorderImageMesh
    \inqmlmodule QtQuick
    \since 5.8
    \ingroup qtquick-effects
    \brief Defines a mesh with vertices arranged like those of a BorderImage.

    BorderImageMesh provides BorderImage-like capabilities to a ShaderEffect
    without the need for a potentially costly ShaderEffectSource.

    The following are functionally equivalent:
    \qml
    BorderImage {
        id: borderImage
        border {
            left: 10
            right: 10
            top: 10
            bottom: 10
        }
        source: "myImage.png"
        visible: false
    }
    ShaderEffectSource {
        id: effectSource
        sourceItem: borderImage
        visible: false
    }
    ShaderEffect {
        property var source: effectSource
        ...
    }
    \endqml

    \qml
    Image {
        id: image
        source: "myImage.png"
        visible: false
    }
    ShaderEffect {
        property var source: image
        mesh: BorderImageMesh {
            border {
                left: 10
                right: 10
                top: 10
                bottom: 10
            }
            size: image.sourceSize
        }
        ...
    }
    \endqml

    But the BorderImageMesh version can typically be better optimized.
*/
QQuickBorderImageMesh::QQuickBorderImageMesh(QObject *parent)
    : QQuickShaderEffectMesh(parent), m_border(new QQuickScaleGrid(this)),
      m_horizontalTileMode(QQuickBorderImageMesh::Stretch),
      m_verticalTileMode(QQuickBorderImageMesh::Stretch)
{
}

bool QQuickBorderImageMesh::validateAttributes(const QVector<QByteArray> &attributes, int *posIndex)
{
    Q_UNUSED(attributes);
    Q_UNUSED(posIndex);
    return true;
}

QSGGeometry *QQuickBorderImageMesh::updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex,
                                                   const QRectF &srcRect, const QRectF &rect)
{
    Q_UNUSED(attrCount);
    Q_UNUSED(posIndex);

    QRectF innerSourceRect;
    QRectF targetRect;
    QRectF innerTargetRect;
    QRectF subSourceRect;

    QQuickBorderImagePrivate::calculateRects(m_border, m_size, rect.size(), m_horizontalTileMode, m_verticalTileMode,
                                             1, &targetRect, &innerTargetRect, &innerSourceRect, &subSourceRect);

    QRectF sourceRect = srcRect;
    QRectF modifiedInnerSourceRect(sourceRect.x() + innerSourceRect.x() * sourceRect.width(),
                                   sourceRect.y() + innerSourceRect.y() * sourceRect.height(),
                                   innerSourceRect.width() * sourceRect.width(),
                                   innerSourceRect.height() * sourceRect.height());

    geometry = QSGBasicInternalImageNode::updateGeometry(targetRect, innerTargetRect, sourceRect,
                                                         modifiedInnerSourceRect, subSourceRect, geometry);

    return geometry;
}

/*!
    \qmlpropertygroup QtQuick::BorderImageMesh::border
    \qmlproperty int QtQuick::BorderImageMesh::border.left
    \qmlproperty int QtQuick::BorderImageMesh::border.right
    \qmlproperty int QtQuick::BorderImageMesh::border.top
    \qmlproperty int QtQuick::BorderImageMesh::border.bottom

    The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
    as shown below:

    \image declarative-scalegrid.png

    Each border line (left, right, top, and bottom) specifies an offset in pixels
    from the respective edge of the mesh. By default, each border line has
    a value of 0.

    For example, the following definition sets the bottom line 10 pixels up from
    the bottom of the mesh:

    \qml
    BorderImageMesh {
        border.bottom: 10
        // ...
    }
    \endqml
*/
QQuickScaleGrid *QQuickBorderImageMesh::border() const
{
    return m_border;
}

/*!
    \qmlproperty size QtQuick::BorderImageMesh::size

    The base size of the mesh. This generally corresponds to the \l {Image::}{sourceSize}
    of the image being used by the ShaderEffect.
*/
QSize QQuickBorderImageMesh::size() const
{
    return m_size;
}

void QQuickBorderImageMesh::setSize(const QSize &size)
{
    if (size == m_size)
        return;
    m_size = size;
    Q_EMIT sizeChanged();
    Q_EMIT geometryChanged();
}

/*!
    \qmlproperty enumeration QtQuick::BorderImageMesh::horizontalTileMode
    \qmlproperty enumeration QtQuick::BorderImageMesh::verticalTileMode

    This property describes how to repeat or stretch the middle parts of an image.

    \list
    \li BorderImage.Stretch - Scales the image to fit to the available area.
    \li BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
    \li BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
    \endlist

    The default tile mode for each property is BorderImage.Stretch.
*/

QQuickBorderImageMesh::TileMode QQuickBorderImageMesh::horizontalTileMode() const
{
    return m_horizontalTileMode;
}

void QQuickBorderImageMesh::setHorizontalTileMode(TileMode t)
{
    if (t == m_horizontalTileMode)
        return;
    m_horizontalTileMode = t;
    Q_EMIT horizontalTileModeChanged();
    Q_EMIT geometryChanged();
}

QQuickBorderImageMesh::TileMode QQuickBorderImageMesh::verticalTileMode() const
{
    return m_verticalTileMode;
}

void QQuickBorderImageMesh::setVerticalTileMode(TileMode t)
{
    if (t == m_verticalTileMode)
        return;

    m_verticalTileMode = t;
    Q_EMIT verticalTileModeChanged();
    Q_EMIT geometryChanged();
}

QT_END_NAMESPACE

#include "moc_qquickshadereffectmesh_p.cpp"
