/****************************************************************************
**
** Copyright (C) 2020 Paolo Angelelli <paolo.angelelli@gmail.com>
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QDECLARATIVEPOLYLINEMAPITEM_P_P_H
#define QDECLARATIVEPOLYLINEMAPITEM_P_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtLocation/private/qlocationglobal_p.h>
#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
#include <QtLocation/private/qdeclarativegeomapitemutils_p.h>
#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
#include <QtLocation/private/qgeomapitemgeometry_p.h>
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
#include <QtPositioning/QGeoPath>
#include <QtPositioning/QGeoPolygon>
#include <QtPositioning/QGeoRectangle>
#include <QtPositioning/QGeoCircle>
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtCore/QScopedValueRollback>
#include <QSharedPointer>
#include <array>

QT_BEGIN_NAMESPACE

class Q_LOCATION_PRIVATE_EXPORT QGeoMapPolylineGeometry : public QGeoMapItemGeometry
{
public:
    QGeoMapPolylineGeometry();

    void updateSourcePoints(const QGeoMap &map,
                            const QList<QDoubleVector2D> &path,
                            const QGeoCoordinate geoLeftBound);

    void updateScreenPoints(const QGeoMap &map,
                            qreal strokeWidth,
                            bool adjustTranslation = true);

    void clearSource();

    bool contains(const QPointF &point) const override;

    QList<QList<QDoubleVector2D> > clipPath(const QGeoMap &map,
                    const QList<QDoubleVector2D> &path,
                    QDoubleVector2D &leftBoundWrapped);

    void pathToScreen(const QGeoMap &map,
                      const QList<QList<QDoubleVector2D> > &clippedPaths,
                      const QDoubleVector2D &leftBoundWrapped);

public:
    QVector<qreal> srcPoints_;
    QVector<QPainterPath::ElementType> srcPointTypes_;

#ifdef QT_LOCATION_DEBUG
    QList<QDoubleVector2D> m_wrappedPath;
    QList<QList<QDoubleVector2D>> m_clippedPaths;
#endif

    friend class QDeclarativeCircleMapItem;
    friend class QDeclarativePolygonMapItem;
    friend class QDeclarativeRectangleMapItem;
};

class Q_LOCATION_PRIVATE_EXPORT VisibleNode
{
public:
    VisibleNode();
    virtual ~VisibleNode();

    bool subtreeBlocked() const;
    void setSubtreeBlocked(bool blocked);
    bool visible() const;
    void setVisible(bool visible);

    bool m_blocked : 1;
    bool m_visible : 1;
};

class Q_LOCATION_PRIVATE_EXPORT MapItemGeometryNode : public QSGGeometryNode, public VisibleNode
{
public:
    ~MapItemGeometryNode() override;
    bool isSubtreeBlocked() const override;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineMaterial : public QSGFlatColorMaterial
{
public:
    MapPolylineMaterial()
        : QSGFlatColorMaterial()
    {
        // Passing RequiresFullMatrix is essential in order to prevent the
        // batch renderer from baking in simple, translate-only transforms into
        // the vertex data. The shader will rely on the fact that
        // vertexCoord.xy is the Shape-space coordinate and so no modifications
        // are welcome.
        setFlag(Blending | RequiresFullMatrix | CustomCompileStep);
    }

    QSGMaterialShader *createShader() const override;

    void setGeoProjection(const QMatrix4x4 &p)
    {
        m_geoProjection = p;
    }

    QMatrix4x4 geoProjection() const
    {
        return m_geoProjection;
    }

    void setCenter(const QDoubleVector3D &c)
    {
        m_center = c;
    }

    QDoubleVector3D center() const
    {
        return m_center;
    }

    void setColor(const QColor &color)
    {
        QSGFlatColorMaterial::setColor(color);
        setFlag(Blending, true); // ToDo: Needed only temporarily, can be removed after debugging
    }

    int wrapOffset() const
    {
        return m_wrapOffset;
    }

    void setWrapOffset(int wrapOffset)
    {
        m_wrapOffset = wrapOffset;
    }

    void setLineWidth(const float lw)
    {
        m_lineWidth = lw;
    }

    float lineWidth() const
    {
        return m_lineWidth;
    }

    QSGMaterialType *type() const override;
    int compare(const QSGMaterial *other) const override;

protected:
    QMatrix4x4 m_geoProjection;
    QDoubleVector3D m_center;
    int m_wrapOffset = 0;
    float m_lineWidth = 1.0;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineNode : public MapItemGeometryNode
{
public:
    MapPolylineNode();
    ~MapPolylineNode() override;

    void update(const QColor &fillColor, const QGeoMapItemGeometry *shape);

protected:
    QSGFlatColorMaterial fill_material_;
    QSGGeometry geometry_;
};

class Q_LOCATION_PRIVATE_EXPORT QGeoMapItemLODGeometry
{
public:
    mutable std::array<QSharedPointer<QVector<QDeclarativeGeoMapItemUtils::vec2>>, 7> m_verticesLOD; // fix it to 7,
                                                                             // do not allow simplifications beyond ZL 20. This could actually be limited even further
    mutable QVector<QDeclarativeGeoMapItemUtils::vec2> *m_screenVertices;
    mutable QSharedPointer<unsigned int> m_working;

    QGeoMapItemLODGeometry()
    {
        resetLOD();
    }

    void resetLOD()
    {
        // New pointer, some old LOD task might still be running and operating on the old pointers.
        m_verticesLOD[0] = QSharedPointer<QVector<QDeclarativeGeoMapItemUtils::vec2>>(
                            new QVector<QDeclarativeGeoMapItemUtils::vec2>);
        for (unsigned int i = 1; i < m_verticesLOD.size(); ++i)
            m_verticesLOD[i] = nullptr; // allocate on first use
        m_screenVertices = m_verticesLOD.front().data(); // resetting pointer to data to be LOD 0
    }

    static unsigned int zoomToLOD(unsigned int zoom);

    static unsigned int zoomForLOD(unsigned int zoom);

    bool isLODActive(unsigned int lod) const;

    void selectLOD(unsigned int zoom, double leftBound, bool /*closed*/);

    static QVector<QDeclarativeGeoMapItemUtils::vec2> getSimplified (
            QVector<QDeclarativeGeoMapItemUtils::vec2> &wrappedPath,
                              double leftBoundWrapped,
                              unsigned int zoom);

    static void enqueueSimplificationTask(const QSharedPointer<QVector<QDeclarativeGeoMapItemUtils::vec2> > &input, // reference as it gets copied in the nested call
                              const QSharedPointer<QVector<QDeclarativeGeoMapItemUtils::vec2> > &output,
                              double leftBound,
                              unsigned int zoom,
                              QSharedPointer<unsigned int> &working);

    void selectLODOnDataChanged(unsigned int zoom, double leftBound) const;

    bool selectLODOnLODMismatch(unsigned int zoom, double leftBound, bool closed) const
    {
        if (*m_working > 0) {
            return false;
        }
        const_cast<QGeoMapItemLODGeometry *>(this)->selectLOD(zoom,
                 leftBound,
                 closed);
        return true;
    }
};

class Q_LOCATION_PRIVATE_EXPORT QGeoMapPolylineGeometryOpenGL : public QGeoMapItemGeometry, public QGeoMapItemLODGeometry
{
public:
    typedef struct {
        QList<QDoubleVector2D> wrappedBboxes;
    } WrappedPolyline;

    QGeoMapPolylineGeometryOpenGL()
    {
        m_working = QSharedPointer<unsigned int>(new unsigned int(0));
    }

    void updateSourcePoints(const QGeoMap &map,
                            const QGeoPolygon &poly);

    void updateSourcePoints(const QGeoMap &map,
                            const QGeoPath &poly);

    void updateSourcePoints(const QGeoProjectionWebMercator &p,
                            const QList<QDoubleVector2D> &wrappedPath,
                            const QGeoRectangle &boundingRectangle);

    void updateSourcePoints(const QGeoMap &map,
                            const QGeoRectangle &rect);

    void updateSourcePoints(const QGeoMap &map,
                            const QGeoCircle &circle);

    void updateScreenPoints(const QGeoMap &map,
                            qreal strokeWidth,
                            bool adjustTranslation = true);

    void updateQuickGeometry(const QGeoProjectionWebMercator &p, qreal strokeWidth = 0.0);

    bool allocateAndFillEntries(QSGGeometry *geom,
                                bool closed = false,
                                unsigned int zoom = 0) const;
    void allocateAndFillLineStrip(QSGGeometry *geom,
                                  int lod = 0) const;

    bool contains(const QPointF &point) const override
    {
        Q_UNUSED(point)
        return false;
    }

    static double distanceTo(const QDoubleVector2D &a, const QDoubleVector2D &b, const QDoubleVector2D &p)
    {
        double u = ((p.x() - a.x()) * (b.x() - a.x()) + (p.y() - a.y()) * (b.y() - a.y()) ) / (b - a).lengthSquared();
        QDoubleVector2D intersection(a.x() + u * (b.x() - a.x()) , a.y() + u * (b.y() - a.y()) );

        QDoubleVector2D candidate = ( (p-a).length() < (p-b).length() ) ? a : b;

        if (u > 0 && u < 1
            && (p-intersection).length() < (p-candidate).length()  ) // And it falls in the segment
                candidate = intersection;

        return qAbs((candidate - p).length());
    }
    // Note: this is also slightly incorrect on joins and in the beginning/end of the line
    bool contains(const QPointF &point, qreal lineWidth, const QGeoProjectionWebMercator &p) const
    {
        const double lineHalfWidth = lineWidth * 0.5;
        const QDoubleVector2D pt(point);
        QDoubleVector2D a;
        if (m_screenVertices->size())
            a = p.wrappedMapProjectionToItemPosition(p.wrapMapProjection(m_screenVertices->first().toDoubleVector2D()));
        QDoubleVector2D b;
        for (int i = 1; i < m_screenVertices->size(); ++i)
        {
            if (!a.isFinite()) {
                a = p.wrappedMapProjectionToItemPosition(p.wrapMapProjection(m_screenVertices->at(i).toDoubleVector2D()));
                continue;
            }

            b = p.wrappedMapProjectionToItemPosition(p.wrapMapProjection(m_screenVertices->at(i).toDoubleVector2D()));
            if (!b.isFinite()) {
                a = b;
                continue;
            }

            if (b == a)
                continue;

            // Heavily simplifying it here: if a point is not projectable, skip the segment.
            // For a correct solution, the segment should be clipped instead.
            if (distanceTo(a, b, pt) <= lineHalfWidth)
                return true;

            a = b;
        }
        return false;
    }

public:
    QDoubleVector2D m_bboxLeftBoundWrapped;
    QVector<WrappedPolyline> m_wrappedPolygons;
    int m_wrapOffset;

    friend class QDeclarativeCircleMapItem;
    friend class QDeclarativePolygonMapItem;
    friend class QDeclarativeRectangleMapItem;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineShaderLineStrip : public QSGMaterialShader
{
public:
    MapPolylineShaderLineStrip();

    const char *vertexShader() const override {
        return
        "attribute highp vec4 vertex;               \n"
        "uniform highp mat4 qt_Matrix;              \n"
        "uniform highp mat4 mapProjection;          \n"
        "uniform highp vec3 center;                 \n"
        "uniform highp vec3 center_lowpart;         \n"
        "uniform lowp float wrapOffset;             \n"
        "vec4 wrapped(in vec4 v) { return vec4(v.x + wrapOffset, v.y, 0.0, 1.0); }\n"
        "void main() {                              \n"
        "    vec4 vtx = wrapped(vertex) - vec4(center, 0.0);   \n"
        "    vtx = vtx - vec4(center_lowpart, 0.0);   \n"
        "    gl_Position = qt_Matrix * mapProjection * vtx;      \n"
        "}";
    }

    const char *fragmentShader() const override {
        return
        "uniform lowp vec4 color;                   \n"
        "void main() {                              \n"
        "    gl_FragColor = color;                  \n"
        "}";
    }

    void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
    char const *const *attributeNames() const override;

protected:
    void initialize() override
    {
        m_matrix_id = program()->uniformLocation("qt_Matrix");
        m_color_id = program()->uniformLocation("color");
        m_mapProjection_id = program()->uniformLocation("mapProjection");
        m_center_id = program()->uniformLocation("center");
        m_center_lowpart_id = program()->uniformLocation("center_lowpart");
        m_wrapOffset_id = program()->uniformLocation("wrapOffset");
    }
    int m_center_id;
    int m_center_lowpart_id;
    int m_mapProjection_id;
    int m_matrix_id;
    int m_color_id;
    int m_wrapOffset_id;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineShaderExtruded : public QSGMaterialShader
{
public:
    MapPolylineShaderExtruded();

    // Heavily adapted from https://github.com/mattdesl/webgl-lines/blob/master/projected/vert.glsl,
    // that is (c) Matt DesLauriers, and released under the MIT license.
    const char *vertexShaderMiteredSegments() const;

    const char *vertexShader() const override
    {
        return vertexShaderMiteredSegments();
    }

    const char *fragmentShader() const override
    {
        return
        "varying vec4 primitivecolor;           \n"
        "void main() {                          \n"
        "    gl_FragColor = primitivecolor;     \n"
        "}";
    }

    void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
    char const *const *attributeNames() const override;

protected:
    void initialize() override
    {
        m_matrix_id = program()->uniformLocation("qt_Matrix");
        m_color_id = program()->uniformLocation("color");
        m_mapProjection_id = program()->uniformLocation("mapProjection");
        m_center_id = program()->uniformLocation("center");
        m_center_lowpart_id = program()->uniformLocation("center_lowpart");
        m_lineWidth_id = program()->uniformLocation("lineWidth");
        m_aspect_id = program()->uniformLocation("aspect");
        m_miter_id = program()->uniformLocation("miter");
        m_wrapOffset_id = program()->uniformLocation("wrapOffset");
    }
    int m_center_id;
    int m_center_lowpart_id;
    int m_mapProjection_id;
    int m_matrix_id;
    int m_color_id;
    int m_lineWidth_id;
    int m_aspect_id;
    int m_miter_id;
    int m_wrapOffset_id;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineNodeOpenGLLineStrip : public MapItemGeometryNode
{
public:
    MapPolylineNodeOpenGLLineStrip();
    ~MapPolylineNodeOpenGLLineStrip() override;

    void update(const QColor &fillColor,
                const qreal lineWidth,
                const QGeoMapPolylineGeometryOpenGL *shape,
                const QMatrix4x4 &geoProjection,
                const QDoubleVector3D &center,
                const Qt::PenCapStyle capStyle = Qt::SquareCap);

protected:
    MapPolylineMaterial fill_material_;
    QSGGeometry geometry_;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineMaterialExtruded : public MapPolylineMaterial
{
public:
    MapPolylineMaterialExtruded() : MapPolylineMaterial()
    {

    }
    QSGMaterialShader *createShader() const override;

    void setMiter(const int m)
    {
        m_miter = m;
    }

    int miter() const
    {
        return m_miter;
    }

    QSGMaterialType *type() const override;
    int compare(const QSGMaterial *other) const override;

    int m_miter = 0;
};

class Q_LOCATION_PRIVATE_EXPORT MapPolylineNodeOpenGLExtruded : public MapItemGeometryNode
{
public:

    typedef struct {
         QDeclarativeGeoMapItemUtils::vec2 pos;
         QDeclarativeGeoMapItemUtils::vec2 prev;
         QDeclarativeGeoMapItemUtils::vec2 next;
         float direction;
         float triangletype; // es2 does not support int attribs
         float vertextype;

         static const char * const *attributeNames()
         {
             static char const *const attr[] = { "vertex", "previous", "next", "direction", "triangletype", "vertextype", nullptr };
             return attr;
         }
         static const QSGGeometry::AttributeSet &attributes()
         {
             static const QSGGeometry::Attribute dataTri[] = {
                 QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType, QSGGeometry::PositionAttribute) // pos
                 ,QSGGeometry::Attribute::createWithAttributeType(1, 2, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // next
                 ,QSGGeometry::Attribute::createWithAttributeType(2, 2, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute) // previous
                 ,QSGGeometry::Attribute::createWithAttributeType(3, 1, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute)  // direction
                 ,QSGGeometry::Attribute::createWithAttributeType(4, 1, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute)  // triangletype
                 ,QSGGeometry::Attribute::createWithAttributeType(5, 1, QSGGeometry::FloatType, QSGGeometry::UnknownAttribute)  // vertextype
             };
             static const QSGGeometry::AttributeSet attrsTri = { 6, sizeof(MapPolylineNodeOpenGLExtruded::MapPolylineEntry), dataTri };
             return attrsTri;
         }
    } MapPolylineEntry;

    MapPolylineNodeOpenGLExtruded();
    ~MapPolylineNodeOpenGLExtruded() override;

    void update(const QColor &fillColor,
                const float lineWidth,
                const QGeoMapPolylineGeometryOpenGL *shape,
                const QMatrix4x4 geoProjection,
                const QDoubleVector3D center,
                const Qt::PenCapStyle capStyle = Qt::FlatCap,
                bool closed = false,
                unsigned int zoom = 30);

    static const QSGGeometry::AttributeSet &attributesMapPolylineTriangulated();

protected:
    MapPolylineMaterialExtruded fill_material_;
    QSGGeometry m_geometryTriangulating;
};

class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivate
{
public:
    QDeclarativePolylineMapItemPrivate(QDeclarativePolylineMapItem &poly) : m_poly(poly)
    {

    }
    QDeclarativePolylineMapItemPrivate(QDeclarativePolylineMapItemPrivate &other) : m_poly(other.m_poly)
    {
    }

    virtual ~QDeclarativePolylineMapItemPrivate();
    virtual void markSourceDirtyAndUpdate() = 0;
    virtual void onMapSet() = 0;
    virtual void onLinePropertiesChanged() = 0;
    virtual void onGeoGeometryChanged() = 0;
    virtual void onGeoGeometryUpdated() = 0;
    virtual void onItemGeometryChanged() = 0;
    virtual void updatePolish() = 0;
    virtual void afterViewportChanged() = 0;
    virtual QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) = 0;
    virtual bool contains(const QPointF &point) const = 0;

    QDeclarativePolylineMapItem &m_poly;
    Qt::PenStyle m_penStyle = Qt::SolidLine;
    Qt::PenCapStyle m_penCapStyle = Qt::SquareCap;
};

class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivateCPU: public QDeclarativePolylineMapItemPrivate
{
public:
    QDeclarativePolylineMapItemPrivateCPU(QDeclarativePolylineMapItem &poly) : QDeclarativePolylineMapItemPrivate(poly)
    {
    }

    QDeclarativePolylineMapItemPrivateCPU(QDeclarativePolylineMapItemPrivate &other)
    : QDeclarativePolylineMapItemPrivate(other)
    {
    }

    ~QDeclarativePolylineMapItemPrivateCPU() override;
    void onLinePropertiesChanged() override
    {
        // mark dirty just in case we're a width change
        markSourceDirtyAndUpdate();
    }
    void markSourceDirtyAndUpdate() override
    {
        m_geometry.markSourceDirty();
        m_poly.polishAndUpdate();
    }
    void regenerateCache()
    {
        if (!m_poly.map() || m_poly.map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
            return;
        const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_poly.map()->geoProjection());
        m_geopathProjected.clear();
        m_geopathProjected.reserve(m_poly.m_geopath.size());
        for (const QGeoCoordinate &c : m_poly.m_geopath.path())
            m_geopathProjected << p.geoToMapProjection(c);
    }
    void updateCache()
    {
        if (!m_poly.map() || m_poly.map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
            return;
        const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_poly.map()->geoProjection());
        m_geopathProjected << p.geoToMapProjection(m_poly.m_geopath.path().last());
    }
    void preserveGeometry()
    {
        m_geometry.setPreserveGeometry(true, m_poly.m_geopath.boundingGeoRectangle().topLeft());
    }
    void afterViewportChanged() override
    {
        // preserveGeometry is cleared in updateMapItemPaintNode
        preserveGeometry();
        markSourceDirtyAndUpdate();
    }
    void onMapSet() override
    {
        regenerateCache();
        markSourceDirtyAndUpdate();
    }
    void onGeoGeometryChanged() override
    {
        regenerateCache();
        preserveGeometry();
        markSourceDirtyAndUpdate();
    }
    void onGeoGeometryUpdated() override
    {
        updateCache();
        preserveGeometry();
        markSourceDirtyAndUpdate();
    }
    void onItemGeometryChanged() override
    {
        onGeoGeometryChanged();
    }
    void updatePolish() override
    {
        if (m_poly.m_geopath.path().length() < 2) { // Possibly cleared
            m_geometry.clear();
            m_poly.setWidth(0);
            m_poly.setHeight(0);
            return;
        }
        QScopedValueRollback<bool> rollback(m_poly.m_updatingGeometry);
        m_poly.m_updatingGeometry = true;

        const QGeoMap *map = m_poly.map();
        const qreal borderWidth = m_poly.m_line.width();

        m_geometry.updateSourcePoints(*map, m_geopathProjected, m_poly.m_geopath.boundingGeoRectangle().topLeft());
        m_geometry.updateScreenPoints(*map, borderWidth);

        m_poly.setWidth(m_geometry.sourceBoundingBox().width() + borderWidth);
        m_poly.setHeight(m_geometry.sourceBoundingBox().height() + borderWidth);

        m_poly.setPositionOnMap(m_geometry.origin(), -1 * m_geometry.sourceBoundingBox().topLeft()
                                + QPointF(borderWidth, borderWidth) * 0.5 ); // it has to be shifted so that the center of the line is on the correct geocoord
    }
    QSGNode *updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData * /*data*/) override
    {
        if (!m_node || !oldNode) {
            m_node = new MapPolylineNode();
            if (oldNode) {
                delete oldNode;
                oldNode = nullptr;
            }
        } else {
            m_node = static_cast<MapPolylineNode *>(oldNode);
        }

        //TODO: update only material
        if (m_geometry.isScreenDirty() || m_poly.m_dirtyMaterial || !oldNode) {
            m_node->update(m_poly.m_line.color(), &m_geometry);
            m_geometry.setPreserveGeometry(false);
            m_geometry.markClean();
            m_poly.m_dirtyMaterial = false;
        }
        return m_node;
    }
    bool contains(const QPointF &point) const override
    {
        return m_geometry.contains(point);
    }

    QList<QDoubleVector2D> m_geopathProjected;
    QGeoMapPolylineGeometry m_geometry;
    MapPolylineNode *m_node = nullptr;
};

class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivateOpenGLLineStrip: public QDeclarativePolylineMapItemPrivate
{
public:

    QDeclarativePolylineMapItemPrivateOpenGLLineStrip(QDeclarativePolylineMapItem &poly) : QDeclarativePolylineMapItemPrivate(poly)
    {
    }

    QDeclarativePolylineMapItemPrivateOpenGLLineStrip(QDeclarativePolylineMapItemPrivate &other)
    : QDeclarativePolylineMapItemPrivate(other)
    {
    }

    ~QDeclarativePolylineMapItemPrivateOpenGLLineStrip() override;
    void onLinePropertiesChanged() override
    {
        afterViewportChanged();
    }
    void markSourceDirtyAndUpdate() override
    {
        m_geometry.markSourceDirty();
        m_poly.polishAndUpdate();
    }
    void preserveGeometry()
    {
        m_geometry.setPreserveGeometry(true, m_poly.m_geopath.boundingGeoRectangle().topLeft());
    }
    void onMapSet() override
    {
        markSourceDirtyAndUpdate();
    }
    void onGeoGeometryChanged() override
    {
        preserveGeometry();
        markSourceDirtyAndUpdate();
    }
    void onGeoGeometryUpdated() override
    {
        preserveGeometry();
        markSourceDirtyAndUpdate();
    }
    void onItemGeometryChanged() override
    {
        onGeoGeometryChanged();
    }
    void afterViewportChanged() override
    {
        preserveGeometry();
        m_poly.polishAndUpdate();
    }
    bool contains(const QPointF &point) const override
    {
        return m_geometry.contains(m_poly.mapToItem(m_poly.quickMap(), point),
                                   m_poly.line()->width(),
                                   static_cast<const QGeoProjectionWebMercator&>(m_poly.map()->geoProjection()));
    }
    void updatePolish() override
    {
        if (m_poly.m_geopath.path().length() == 0) { // Possibly cleared
            m_geometry.clear();
            m_geometry.clear();
            m_poly.setWidth(0);
            m_poly.setHeight(0);
            return;
        }

        QScopedValueRollback<bool> rollback(m_poly.m_updatingGeometry);
        m_poly.m_updatingGeometry = true;
        const qreal lineWidth = m_poly.m_line.width();
        m_geometry.updateSourcePoints(*m_poly.map(), m_poly.m_geopath);
        m_geometry.markScreenDirty();
        m_geometry.updateScreenPoints(*m_poly.map(), lineWidth);

        m_poly.setWidth(m_geometry.sourceBoundingBox().width());
        m_poly.setHeight(m_geometry.sourceBoundingBox().height());
        m_poly.setPosition(1.0 * m_geometry.firstPointOffset() - QPointF(lineWidth * 0.5,lineWidth * 0.5));
    }
    QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override
    {
        Q_UNUSED(data);

        if (!m_node || !oldNode) {
            m_node = new MapPolylineNodeOpenGLLineStrip();
            if (oldNode)
                delete oldNode;
        } else {
            m_node = static_cast<MapPolylineNodeOpenGLLineStrip *>(oldNode);
        }

        if (m_geometry.isScreenDirty() || m_poly.m_dirtyMaterial) {
            const QGeoMap *map = m_poly.map();
            const QMatrix4x4 &combinedMatrix = map->geoProjection().qsgTransform();
            const QDoubleVector3D &cameraCenter = map->geoProjection().centerMercator();
            m_node->update(m_poly.m_line.color(), // This updates only the material if the geometry is unchanged
                           m_poly.m_line.width(),
                         &m_geometry,
                         combinedMatrix,
                         cameraCenter);
            m_geometry.setPreserveGeometry(false);
            m_geometry.markClean();
            m_poly.m_dirtyMaterial = false;
        }
        return m_node;
    }

    QGeoMapPolylineGeometryOpenGL m_geometry;
    MapPolylineNodeOpenGLLineStrip *m_node = nullptr;
};

class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivateOpenGLExtruded: public QDeclarativePolylineMapItemPrivateOpenGLLineStrip
{
public:

    QDeclarativePolylineMapItemPrivateOpenGLExtruded(QDeclarativePolylineMapItem &poly)
    : QDeclarativePolylineMapItemPrivateOpenGLLineStrip(poly)
    {
    }

    QDeclarativePolylineMapItemPrivateOpenGLExtruded(QDeclarativePolylineMapItemPrivate &other)
    : QDeclarativePolylineMapItemPrivateOpenGLLineStrip(other)
    {
    }

    ~QDeclarativePolylineMapItemPrivateOpenGLExtruded() override;

    QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override
    {
        Q_UNUSED(data);
        const QGeoMap *map = m_poly.map();
        const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map->geoProjection());
        const QMatrix4x4 &combinedMatrix = p.qsgTransform();
        const QDoubleVector3D &cameraCenter = p.centerMercator();
        const QColor &color = m_poly.m_line.color();
        const float lineWidth = m_poly.m_line.width();

        MapPolylineNodeOpenGLExtruded *nodeTri = nullptr;
        if (!m_nodeTri || !oldNode) {
            if (oldNode)
                delete oldNode;
            nodeTri = new MapPolylineNodeOpenGLExtruded();
        } else {
            nodeTri = static_cast<MapPolylineNodeOpenGLExtruded *>(oldNode);
        }

        //TODO: update only material
        if (m_geometry.isScreenDirty() || m_poly.m_dirtyMaterial) {
            nodeTri->update(color,
                         lineWidth  ,
                         &m_geometry,
                         combinedMatrix,
                         cameraCenter,
                         m_penCapStyle,
                         false,
                         m_poly.zoomForLOD(int(map->cameraData().zoomLevel())));
            m_geometry.setPreserveGeometry(false);
            m_geometry.markClean();
            m_poly.m_dirtyMaterial = false;
        }
        m_nodeTri = nodeTri;
        return nodeTri;
    }

    MapPolylineNodeOpenGLExtruded *m_nodeTri = nullptr;
};

QT_END_NAMESPACE

#endif // QDECLARATIVEPOLYLINEMAPITEM_P_P_H
