/****************************************************************************
**
** 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 QDECLARATIVERECTANGLEMAPITEM_P_P_H
#define QDECLARATIVERECTANGLEMAPITEM_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/qdeclarativepolygonmapitem_p_p.h>
#include <QtLocation/private/qdeclarativerectanglemapitem_p.h>
#include <QtPositioning/private/qwebmercator_p.h>

QT_BEGIN_NAMESPACE

class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItemPrivate
{
public:
    QDeclarativeRectangleMapItemPrivate(QDeclarativeRectangleMapItem &rect) : m_rect(rect)
    {

    }
    QDeclarativeRectangleMapItemPrivate(QDeclarativeRectangleMapItemPrivate &other) : m_rect(other.m_rect)
    {
    }

    virtual ~QDeclarativeRectangleMapItemPrivate();
    virtual void onLinePropertiesChanged() = 0;
    virtual void markSourceDirtyAndUpdate() = 0;
    virtual void onMapSet() = 0;
    virtual void onGeoGeometryChanged() = 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;

    QDeclarativeRectangleMapItem &m_rect;
};

class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItemPrivateCPU: public QDeclarativeRectangleMapItemPrivate
{
public:
    QDeclarativeRectangleMapItemPrivateCPU(QDeclarativeRectangleMapItem &rect) : QDeclarativeRectangleMapItemPrivate(rect)
    {
    }

    QDeclarativeRectangleMapItemPrivateCPU(QDeclarativeRectangleMapItemPrivate &other)
    : QDeclarativeRectangleMapItemPrivate(other)
    {
    }

    ~QDeclarativeRectangleMapItemPrivateCPU() override;

    void onLinePropertiesChanged() override
    {
        // mark dirty just in case we're a width change
        markSourceDirtyAndUpdate();
    }
    virtual void markSourceDirtyAndUpdate() override
    {
        m_geometry.markSourceDirty();
        m_borderGeometry.markSourceDirty();
        m_rect.polishAndUpdate();
    }
    virtual void onMapSet() override
    {
        markSourceDirtyAndUpdate();
    }
    virtual void onGeoGeometryChanged() override
    {
        markSourceDirtyAndUpdate();
    }
    virtual void onItemGeometryChanged() override
    {
        m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
        m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
        markSourceDirtyAndUpdate();
    }
    virtual void afterViewportChanged() override
    {
        m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
        m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
        markSourceDirtyAndUpdate();
    }
    virtual void updatePolish() override
    {
        if (!m_rect.topLeft().isValid() || !m_rect.bottomRight().isValid()) {
            m_geometry.clear();
            m_borderGeometry.clear();
            m_rect.setWidth(0);
            m_rect.setHeight(0);
            return;
        }

        const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_rect.map()->geoProjection());

        QScopedValueRollback<bool> rollback(m_rect.m_updatingGeometry);
        m_rect.m_updatingGeometry = true;

        const QList<QGeoCoordinate> perimeter = path(m_rect.m_rectangle);
        const QList<QDoubleVector2D> pathMercator_ = pathMercator(perimeter);
        m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
        m_geometry.updateSourcePoints(*m_rect.map(), pathMercator_);
        m_geometry.updateScreenPoints(*m_rect.map(), m_rect.m_border.width());

        QList<QGeoMapItemGeometry *> geoms;
        geoms << &m_geometry;
        m_borderGeometry.clear();

        if (m_rect.m_border.color().alpha() != 0 && m_rect.m_border.width() > 0) {
            QList<QDoubleVector2D> closedPath = pathMercator_;
            closedPath << closedPath.first();

            m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
            const QGeoCoordinate &geometryOrigin = m_geometry.origin();

            m_borderGeometry.srcPoints_.clear();
            m_borderGeometry.srcPointTypes_.clear();

            QDoubleVector2D borderLeftBoundWrapped;
            QList<QList<QDoubleVector2D > > clippedPaths = m_borderGeometry.clipPath(*m_rect.map(), closedPath, borderLeftBoundWrapped);
            if (clippedPaths.size()) {
                borderLeftBoundWrapped = p.geoToWrappedMapProjection(geometryOrigin);
                m_borderGeometry.pathToScreen(*m_rect.map(), clippedPaths, borderLeftBoundWrapped);
                m_borderGeometry.updateScreenPoints(*m_rect.map(), m_rect.m_border.width());

                geoms << &m_borderGeometry;
            } else {
                m_borderGeometry.clear();
            }
        }

        QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
        m_rect.setWidth(combined.width()  + 2 * m_rect.m_border.width()); // ToDo: fix this! 2 is incorrect
        m_rect.setHeight(combined.height()  + 2 * m_rect.m_border.width());

        m_rect.setPositionOnMap(m_geometry.origin(), m_geometry.firstPointOffset());
    }

    virtual QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override
    {
        Q_UNUSED(data);
        if (!m_node || !oldNode) {
            m_node = new MapPolygonNode();
            if (oldNode) {
                delete oldNode;
                oldNode = nullptr;
            }
        } else {
            m_node = static_cast<MapPolygonNode *>(oldNode);
        }

        //TODO: update only material
        if (m_geometry.isScreenDirty() || m_borderGeometry.isScreenDirty() || m_rect.m_dirtyMaterial) {
            m_node->update(m_rect.m_color, m_rect.m_border.color(), &m_geometry, &m_borderGeometry);
            m_geometry.setPreserveGeometry(false);
            m_borderGeometry.setPreserveGeometry(false);
            m_geometry.markClean();
            m_borderGeometry.markClean();
            m_rect.m_dirtyMaterial = false;
        }
        return m_node;
    }
    virtual bool contains(const QPointF &point) const override
    {
        return (m_geometry.contains(point) || m_borderGeometry.contains(point));
    }

    static QList<QGeoCoordinate> path(const QGeoRectangle &rect)
    {
        QList<QGeoCoordinate> res;
        res << rect.topLeft();
        res << QGeoCoordinate(rect.topLeft().latitude(), rect.bottomRight().longitude());
        res << rect.bottomRight();
        res << QGeoCoordinate(rect.bottomRight().latitude(), rect.topLeft().longitude());
        return res;
    }

    static QList<QGeoCoordinate> perimeter(const QGeoRectangle &rect)
    {
        QList<QGeoCoordinate> res;
        res << rect.topLeft();
        res << QGeoCoordinate(rect.topLeft().latitude(), rect.bottomRight().longitude());
        res << rect.bottomRight();
        res << QGeoCoordinate(rect.bottomRight().latitude(), rect.topLeft().longitude());
        res << res.first();
        return res;
    }

    static QList<QDoubleVector2D> pathMercator(const QList<QGeoCoordinate> &p)
    {
        QList<QDoubleVector2D> res;
        for (const auto &c: p)
            res << QWebMercator::coordToMercator(c);
        return res;
    }

    QGeoMapPolygonGeometry m_geometry;
    QGeoMapPolylineGeometry m_borderGeometry;
    MapPolygonNode *m_node = nullptr;
};

class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItemPrivateOpenGL: public QDeclarativeRectangleMapItemPrivate
{
public:
    QDeclarativeRectangleMapItemPrivateOpenGL(QDeclarativeRectangleMapItem &rect) : QDeclarativeRectangleMapItemPrivate(rect)
    {
    }

    QDeclarativeRectangleMapItemPrivateOpenGL(QDeclarativeRectangleMapItemPrivate &other)
    : QDeclarativeRectangleMapItemPrivate(other)
    {
    }

    ~QDeclarativeRectangleMapItemPrivateOpenGL() override;

    void markScreenDirtyAndUpdate()
    {
        // preserveGeometry is cleared in updateMapItemPaintNode
        m_geometry.markScreenDirty();
        m_borderGeometry.markScreenDirty();
        m_rect.polishAndUpdate();
    }
    void onLinePropertiesChanged() override
    {
        m_rect.m_dirtyMaterial = true;
        afterViewportChanged();
    }
    virtual void markSourceDirtyAndUpdate() override
    {
        m_geometry.markSourceDirty();
        m_borderGeometry.markSourceDirty();
        m_rect.polishAndUpdate();
    }
    void preserveGeometry()
    {
        m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
        m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
    }
    virtual void onMapSet() override
    {
        markSourceDirtyAndUpdate();
    }
    virtual void onGeoGeometryChanged() override
    {
        preserveGeometry();
        markSourceDirtyAndUpdate();
    }
    virtual void onItemGeometryChanged() override
    {
        onGeoGeometryChanged();
    }
    virtual void afterViewportChanged() override
    {
        preserveGeometry();
        markScreenDirtyAndUpdate();
    }
    virtual void updatePolish() override
    {
        if (!m_rect.topLeft().isValid() || !m_rect.bottomRight().isValid()) {
            m_geometry.clear();
            m_borderGeometry.clear();
            m_rect.setWidth(0);
            m_rect.setHeight(0);
            return;
        }

        QScopedValueRollback<bool> rollback(m_rect.m_updatingGeometry);
        m_rect.m_updatingGeometry = true;
        const qreal lineWidth = m_rect.m_border.width();
        const QColor &lineColor = m_rect.m_border.color();
        const QColor &fillColor = m_rect.color();
        if (fillColor.alpha() != 0) {
            m_geometry.updateSourcePoints(*m_rect.map(), m_rect.m_rectangle);
            m_geometry.markScreenDirty();
            m_geometry.updateScreenPoints(*m_rect.map(), lineWidth, lineColor);
        } else {
            m_geometry.clearBounds();
        }

        QGeoMapItemGeometry * geom = &m_geometry;
        m_borderGeometry.clearScreen();
        if (lineColor.alpha() != 0 && lineWidth > 0) {
            m_borderGeometry.updateSourcePoints(*m_rect.map(), m_rect.m_rectangle);
            m_borderGeometry.markScreenDirty();
            m_borderGeometry.updateScreenPoints(*m_rect.map(), lineWidth);
            geom = &m_borderGeometry;
        }
        m_rect.setWidth(geom->sourceBoundingBox().width());
        m_rect.setHeight(geom->sourceBoundingBox().height());
        m_rect.setPosition(1.0 * geom->firstPointOffset() - QPointF(lineWidth * 0.5,lineWidth * 0.5));
    }

    virtual QSGNode * updateMapItemPaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override
    {
        Q_UNUSED(data);

        if (!m_rootNode || !oldNode) {
            m_rootNode = new QDeclarativePolygonMapItemPrivateOpenGL::RootNode();
            m_node = new MapPolygonNodeGL();
            m_rootNode->appendChildNode(m_node);
            m_polylinenode = new MapPolylineNodeOpenGLExtruded();
            m_rootNode->appendChildNode(m_polylinenode);
            m_rootNode->markDirty(QSGNode::DirtyNodeAdded);
            if (oldNode)
                delete oldNode;
        } else {
            m_rootNode = static_cast<QDeclarativePolygonMapItemPrivateOpenGL::RootNode *>(oldNode);
        }

        const QGeoMap *map = m_rect.map();
        const QMatrix4x4 &combinedMatrix = map->geoProjection().qsgTransform();
        const QDoubleVector3D &cameraCenter = map->geoProjection().centerMercator();

        if (m_borderGeometry.isScreenDirty()) {
            /* Do the border update first */
            m_polylinenode->update(m_rect.m_border.color(),
                                   float(m_rect.m_border.width()),
                                   &m_borderGeometry,
                                   combinedMatrix,
                                   cameraCenter,
                                   Qt::SquareCap,
                                   true,
                                   30); // No LOD for rectangles
            m_borderGeometry.setPreserveGeometry(false);
            m_borderGeometry.markClean();
        } else {
            m_polylinenode->setSubtreeBlocked(true);
        }
        if (m_geometry.isScreenDirty()) {
            m_node->update(m_rect.m_color,
                         &m_geometry,
                         combinedMatrix,
                         cameraCenter);
            m_geometry.setPreserveGeometry(false);
            m_geometry.markClean();
        } else {
            m_node->setSubtreeBlocked(true);
        }

        m_rootNode->setSubtreeBlocked(false);
        return m_rootNode;
    }
    virtual bool contains(const QPointF &point) const override
    {
        const qreal lineWidth = m_rect.m_border.width();
        const QColor &lineColor = m_rect.m_border.color();
        const QRectF &bounds = (lineColor.alpha() != 0 && lineWidth > 0) ? m_borderGeometry.sourceBoundingBox() : m_geometry.sourceBoundingBox();
        if (bounds.contains(point)) {
            QDeclarativeGeoMap *m = m_rect.quickMap();
            if (m) {
                const QGeoCoordinate crd = m->toCoordinate(m->mapFromItem(&m_rect, point));
                return  m_rect.m_rectangle.contains(crd) || m_borderGeometry.contains(m_rect.mapToItem(m_rect.quickMap(), point),
                                                                                      m_rect.border()->width(),
                                                                                      static_cast<const QGeoProjectionWebMercator&>(m_rect.map()->geoProjection()));
            } else {
                return  true;
            }
        }
        return false;
    }

    QGeoMapPolygonGeometryOpenGL m_geometry;
    QGeoMapPolylineGeometryOpenGL m_borderGeometry;
    QDeclarativePolygonMapItemPrivateOpenGL::RootNode *m_rootNode = nullptr;
    MapPolygonNodeGL *m_node = nullptr;
    MapPolylineNodeOpenGLExtruded *m_polylinenode = nullptr;
};

QT_END_NAMESPACE

#endif // QDECLARATIVERECTANGLEMAPITEM_P_P_H

