/****************************************************************************
**
** Copyright (C) 2019 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 "qquickpathview_p.h"
#include "qquickpathview_p_p.h"
#include "qquickwindow.h"
#include "qquickflickablebehavior_p.h" //Contains flicking behavior defines
#include "qquicktext_p.h"

#include <QtQuick/private/qquickstate_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlopenmetaobject_p.h>
#include <private/qqmlchangeset_p.h>

#include <QtQml/qqmlinfo.h>
#include <QtGui/qevent.h>
#include <QtGui/qevent.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>
#include <QtCore/qmath.h>

#include <cmath>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(lcItemViewDelegateLifecycle)
Q_LOGGING_CATEGORY(lcPathView, "qt.quick.pathview")

static const qreal MinimumFlickVelocity = 75;

static QQmlOpenMetaObjectType *qPathViewAttachedType = nullptr;

QQuickPathViewAttached::QQuickPathViewAttached(QObject *parent)
: QObject(parent), m_percent(-1), m_view(nullptr), m_onPath(false), m_isCurrent(false)
{
    if (qPathViewAttachedType) {
        m_metaobject = new QQmlOpenMetaObject(this, qPathViewAttachedType);
        m_metaobject->setCached(true);
    } else {
        m_metaobject = new QQmlOpenMetaObject(this);
    }
}

QQuickPathViewAttached::~QQuickPathViewAttached()
{
}

QVariant QQuickPathViewAttached::value(const QByteArray &name) const
{
    return m_metaobject->value(name);
}
void QQuickPathViewAttached::setValue(const QByteArray &name, const QVariant &val)
{
    m_metaobject->setValue(name, val);
}

QQuickPathViewPrivate::QQuickPathViewPrivate()
  : path(nullptr), currentIndex(0), currentItemOffset(0), startPc(0)
    , offset(0), offsetAdj(0), mappedRange(1), mappedCache(0)
    , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
    , autoHighlight(true), highlightUp(false), layoutScheduled(false)
    , moving(false), flicking(false), dragging(false), inRequest(false), delegateValidated(false)
    , inRefill(false)
    , dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY)
    , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
    , pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
    , moveReason(Other), movementDirection(QQuickPathView::Shortest), moveDirection(QQuickPathView::Shortest)
    , attType(nullptr), highlightComponent(nullptr), highlightItem(nullptr)
    , moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
    , highlightPosition(0)
    , highlightRangeStart(0), highlightRangeEnd(0)
    , highlightRangeMode(QQuickPathView::StrictlyEnforceRange)
    , highlightMoveDuration(300), modelCount(0), snapMode(QQuickPathView::NoSnap)
{
}

void QQuickPathViewPrivate::init()
{
    Q_Q(QQuickPathView);
    offset = 0;
    q->setAcceptedMouseButtons(Qt::LeftButton);
    q->setFlag(QQuickItem::ItemIsFocusScope);
    q->setFiltersChildMouseEvents(true);
    qmlobject_connect(&tl, QQuickTimeLine, SIGNAL(updated()),
                      q, QQuickPathView, SLOT(ticked()));
    timer.invalidate();
    qmlobject_connect(&tl, QQuickTimeLine, SIGNAL(completed()),
                      q, QQuickPathView, SLOT(movementEnding()));
}

QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async)
{
    Q_Q(QQuickPathView);
    requestedIndex = modelIndex;
    requestedZ = z;
    inRequest = true;
    QObject *object = model->object(modelIndex, async ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
    QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
    if (!item) {
        if (object) {
            model->release(object);
            if (!delegateValidated) {
                delegateValidated = true;
                QObject* delegate = q->delegate();
                qmlWarning(delegate ? delegate : q) << QQuickPathView::tr("Delegate must be of Item type");
            }
        }
    } else {
        item->setParentItem(q);
        requestedIndex = -1;
        QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
        itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
    }
    inRequest = false;
    return item;
}

void QQuickPathView::createdItem(int index, QObject *object)
{
    Q_D(QQuickPathView);
    QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
    if (d->requestedIndex != index) {
        qPathViewAttachedType = d->attachedType();
        QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item));
        qPathViewAttachedType = nullptr;
        if (att) {
            att->m_view = this;
            att->setOnPath(false);
        }
        item->setParentItem(this);
        d->updateItem(item, 1);
    } else {
        d->requestedIndex = -1;
        if (!d->inRequest)
            refill();
    }
}

void QQuickPathView::initItem(int index, QObject *object)
{
    Q_D(QQuickPathView);
    QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
    if (item && d->requestedIndex == index) {
        QQuickItemPrivate::get(item)->setCulled(true);
        item->setParentItem(this);
        qPathViewAttachedType = d->attachedType();
        QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item));
        qPathViewAttachedType = nullptr;
        if (att) {
            att->m_view = this;
            qreal percent = d->positionOfIndex(index);
            if (percent < 1 && d->path) {
                const auto attributes = d->path->attributes();
                for (const QString &attr : attributes)
                    att->setValue(attr.toUtf8(), d->path->attributeAt(attr, percent));
                item->setZ(d->requestedZ);
            }
            att->setOnPath(percent < 1);
        }
    }
}

void QQuickPathViewPrivate::releaseItem(QQuickItem *item)
{
    if (!item || !model)
        return;
    qCDebug(lcItemViewDelegateLifecycle) << "release" << item;
    QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
    itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
    QQmlInstanceModel::ReleaseFlags flags = model->release(item);
    if (!flags) {
        // item was not destroyed, and we no longer reference it.
        if (QQuickPathViewAttached *att = attached(item))
            att->setOnPath(false);
    } else if (flags & QQmlInstanceModel::Destroyed) {
        // but we still reference it
        item->setParentItem(nullptr);
    }
}

QQuickPathViewAttached *QQuickPathViewPrivate::attached(QQuickItem *item)
{
    return static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item, false));
}

QQmlOpenMetaObjectType *QQuickPathViewPrivate::attachedType()
{
    Q_Q(QQuickPathView);
    if (!attType) {
        // pre-create one metatype to share with all attached objects
        attType = new QQmlOpenMetaObjectType(&QQuickPathViewAttached::staticMetaObject, qmlEngine(q));
        if (path) {
            const auto attributes = path->attributes();
            for (const QString &attr : attributes)
                attType->createProperty(attr.toUtf8());
        }
    }

    return attType;
}

void QQuickPathViewPrivate::clear()
{
    if (currentItem) {
        releaseItem(currentItem);
        currentItem = nullptr;
    }

    for (QQuickItem *p : qAsConst(items))
        releaseItem(p);

    for (QQuickItem *p : qAsConst(itemCache))
        releaseItem(p);

    if (requestedIndex >= 0) {
        if (model)
            model->cancel(requestedIndex);
        requestedIndex = -1;
    }

    items.clear();
    itemCache.clear();
    tl.clear();
}

void QQuickPathViewPrivate::updateMappedRange()
{
    if (model && pathItems != -1 && pathItems < modelCount) {
        mappedRange = qreal(modelCount)/pathItems;
        mappedCache = qreal(cacheSize)/pathItems/2; // Half of cache at each end
    } else {
        mappedRange = 1;
        mappedCache = 0;
    }
}

qreal QQuickPathViewPrivate::positionOfIndex(qreal index) const
{
    qreal pos = -1;

    if (model && index >= 0 && index < modelCount) {
        qreal start = 0;
        if (haveHighlightRange && (highlightRangeMode != QQuickPathView::NoHighlightRange
                                   || snapMode != QQuickPathView::NoSnap))
            start = highlightRangeStart;
        qreal globalPos = index + offset;
        globalPos = std::fmod(globalPos, qreal(modelCount)) / modelCount;
        if (pathItems != -1 && pathItems < modelCount) {
            globalPos += start / mappedRange;
            globalPos = std::fmod(globalPos, qreal(1));
            pos = globalPos * mappedRange;
        } else {
            pos = std::fmod(globalPos + start, qreal(1));
        }
    }

    return pos;
}

// returns true if position is between lower and upper, taking into
// account the circular space.
bool QQuickPathViewPrivate::isInBound(qreal position, qreal lower, qreal upper) const
{
    if (qFuzzyCompare(lower, upper))
        return true;
    if (lower > upper) {
        if (position > upper && position > lower)
            position -= mappedRange;
        lower -= mappedRange;
    }
    return position >= lower && position < upper;
}

void QQuickPathViewPrivate::createHighlight()
{
    Q_Q(QQuickPathView);
    if (!q->isComponentComplete())
        return;

    bool changed = false;
    if (highlightItem) {
        highlightItem->setParentItem(nullptr);
        highlightItem->deleteLater();
        highlightItem = nullptr;
        changed = true;
    }

    QQuickItem *item = nullptr;
    if (highlightComponent) {
        QQmlContext *creationContext = highlightComponent->creationContext();
        QQmlContext *highlightContext = new QQmlContext(
                creationContext ? creationContext : qmlContext(q));
        QObject *nobj = highlightComponent->create(highlightContext);
        if (nobj) {
            QQml_setParent_noEvent(highlightContext, nobj);
            item = qobject_cast<QQuickItem *>(nobj);
            if (!item)
                delete nobj;
        } else {
            delete highlightContext;
        }
    } else {
        item = new QQuickItem;
    }
    if (item) {
        QQml_setParent_noEvent(item, q);
        item->setParentItem(q);
        highlightItem = item;
        changed = true;
    }
    if (changed)
        emit q->highlightItemChanged();
}

void QQuickPathViewPrivate::updateHighlight()
{
    Q_Q(QQuickPathView);
    if (!q->isComponentComplete() || !isValid())
        return;
    if (highlightItem) {
        if (haveHighlightRange && highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
            updateItem(highlightItem, highlightRangeStart);
        } else {
            qreal target = currentIndex;

            offsetAdj = 0;
            tl.reset(moveHighlight);
            moveHighlight.setValue(highlightPosition);

            const int duration = highlightMoveDuration;

            if (target - highlightPosition > modelCount/2) {
                highlightUp = false;
                qreal distance = modelCount - target + highlightPosition;
                tl.move(moveHighlight, 0, QEasingCurve(QEasingCurve::InQuad), int(duration * highlightPosition / distance));
                tl.set(moveHighlight, modelCount-0.01);
                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * (modelCount-target) / distance));
            } else if (target - highlightPosition <= -modelCount/2) {
                highlightUp = true;
                qreal distance = modelCount - highlightPosition + target;
                tl.move(moveHighlight, modelCount-0.01, QEasingCurve(QEasingCurve::InQuad), int(duration * (modelCount-highlightPosition) / distance));
                tl.set(moveHighlight, 0);
                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::OutQuad), int(duration * target / distance));
            } else {
                highlightUp = highlightPosition - target < 0;
                tl.move(moveHighlight, target, QEasingCurve(QEasingCurve::InOutQuad), duration);
            }
        }
    }
}

void QQuickPathViewPrivate::setHighlightPosition(qreal pos)
{
    if (!(qFuzzyCompare(pos, highlightPosition))) {
        qreal start = 0;
        qreal end = 1;
        if (haveHighlightRange && highlightRangeMode != QQuickPathView::NoHighlightRange) {
            start = highlightRangeStart;
            end = highlightRangeEnd;
        }

        qreal range = qreal(modelCount);
        // calc normalized position of highlight relative to offset
        qreal relativeHighlight = std::fmod(pos + offset, range) / range;

        if (!highlightUp && relativeHighlight > end / mappedRange) {
            qreal diff = 1 - relativeHighlight;
            setOffset(offset + diff * range);
        } else if (highlightUp && relativeHighlight >= (end - start) / mappedRange) {
            qreal diff = relativeHighlight - (end - start) / mappedRange;
            setOffset(offset - diff * range - 0.00001);
        }

        highlightPosition = pos;
        qreal pathPos = positionOfIndex(pos);
        updateItem(highlightItem, pathPos);
        if (QQuickPathViewAttached *att = attached(highlightItem))
            att->setOnPath(pathPos < 1);
    }
}

void QQuickPathView::pathUpdated()
{
    Q_D(QQuickPathView);
    for (QQuickItem *item : qAsConst(d->items)) {
        if (QQuickPathViewAttached *att = d->attached(item))
            att->m_percent = -1;
    }
    refill();
}

void QQuickPathViewPrivate::updateItem(QQuickItem *item, qreal percent)
{
    if (!path)
        return;
    if (QQuickPathViewAttached *att = attached(item)) {
        if (qFuzzyCompare(att->m_percent, percent))
            return;
        att->m_percent = percent;
        const auto attributes = path->attributes();
        for (const QString &attr : attributes)
            att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
        att->setOnPath(percent < 1);
    }
    QQuickItemPrivate::get(item)->setCulled(percent >= 1);
    QPointF pf = path->pointAtPercent(qMin(percent, qreal(1)));
    item->setPosition(pf - QPointF(item->width()/2, item->height()/2));
}

void QQuickPathViewPrivate::regenerate()
{
    Q_Q(QQuickPathView);
    if (!q->isComponentComplete())
        return;

    clear();

    if (!isValid())
        return;

    updateMappedRange();
    q->refill();
}

void QQuickPathViewPrivate::setDragging(bool d)
{
    Q_Q(QQuickPathView);
    if (dragging == d)
        return;

    dragging = d;
    if (dragging)
        emit q->dragStarted();
    else
        emit q->dragEnded();

    emit q->draggingChanged();
}

/*!
    \qmltype PathView
    \instantiates QQuickPathView
    \inqmlmodule QtQuick
    \ingroup qtquick-paths
    \ingroup qtquick-views
    \inherits Item
    \brief Lays out model-provided items on a path.

    A PathView displays data from models created from built-in QML types like ListModel
    and XmlListModel, or custom model classes defined in C++ that inherit from
    QAbstractListModel.

    The view has a \l model, which defines the data to be displayed, and
    a \l delegate, which defines how the data should be displayed.
    The \l delegate is instantiated for each item on the \l path.
    The items may be flicked to move them along the path.

    For example, if there is a simple list model defined in a file \c ContactModel.qml like this:

    \snippet qml/pathview/ContactModel.qml 0

    This data can be represented as a PathView, like this:

    \snippet qml/pathview/pathview.qml 0

    \image pathview.gif

    (Note the above example uses PathAttribute to scale and modify the
    opacity of the items as they rotate. This additional code can be seen in the
    PathAttribute documentation.)

    PathView does not automatically handle keyboard navigation.  This is because
    the keys to use for navigation will depend upon the shape of the path.  Navigation
    can be added quite simply by setting \c focus to \c true and calling
    \l decrementCurrentIndex() or \l incrementCurrentIndex(), for example to navigate
    using the left and right arrow keys:

    \qml
    PathView {
        // ...
        focus: true
        Keys.onLeftPressed: decrementCurrentIndex()
        Keys.onRightPressed: incrementCurrentIndex()
    }
    \endqml

    The path view itself is a focus scope (see \l{Keyboard Focus in Qt Quick} for more details).

    Delegates are instantiated as needed and may be destroyed at any time.
    State should \e never be stored in a delegate.

    PathView attaches a number of properties to the root item of the delegate, for example
    \c {PathView.isCurrentItem}.  In the following example, the root delegate item can access
    this attached property directly as \c PathView.isCurrentItem, while the child
    \c nameText object must refer to this property as \c wrapper.PathView.isCurrentItem.

    \snippet qml/pathview/pathview.qml 1

    \b Note that views do not enable \e clip automatically.  If the view
    is not clipped by another item or the screen, it will be necessary
    to set \e {clip: true} in order to have the out of view items clipped
    nicely.

    \sa Path, {QML Data Models}, ListView, GridView, {Qt Quick Examples - Views}
*/

QQuickPathView::QQuickPathView(QQuickItem *parent)
  : QQuickItem(*(new QQuickPathViewPrivate), parent)
{
    Q_D(QQuickPathView);
    d->init();
}

QQuickPathView::~QQuickPathView()
{
    Q_D(QQuickPathView);
    d->clear();
    if (d->attType)
        d->attType->release();
    if (d->ownModel)
        delete d->model;
}

/*!
    \qmlattachedproperty PathView QtQuick::PathView::view
    This attached property holds the view that manages this delegate instance.

    It is attached to each instance of the delegate.
*/

/*!
    \qmlattachedproperty bool QtQuick::PathView::onPath
    This attached property holds whether the item is currently on the path.

    If a pathItemCount has been set, it is possible that some items may
    be instantiated, but not considered to be currently on the path.
    Usually, these items would be set invisible, for example:

    \qml
    Component {
        Rectangle {
            visible: PathView.onPath
            // ...
        }
    }
    \endqml

    It is attached to each instance of the delegate.
*/

/*!
    \qmlattachedproperty bool QtQuick::PathView::isCurrentItem
    This attached property is true if this delegate is the current item; otherwise false.

    It is attached to each instance of the delegate.

    This property may be used to adjust the appearance of the current item.

    \snippet qml/pathview/pathview.qml 1
*/

/*!
    \qmlproperty model QtQuick::PathView::model
    This property holds the model providing data for the view.

    The model provides a set of data that is used to create the items for the view.
    For large or dynamic datasets the model is usually provided by a C++ model object.
    Models can also be created directly in QML, using the ListModel type.

    \note changing the model will reset the offset and currentIndex to 0.

    \sa {qml-data-models}{Data Models}
*/
QVariant QQuickPathView::model() const
{
    Q_D(const QQuickPathView);
    return d->modelVariant;
}

void QQuickPathView::setModel(const QVariant &m)
{
    Q_D(QQuickPathView);
    QVariant model = m;
    if (model.userType() == qMetaTypeId<QJSValue>())
        model = model.value<QJSValue>().toVariant();

    if (d->modelVariant == model)
        return;

    if (d->model) {
        qmlobject_disconnect(d->model, QQmlInstanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
                             this, QQuickPathView, SLOT(modelUpdated(QQmlChangeSet,bool)));
        qmlobject_disconnect(d->model, QQmlInstanceModel, SIGNAL(createdItem(int,QObject*)),
                             this, QQuickPathView, SLOT(createdItem(int,QObject*)));
        qmlobject_disconnect(d->model, QQmlInstanceModel, SIGNAL(initItem(int,QObject*)),
                             this, QQuickPathView, SLOT(initItem(int,QObject*)));
        d->clear();
    }

    d->modelVariant = model;
    QObject *object = qvariant_cast<QObject*>(model);
    QQmlInstanceModel *vim = nullptr;
    if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) {
        if (d->ownModel) {
            delete d->model;
            d->ownModel = false;
        }
        d->model = vim;
    } else {
        if (!d->ownModel) {
            d->model = new QQmlDelegateModel(qmlContext(this));
            d->ownModel = true;
            if (isComponentComplete())
                static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();
        }
        if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model))
            dataModel->setModel(model);
    }
    int oldModelCount = d->modelCount;
    d->modelCount = 0;
    if (d->model) {
        qmlobject_connect(d->model, QQmlInstanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)),
                          this, QQuickPathView, SLOT(modelUpdated(QQmlChangeSet,bool)));
        qmlobject_connect(d->model, QQmlInstanceModel, SIGNAL(createdItem(int,QObject*)),
                          this, QQuickPathView, SLOT(createdItem(int,QObject*)));
        qmlobject_connect(d->model, QQmlInstanceModel, SIGNAL(initItem(int,QObject*)),
                          this, QQuickPathView, SLOT(initItem(int,QObject*)));
        d->modelCount = d->model->count();
    }
    if (isComponentComplete()) {
        if (d->currentIndex != 0) {
            d->currentIndex = 0;
            emit currentIndexChanged();
        }
        if (!(qFuzzyIsNull(d->offset))) {
            d->offset = 0;
            emit offsetChanged();
        }
    }
    d->regenerate();
    if (d->modelCount != oldModelCount)
        emit countChanged();
    emit modelChanged();
}

/*!
    \qmlproperty int QtQuick::PathView::count
    This property holds the number of items in the model.
*/
int QQuickPathView::count() const
{
    Q_D(const QQuickPathView);
    return d->model ? d->modelCount : 0;
}

/*!
    \qmlproperty Path QtQuick::PathView::path
    This property holds the path used to lay out the items.
    For more information see the \l Path documentation.
*/
QQuickPath *QQuickPathView::path() const
{
    Q_D(const QQuickPathView);
    return d->path;
}

void QQuickPathView::setPath(QQuickPath *path)
{
    Q_D(QQuickPathView);
    if (d->path == path)
        return;
    if (d->path)
        qmlobject_disconnect(d->path, QQuickPath, SIGNAL(changed()),
                             this, QQuickPathView, SLOT(pathUpdated()));
    d->path = path;

    if (path) {
        qmlobject_connect(d->path, QQuickPath, SIGNAL(changed()),
                          this, QQuickPathView, SLOT(pathUpdated()));
    }

    if (isComponentComplete()) {
        d->clear();
        if (d->isValid()) {
            if (d->attType) {
                d->attType->release();
                d->attType = nullptr;
            }
            d->regenerate();
        }
    }

    emit pathChanged();
}

/*!
    \qmlproperty int QtQuick::PathView::currentIndex
    This property holds the index of the current item.
*/
int QQuickPathView::currentIndex() const
{
    Q_D(const QQuickPathView);
    return d->currentIndex;
}

void QQuickPathView::setCurrentIndex(int idx)
{
    Q_D(QQuickPathView);
    if (!isComponentComplete()) {
        if (idx != d->currentIndex) {
            d->currentIndex = idx;
            emit currentIndexChanged();
        }
        return;
    }

    idx = d->modelCount
        ? ((idx % d->modelCount) + d->modelCount) % d->modelCount
        : 0;
    if (d->model && (idx != d->currentIndex || !d->currentItem)) {
        if (d->currentItem) {
            if (QQuickPathViewAttached *att = d->attached(d->currentItem))
                att->setIsCurrentItem(false);
            d->releaseItem(d->currentItem);
        }
        int oldCurrentIdx = d->currentIndex;
        QQuickItem *oldCurrentItem = d->currentItem;
        d->currentItem = nullptr;
        d->moveReason = QQuickPathViewPrivate::SetIndex;
        d->currentIndex = idx;
        if (d->modelCount) {
            d->createCurrentItem();
            if (d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange)
                d->snapToIndex(d->currentIndex, QQuickPathViewPrivate::SetIndex);
            d->currentItemOffset = d->positionOfIndex(d->currentIndex);
            d->updateHighlight();
        }
        if (oldCurrentIdx != d->currentIndex)
            emit currentIndexChanged();
        if (oldCurrentItem != d->currentItem)
            emit currentItemChanged();
    }
}

/*!
    \qmlproperty Item QtQuick::PathView::currentItem
    This property holds the current item in the view.
*/
QQuickItem *QQuickPathView::currentItem() const
{
    Q_D(const QQuickPathView);
    return d->currentItem;
}

/*!
    \qmlmethod QtQuick::PathView::incrementCurrentIndex()

    Increments the current index.

    \b Note: methods should only be called after the Component has completed.
*/
void QQuickPathView::incrementCurrentIndex()
{
    Q_D(QQuickPathView);
    d->moveDirection = QQuickPathView::Positive;
    setCurrentIndex(currentIndex()+1);
}

/*!
    \qmlmethod QtQuick::PathView::decrementCurrentIndex()

    Decrements the current index.

    \b Note: methods should only be called after the Component has completed.
*/
void QQuickPathView::decrementCurrentIndex()
{
    Q_D(QQuickPathView);
    d->moveDirection = QQuickPathView::Negative;
    setCurrentIndex(currentIndex()-1);
}

/*!
    \qmlproperty real QtQuick::PathView::offset

    The offset specifies how far along the path the items are from their initial positions.
    This is a real number that ranges from \c 0 to the count of items in the model.
*/
qreal QQuickPathView::offset() const
{
    Q_D(const QQuickPathView);
    return d->offset;
}

void QQuickPathView::setOffset(qreal offset)
{
    Q_D(QQuickPathView);
    d->moveReason = QQuickPathViewPrivate::Other;
    d->setOffset(offset);
    d->updateCurrent();
}

void QQuickPathViewPrivate::setOffset(qreal o)
{
    Q_Q(QQuickPathView);
    if (!qFuzzyCompare(offset, o)) {
        if (isValid() && q->isComponentComplete()) {
            qreal oldOffset = offset;
            offset = std::fmod(o, qreal(modelCount));
            if (offset < 0)
                offset += qreal(modelCount);
            qCDebug(lcItemViewDelegateLifecycle) << o << "was" << oldOffset << "now" << offset;
            q->refill();
        } else {
            offset = o;
        }
        emit q->offsetChanged();
    }
}

void QQuickPathViewPrivate::setAdjustedOffset(qreal o)
{
    setOffset(o+offsetAdj);
}

/*!
    \qmlproperty Component QtQuick::PathView::highlight
    This property holds the component to use as the highlight.

    An instance of the highlight component will be created for each view.
    The geometry of the resultant component instance will be managed by the view
    so as to stay with the current item.

    The below example demonstrates how to make a simple highlight.  Note the use
    of the \l{PathView::onPath}{PathView.onPath} attached property to ensure that
    the highlight is hidden when flicked away from the path.

    \qml
    Component {
        Rectangle {
            visible: PathView.onPath
            // ...
        }
    }
    \endqml

    \sa highlightItem, highlightRangeMode
*/
QQmlComponent *QQuickPathView::highlight() const
{
    Q_D(const QQuickPathView);
    return d->highlightComponent;
}

void QQuickPathView::setHighlight(QQmlComponent *highlight)
{
    Q_D(QQuickPathView);
    if (highlight != d->highlightComponent) {
        d->highlightComponent = highlight;
        d->createHighlight();
        d->updateHighlight();
        emit highlightChanged();
    }
}

/*!
    \qmlproperty Item QtQuick::PathView::highlightItem

    \c highlightItem holds the highlight item, which was created
    from the \l highlight component.

    \sa highlight
*/
QQuickItem *QQuickPathView::highlightItem() const
{
    Q_D(const QQuickPathView);
    return d->highlightItem;
}

/*!
    \qmlproperty real QtQuick::PathView::preferredHighlightBegin
    \qmlproperty real QtQuick::PathView::preferredHighlightEnd
    \qmlproperty enumeration QtQuick::PathView::highlightRangeMode

    These properties set the preferred range of the highlight (current item)
    within the view. The preferred values must be in the range from \c 0 to \c 1.

    Valid values for \c highlightRangeMode are:

    \list
        \li \e PathView.NoHighlightRange - no range is applied and the
            highlight will move freely within the view.
        \li \e PathView.ApplyRange - the view will attempt to maintain
            the highlight within the range, however the highlight can
            move outside of the range at the ends of the path or due to
            a mouse interaction.
        \li \e PathView.StrictlyEnforceRange - the highlight will never
            move outside of the range. This means that the current item
            will change if a keyboard or mouse action would cause the
            highlight to move outside of the range.
    \endlist

    The default value is \e PathView.StrictlyEnforceRange.

    Defining a highlight range is the correct way to influence where the
    current item ends up when the view moves. For example, if you want the
    currently selected item to be in the middle of the path, then set the
    highlight range to be 0.5,0.5 and highlightRangeMode to \e PathView.StrictlyEnforceRange.
    Then, when the path scrolls,
    the currently selected item will be the item at that position. This also applies to
    when the currently selected item changes - it will scroll to within the preferred
    highlight range. Furthermore, the behaviour of the current item index will occur
    whether or not a highlight exists.

    \note A valid range requires \c preferredHighlightEnd to be greater
    than or equal to \c preferredHighlightBegin.
*/
qreal QQuickPathView::preferredHighlightBegin() const
{
    Q_D(const QQuickPathView);
    return d->highlightRangeStart;
}

void QQuickPathView::setPreferredHighlightBegin(qreal start)
{
    Q_D(QQuickPathView);
    if (qFuzzyCompare(d->highlightRangeStart, start) || start < 0 || start > 1)
        return;
    d->highlightRangeStart = start;
    d->haveHighlightRange = d->highlightRangeStart <= d->highlightRangeEnd;
    refill();
    emit preferredHighlightBeginChanged();
}

qreal QQuickPathView::preferredHighlightEnd() const
{
    Q_D(const QQuickPathView);
    return d->highlightRangeEnd;
}

void QQuickPathView::setPreferredHighlightEnd(qreal end)
{
    Q_D(QQuickPathView);
    if (qFuzzyCompare(d->highlightRangeEnd, end) || end < 0 || end > 1)
        return;
    d->highlightRangeEnd = end;
    d->haveHighlightRange = d->highlightRangeStart <= d->highlightRangeEnd;
    refill();
    emit preferredHighlightEndChanged();
}

QQuickPathView::HighlightRangeMode QQuickPathView::highlightRangeMode() const
{
    Q_D(const QQuickPathView);
    return d->highlightRangeMode;
}

void QQuickPathView::setHighlightRangeMode(HighlightRangeMode mode)
{
    Q_D(QQuickPathView);
    if (d->highlightRangeMode == mode)
        return;
    d->highlightRangeMode = mode;
    d->haveHighlightRange = d->highlightRangeStart <= d->highlightRangeEnd;
    if (d->haveHighlightRange) {
        d->regenerate();
        int index = d->highlightRangeMode != NoHighlightRange ? d->currentIndex : d->calcCurrentIndex();
        if (index >= 0)
            d->snapToIndex(index, QQuickPathViewPrivate::Other);
    }
    emit highlightRangeModeChanged();
}

/*!
    \qmlproperty int QtQuick::PathView::highlightMoveDuration
    This property holds the move animation duration of the highlight delegate.

    If the highlightRangeMode is StrictlyEnforceRange then this property
    determines the speed that the items move along the path.

    The default value for the duration is 300ms.
*/
int QQuickPathView::highlightMoveDuration() const
{
    Q_D(const QQuickPathView);
    return d->highlightMoveDuration;
}

void QQuickPathView::setHighlightMoveDuration(int duration)
{
    Q_D(QQuickPathView);
    if (d->highlightMoveDuration == duration)
        return;
    d->highlightMoveDuration = duration;
    emit highlightMoveDurationChanged();
}

/*!
    \qmlproperty real QtQuick::PathView::dragMargin
    This property holds the maximum distance from the path that initiates mouse dragging.

    By default the path can only be dragged by clicking on an item.  If
    dragMargin is greater than zero, a drag can be initiated by clicking
    within dragMargin pixels of the path.
*/
qreal QQuickPathView::dragMargin() const
{
    Q_D(const QQuickPathView);
    return d->dragMargin;
}

void QQuickPathView::setDragMargin(qreal dragMargin)
{
    Q_D(QQuickPathView);
    if (qFuzzyCompare(d->dragMargin, dragMargin))
        return;
    d->dragMargin = dragMargin;
    emit dragMarginChanged();
}

/*!
    \qmlproperty real QtQuick::PathView::flickDeceleration
    This property holds the rate at which a flick will decelerate.

    The default is 100.
*/
qreal QQuickPathView::flickDeceleration() const
{
    Q_D(const QQuickPathView);
    return d->deceleration;
}

void QQuickPathView::setFlickDeceleration(qreal dec)
{
    Q_D(QQuickPathView);
    if (qFuzzyCompare(d->deceleration, dec))
        return;
    d->deceleration = dec;
    emit flickDecelerationChanged();
}

/*!
    \qmlproperty real QtQuick::PathView::maximumFlickVelocity
    This property holds the approximate maximum velocity that the user can flick the view in pixels/second.

    The default value is platform dependent.
*/
qreal QQuickPathView::maximumFlickVelocity() const
{
    Q_D(const QQuickPathView);
    return d->maximumFlickVelocity;
}

void QQuickPathView::setMaximumFlickVelocity(qreal vel)
{
    Q_D(QQuickPathView);
    if (qFuzzyCompare(vel, d->maximumFlickVelocity))
        return;
    d->maximumFlickVelocity = vel;
    emit maximumFlickVelocityChanged();
}


/*!
    \qmlproperty bool QtQuick::PathView::interactive

    A user cannot drag or flick a PathView that is not interactive.

    This property is useful for temporarily disabling flicking. This allows
    special interaction with PathView's children.
*/
bool QQuickPathView::isInteractive() const
{
    Q_D(const QQuickPathView);
    return d->interactive;
}

void QQuickPathView::setInteractive(bool interactive)
{
    Q_D(QQuickPathView);
    if (interactive != d->interactive) {
        d->interactive = interactive;
        if (!interactive)
            d->tl.clear();
        emit interactiveChanged();
    }
}

/*!
    \qmlproperty bool QtQuick::PathView::moving

    This property holds whether the view is currently moving
    due to the user either dragging or flicking the view.
*/
bool QQuickPathView::isMoving() const
{
    Q_D(const QQuickPathView);
    return d->moving;
}

/*!
    \qmlproperty bool QtQuick::PathView::flicking

    This property holds whether the view is currently moving
    due to the user flicking the view.
*/
bool QQuickPathView::isFlicking() const
{
    Q_D(const QQuickPathView);
    return d->flicking;
}

/*!
    \qmlproperty bool QtQuick::PathView::dragging

    This property holds whether the view is currently moving
    due to the user dragging the view.
*/
bool QQuickPathView::isDragging() const
{
    Q_D(const QQuickPathView);
    return d->dragging;
}

/*!
    \qmlsignal QtQuick::PathView::movementStarted()

    This signal is emitted when the view begins moving due to user
    interaction.
*/

/*!
    \qmlsignal QtQuick::PathView::movementEnded()

    This signal is emitted when the view stops moving due to user
    interaction.  If a flick was generated, this signal will
    be emitted once the flick stops.  If a flick was not
    generated, this signal will be emitted when the
    user stops dragging - i.e. a mouse or touch release.
*/

/*!
    \qmlsignal QtQuick::PathView::flickStarted()

    This signal is emitted when the view is flicked.  A flick
    starts from the point that the mouse or touch is released,
    while still in motion.
*/

/*!
    \qmlsignal QtQuick::PathView::flickEnded()

    This signal is emitted when the view stops moving due to a flick.
*/

/*!
    \qmlsignal QtQuick::PathView::dragStarted()

    This signal is emitted when the view starts to be dragged due to user
    interaction.
*/

/*!
    \qmlsignal QtQuick::PathView::dragEnded()

    This signal is emitted when the user stops dragging the view.

    If the velocity of the drag is suffient at the time the
    touch/mouse button is released then a flick will start.
*/

/*!
    \qmlproperty Component QtQuick::PathView::delegate

    The delegate provides a template defining each item instantiated by the view.
    The index is exposed as an accessible \c index property.  Properties of the
    model are also available depending upon the type of \l {qml-data-models}{Data Model}.

    The number of objects and bindings in the delegate has a direct effect on the
    flicking performance of the view when pathItemCount is specified.  If at all possible, place functionality
    that is not needed for the normal display of the delegate in a \l Loader which
    can load additional components when needed.

    Note that the PathView will layout the items based on the size of the root
    item in the delegate.

    Here is an example delegate:
    \snippet qml/pathview/pathview.qml 1
*/
QQmlComponent *QQuickPathView::delegate() const
{
    Q_D(const QQuickPathView);
     if (d->model) {
        if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model))
            return dataModel->delegate();
    }

    return nullptr;
}

void QQuickPathView::setDelegate(QQmlComponent *delegate)
{
    Q_D(QQuickPathView);
    if (delegate == this->delegate())
        return;
    if (!d->ownModel) {
        d->model = new QQmlDelegateModel(qmlContext(this));
        d->ownModel = true;
        if (isComponentComplete())
            static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();
    }
    if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
        int oldCount = dataModel->count();
        dataModel->setDelegate(delegate);
        d->modelCount = dataModel->count();
        d->regenerate();
        if (oldCount != dataModel->count())
            emit countChanged();
        emit delegateChanged();
        d->delegateValidated = false;
    }
}

/*!
  \qmlproperty int QtQuick::PathView::pathItemCount
  This property holds the number of items visible on the path at any one time.

  Setting pathItemCount to undefined will show all items on the path.
*/
int QQuickPathView::pathItemCount() const
{
    Q_D(const QQuickPathView);
    return d->pathItems;
}

void QQuickPathView::setPathItemCount(int i)
{
    Q_D(QQuickPathView);
    if (i == d->pathItems)
        return;
    if (i < 1)
        i = 1;
    d->pathItems = i;
    d->updateMappedRange();
    if (d->isValid() && isComponentComplete()) {
        d->regenerate();
    }
    emit pathItemCountChanged();
}

void QQuickPathView::resetPathItemCount()
{
    Q_D(QQuickPathView);
    if (-1 == d->pathItems)
        return;
    d->pathItems = -1;
    d->updateMappedRange();
    if (d->isValid() && isComponentComplete())
        d->regenerate();
    emit pathItemCountChanged();
}

/*!
    \qmlproperty int QtQuick::PathView::cacheItemCount
    This property holds the maximum number of items to cache off the path.

    For example, a PathView with a model containing 20 items, a pathItemCount
    of 10, and an cacheItemCount of 4 will create up to 14 items, with 10 visible
    on the path and 4 invisible cached items.

    The cached delegates are created asynchronously,
    allowing creation to occur across multiple frames and reducing the
    likelihood of skipping frames.

    \note Setting this property is not a replacement for creating efficient delegates.
    It can improve the smoothness of scrolling behavior at the expense of additional
    memory usage. The fewer objects and bindings in a delegate, the faster a
    view can be scrolled. It is important to realize that setting cacheItemCount
    will only postpone issues caused by slow-loading delegates, it is not a
    solution for this scenario.

    \sa pathItemCount
*/
int QQuickPathView::cacheItemCount() const
{
    Q_D(const QQuickPathView);
    return d->cacheSize;
}

void QQuickPathView::setCacheItemCount(int i)
{
    Q_D(QQuickPathView);
    if (i == d->cacheSize || i < 0)
        return;

    d->cacheSize = i;
    d->updateMappedRange();
    refill();
    emit cacheItemCountChanged();
}

/*!
    \qmlproperty enumeration QtQuick::PathView::snapMode

    This property determines how the items will settle following a drag or flick.
    The possible values are:

    \list
    \li PathView.NoSnap (default) - the items stop anywhere along the path.
    \li PathView.SnapToItem - the items settle with an item aligned with the \l preferredHighlightBegin.
    \li PathView.SnapOneItem - the items settle no more than one item away from the item nearest
        \l preferredHighlightBegin at the time the press is released.  This mode is particularly
        useful for moving one page at a time.
    \endlist

    \c snapMode does not affect the \l currentIndex.  To update the
    \l currentIndex as the view is moved, set \l highlightRangeMode
    to \c PathView.StrictlyEnforceRange (default for PathView).

    \sa highlightRangeMode
*/
QQuickPathView::SnapMode QQuickPathView::snapMode() const
{
    Q_D(const QQuickPathView);
    return d->snapMode;
}

void QQuickPathView::setSnapMode(SnapMode mode)
{
    Q_D(QQuickPathView);
    if (mode == d->snapMode)
        return;
    d->snapMode = mode;
    emit snapModeChanged();
}

/*!
    \qmlproperty enumeration QtQuick::PathView::movementDirection
    \since 5.7

    This property determines the direction in which items move when setting the current index.
    The possible values are:

    \list
    \li PathView.Shortest (default) - the items move in the direction that requires the least
        movement, which could be either \c Negative or \c Positive.
    \li PathView.Negative - the items move backwards towards their destination.
    \li PathView.Positive - the items move forwards towards their destination.
    \endlist

    For example, suppose that there are 5 items in the model, and \l currentIndex is \c 0.
    If currentIndex is set to \c 2,

    \list
    \li a \c Positive movement direction will result in the following order: 0, 1, 2
    \li a \c Negative movement direction will result in the following order: 0, 5, 4, 3, 2
    \li a \c Shortest movement direction will result in same order with \c Positive .
    \endlist

    \note this property doesn't affect the movement of \l incrementCurrentIndex() and \l decrementCurrentIndex().
*/
QQuickPathView::MovementDirection QQuickPathView::movementDirection() const
{
    Q_D(const QQuickPathView);
    return d->movementDirection;
}

void QQuickPathView::setMovementDirection(QQuickPathView::MovementDirection dir)
{
    Q_D(QQuickPathView);
    if (dir == d->movementDirection)
        return;
    d->movementDirection = dir;
    if (!d->tl.isActive())
        d->moveDirection = d->movementDirection;
    emit movementDirectionChanged();
}

/*!
    \qmlmethod QtQuick::PathView::positionViewAtIndex(int index, PositionMode mode)

    Positions the view such that the \a index is at the position specified by
    \a mode:

    \list
    \li PathView.Beginning - position item at the beginning of the path.
    \li PathView.Center - position item in the center of the path.
    \li PathView.End - position item at the end of the path.
    \li PathView.Contain - ensure the item is positioned on the path.
    \li PathView.SnapPosition - position the item at \l preferredHighlightBegin.  This mode
    is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled
    via \l snapMode.
    \endlist

    \b Note: methods should only be called after the Component has completed.  To position
    the view at startup, this method should be called by Component.onCompleted.  For
    example, to position the view at the end:

    \code
    Component.onCompleted: positionViewAtIndex(count - 1, PathView.End)
    \endcode
*/
void QQuickPathView::positionViewAtIndex(int index, int mode)
{
    Q_D(QQuickPathView);
    if (!d->isValid())
        return;
    if (mode < QQuickPathView::Beginning || mode > QQuickPathView::SnapPosition || mode == 3) // 3 is unused in PathView
        return;

    if (mode == QQuickPathView::Contain && (d->pathItems < 0 || d->modelCount <= d->pathItems))
        return;

    int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);
    int idx = (index+d->modelCount) % d->modelCount;
    bool snap = d->haveHighlightRange && (d->highlightRangeMode != QQuickPathView::NoHighlightRange
            || d->snapMode != QQuickPathView::NoSnap);

    qreal beginOffset;
    qreal endOffset;
    if (snap) {
        beginOffset = d->modelCount - idx - qFloor(count * d->highlightRangeStart);
        endOffset = beginOffset + count - 1;
    } else {
        beginOffset = d->modelCount - idx;
        // Small offset since the last point coincides with the first and
        // this the only "end" position that gives the expected visual result.
        qreal adj = sizeof(qreal) == sizeof(float) ? 0.00001f : 0.000000000001;
        endOffset = std::fmod(beginOffset + count, qreal(d->modelCount)) - adj;
    }
    qreal offset = d->offset;
    switch (mode) {
    case Beginning:
        offset = beginOffset;
        break;
    case End:
        offset = endOffset;
        break;
    case Center:
        if (beginOffset < endOffset)
            offset = (beginOffset + endOffset)/2;
        else
            offset = (beginOffset + (endOffset + d->modelCount))/2;
        if (snap)
            offset = qRound(offset);
        break;
    case Contain:
        if ((beginOffset < endOffset && (d->offset < beginOffset || d->offset > endOffset))
                || (d->offset < beginOffset && d->offset > endOffset)) {
            qreal diff1 = std::fmod(beginOffset - d->offset + d->modelCount, qreal(d->modelCount));
            qreal diff2 = std::fmod(d->offset - endOffset + d->modelCount, qreal(d->modelCount));
            if (diff1 < diff2)
                offset = beginOffset;
            else
                offset = endOffset;
        }
        break;
    case SnapPosition:
        offset = d->modelCount - idx;
        break;
    }

    d->tl.clear();
    setOffset(offset);
}

/*!
    \qmlmethod int QtQuick::PathView::indexAt(real x, real y)

    Returns the index of the item containing the point \a x, \a y in content
    coordinates.  If there is no item at the point specified, -1 is returned.

    \b Note: methods should only be called after the Component has completed.
*/
int QQuickPathView::indexAt(qreal x, qreal y) const
{
    Q_D(const QQuickPathView);
    QQuickItem *item = itemAt(x, y);
    return item ? d->model->indexOf(item, nullptr) : -1;
}

/*!
    \qmlmethod Item QtQuick::PathView::itemAt(real x, real y)

    Returns the item containing the point \a x, \a y in content
    coordinates.  If there is no item at the point specified, null is returned.

    \b Note: methods should only be called after the Component has completed.
*/
QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const
{
    Q_D(const QQuickPathView);
    if (!d->isValid())
        return nullptr;

    for (QQuickItem *item : d->items) {
        QPointF p = item->mapFromItem(this, QPointF(x, y));
        if (item->contains(p))
            return item;
    }

    return nullptr;
}

/*!
    \qmlmethod Item QtQuick::QQuickPathView::itemAtIndex(int index)

    Returns the item for \a index. If there is no item for that index, for example
    because it has not been created yet, or because it has been panned out of
    the visible area and removed from the cache, null is returned.

    \b Note: this method should only be called after the Component has completed.
    The returned value should also not be stored since it can turn to null
    as soon as control goes out of the calling scope, if the view releases that item.

    \since 5.13
*/
QQuickItem *QQuickPathView::itemAtIndex(int index) const
{
    Q_D(const QQuickPathView);
    if (!d->isValid())
        return nullptr;

    for (QQuickItem *item : d->items) {
        if (index ==  d->model->indexOf(item, nullptr))
            return item;
    }

    return nullptr;
}

QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const
{
    const auto pathLength = path->path().length();
    qreal samples = qMin(pathLength / 5, qreal(500));
    qreal res = pathLength / samples;

    qreal mindist = 1e10; // big number
    QPointF nearPoint = path->pointAtPercent(0);
    qreal nearPc = 0;

    // get rough pos
    for (qreal i=1; i < samples; i++) {
        QPointF pt = path->pointAtPercent(i/samples);
        QPointF diff = pt - point;
        qreal dist = diff.x()*diff.x() + diff.y()*diff.y();
        if (dist < mindist) {
            nearPoint = pt;
            nearPc = i;
            mindist = dist;
        }
    }

    // now refine
    qreal approxPc = nearPc;
    for (qreal i = approxPc-1; i < approxPc+1; i += 1/(2*res)) {
        QPointF pt = path->pointAtPercent(i/samples);
        QPointF diff = pt - point;
        qreal dist = diff.x()*diff.x() + diff.y()*diff.y();
        if (dist < mindist) {
            nearPoint = pt;
            nearPc = i;
            mindist = dist;
        }
    }

    if (nearPercent)
        *nearPercent = nearPc / samples;

    return nearPoint;
}

void QQuickPathViewPrivate::addVelocitySample(qreal v)
{
    velocityBuffer.append(v);
    if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER)
        velocityBuffer.remove(0);
    qCDebug(lcPathView) << "instantaneous velocity" << v;
}

qreal QQuickPathViewPrivate::calcVelocity() const
{
    qreal velocity = 0;
    if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) {
        int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES;
        for (int i = 0; i < count; ++i) {
            qreal v = velocityBuffer.at(i);
            velocity += v;
        }
        velocity /= count;
        qCDebug(lcPathView) << "average velocity" << velocity << "based on" << count << "samples";
    }
    return velocity;
}

qint64 QQuickPathViewPrivate::computeCurrentTime(QInputEvent *event) const
{
    if (0 != event->timestamp())
        return qint64(event->timestamp());
    return timer.elapsed();
}

void QQuickPathView::mousePressEvent(QMouseEvent *event)
{
    Q_D(QQuickPathView);
    if (d->interactive) {
        d->handleMousePressEvent(event);
        event->accept();
    } else {
        QQuickItem::mousePressEvent(event);
    }
}

void QQuickPathViewPrivate::handleMousePressEvent(QMouseEvent *event)
{
    Q_Q(QQuickPathView);
    if (!interactive || !items.count() || !model || !modelCount)
        return;
    velocityBuffer.clear();
    int idx = 0;
    for (; idx < items.count(); ++idx) {
        QQuickItem *item = items.at(idx);
        if (item->contains(item->mapFromScene(event->windowPos())))
            break;
    }
    if (idx == items.count() && qFuzzyIsNull(dragMargin))  // didn't click on an item
        return;

    startPoint = pointNear(event->localPos(), &startPc);
    startPos = event->localPos();
    if (idx == items.count()) {
        qreal distance = qAbs(event->localPos().x() - startPoint.x()) + qAbs(event->localPos().y() - startPoint.y());
        if (distance > dragMargin)
            return;
    }

    if (tl.isActive() && flicking && flickDuration && qreal(tl.time()) / flickDuration < 0.8) {
        stealMouse = true; // If we've been flicked then steal the click.
        q->grabMouse(); // grab it right now too, just to be sure (QTBUG-77173)
    } else {
        stealMouse = false;
    }
    q->setKeepMouseGrab(stealMouse);

    timer.start();
    lastPosTime = computeCurrentTime(event);
    tl.clear();
}

void QQuickPathView::mouseMoveEvent(QMouseEvent *event)
{
    Q_D(QQuickPathView);
    if (d->interactive) {
        d->handleMouseMoveEvent(event);
        event->accept();
    } else {
        QQuickItem::mouseMoveEvent(event);
    }
}

void QQuickPathViewPrivate::handleMouseMoveEvent(QMouseEvent *event)
{
    Q_Q(QQuickPathView);
    if (!interactive || !timer.isValid() || !model || !modelCount)
        return;

    qint64 currentTimestamp = computeCurrentTime(event);
    qreal newPc;
    QPointF pathPoint = pointNear(event->localPos(), &newPc);
    if (!stealMouse) {
        QPointF posDelta = event->localPos() - startPos;
        if (QQuickWindowPrivate::dragOverThreshold(posDelta.y(), Qt::YAxis, event) || QQuickWindowPrivate::dragOverThreshold(posDelta.x(), Qt::XAxis, event)) {
            // The touch has exceeded the threshold. If the movement along the path is close to the drag threshold
            // then we'll assume that this gesture targets the PathView. This ensures PathView gesture grabbing
            // is in sync with other items.
            QPointF pathDelta = pathPoint - startPoint;
            const int startDragDistance = QGuiApplication::styleHints()->startDragDistance();
            if (qAbs(pathDelta.x()) > startDragDistance * 0.8
                    || qAbs(pathDelta.y()) > startDragDistance * 0.8) {
                stealMouse = true;
                q->setKeepMouseGrab(true);
            }
        }
    } else {
        moveReason = QQuickPathViewPrivate::Mouse;
        int count = pathItems == -1 ? modelCount : qMin(pathItems, modelCount);
        qreal diff = (newPc - startPc)*count;
        if (!qFuzzyIsNull(diff)) {
            q->setOffset(offset + diff);

            if (diff > modelCount/2)
                diff -= modelCount;
            else if (diff < -modelCount/2)
                diff += modelCount;

            qint64 elapsed = currentTimestamp - lastPosTime;
            if (elapsed > 0)
                addVelocitySample(diff / (qreal(elapsed) / 1000));
        }
        if (!moving) {
            moving = true;
            emit q->movingChanged();
            emit q->movementStarted();
        }
        setDragging(true);
    }
    startPc = newPc;
    lastPosTime = currentTimestamp;
}

void QQuickPathView::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QQuickPathView);
    if (d->interactive) {
        d->handleMouseReleaseEvent(event);
        event->accept();
        ungrabMouse();
    } else {
        QQuickItem::mouseReleaseEvent(event);
    }
}

void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *event)
{
    Q_Q(QQuickPathView);
    stealMouse = false;
    q->setKeepMouseGrab(false);
    setDragging(false);
    if (!interactive || !timer.isValid() || !model || !modelCount) {
        timer.invalidate();
        if (!tl.isActive())
            q->movementEnding();
        return;
    }

    qreal velocity = calcVelocity();
    qint64 elapsed = computeCurrentTime(event) - lastPosTime;
    // Let the velocity linearly decay such that it becomes 0 if elapsed time > QML_FLICK_VELOCITY_DECAY_TIME
    // The intention is that if you are flicking at some speed, then stop in one place for some time before releasing,
    // the previous velocity is lost. (QTBUG-77173, QTBUG-59052)
    velocity *= qreal(qMax(0LL, QML_FLICK_VELOCITY_DECAY_TIME - elapsed)) / QML_FLICK_VELOCITY_DECAY_TIME;
    qCDebug(lcPathView) << "after elapsed time" << elapsed << "velocity decayed to" << velocity;
    qreal count = pathItems == -1 ? modelCount : qMin(pathItems, modelCount);
    const auto averageItemLength = path->path().length() / count;
    qreal pixelVelocity = averageItemLength * velocity;
    if (qAbs(pixelVelocity) > MinimumFlickVelocity) {
        if (qAbs(pixelVelocity) > maximumFlickVelocity || snapMode == QQuickPathView::SnapOneItem) {
            // limit velocity
            qreal maxVel = velocity < 0 ? -maximumFlickVelocity : maximumFlickVelocity;
            velocity = maxVel / averageItemLength;
        }
        // Calculate the distance to be travelled
        qreal v2 = velocity*velocity;
        qreal accel = deceleration/10;
        qreal dist = 0;
        if (haveHighlightRange && (highlightRangeMode == QQuickPathView::StrictlyEnforceRange
                || snapMode != QQuickPathView::NoSnap)) {
            if (snapMode == QQuickPathView::SnapOneItem) {
                // encourage snapping one item in direction of motion
                if (velocity > 0)
                    dist = qRound(0.5 + offset) - offset;
                else
                    dist = qRound(0.5 - offset) + offset;
            } else {
                // + 0.25 to encourage moving at least one item in the flick direction
                dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2) + 0.25));

                // round to nearest item.
                if (velocity > 0)
                    dist = qRound(dist + offset) - offset;
                else
                    dist = qRound(dist - offset) + offset;
            }
            // Calculate accel required to stop on item boundary
            if (dist <= 0) {
                dist = 0;
                accel = 0;
            } else {
                accel = v2 / (2 * qAbs(dist));
            }
        } else {
            dist = qMin(qreal(modelCount-1), qreal(v2 / (accel * 2)));
        }
        flickDuration = int(1000 * qAbs(velocity) / accel);
        offsetAdj = 0;
        moveOffset.setValue(offset);
        tl.accel(moveOffset, velocity, accel, dist);
        tl.callback(QQuickTimeLineCallback(&moveOffset, fixOffsetCallback, this));
        if (!flicking) {
            flicking = true;
            emit q->flickingChanged();
            emit q->flickStarted();
        }
    } else {
        fixOffset();
    }

    timer.invalidate();
    if (!tl.isActive())
        q->movementEnding();
}

bool QQuickPathView::sendMouseEvent(QMouseEvent *event)
{
    Q_D(QQuickPathView);
    QPointF localPos = mapFromScene(event->windowPos());

    QQuickWindow *c = window();
    QQuickItem *grabber = c ? c->mouseGrabberItem() : nullptr;
    if (grabber == this && d->stealMouse) {
        // we are already the grabber and we do want the mouse event to ourselves.
        return true;
    }

    bool grabberDisabled = grabber && !grabber->isEnabled();
    bool stealThisEvent = d->stealMouse;
    if ((stealThisEvent || contains(localPos)) && (!grabber || !grabber->keepMouseGrab() || grabberDisabled)) {
        QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
        mouseEvent->setAccepted(false);

        switch (mouseEvent->type()) {
        case QEvent::MouseMove:
            d->handleMouseMoveEvent(mouseEvent.data());
            break;
        case QEvent::MouseButtonPress:
            d->handleMousePressEvent(mouseEvent.data());
            stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
            break;
        case QEvent::MouseButtonRelease:
            d->handleMouseReleaseEvent(mouseEvent.data());
            break;
        default:
            break;
        }
        grabber = c ? c->mouseGrabberItem() : nullptr;
        if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || grabberDisabled) {
            grabMouse();
        }

        const bool filtered = stealThisEvent || grabberDisabled;
        if (filtered) {
            event->setAccepted(false);
        }
        return filtered;
    } else if (d->timer.isValid()) {
        d->timer.invalidate();
        d->fixOffset();
    }
    if (event->type() == QEvent::MouseButtonRelease || (grabber && grabber->keepMouseGrab() && !grabberDisabled)) {
        d->stealMouse = false;
    }
    return false;
}

bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
{
    Q_D(QQuickPathView);
    if (!isVisible() || !d->interactive)
        return QQuickItem::childMouseEventFilter(i, e);

    switch (e->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
        return sendMouseEvent(static_cast<QMouseEvent *>(e));
    default:
        break;
    }

    return QQuickItem::childMouseEventFilter(i, e);
}

void QQuickPathView::mouseUngrabEvent()
{
    Q_D(QQuickPathView);
    if (d->stealMouse ||
            (!d->flicking && d->snapMode != NoSnap && !qFuzzyCompare(qRound(d->offset), d->offset))) {
        // if our mouse grab has been removed (probably by a Flickable),
        // or if we should snap but haven't done it, fix our state
        d->stealMouse = false;
        setKeepMouseGrab(false);
        d->timer.invalidate();
        d->fixOffset();
        d->setDragging(false);
        if (!d->tl.isActive())
            movementEnding();
    }
}

void QQuickPathView::updatePolish()
{
    QQuickItem::updatePolish();
    refill();
}

static inline int currentIndexRemainder(int currentIndex, int modelCount) Q_DECL_NOTHROW
{
    if (currentIndex < 0)
        return modelCount + currentIndex % modelCount;
    else
        return currentIndex % modelCount;
}

void QQuickPathView::componentComplete()
{
    Q_D(QQuickPathView);
    if (d->model && d->ownModel)
        static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();

    QQuickItem::componentComplete();

    if (d->model) {
        d->modelCount = d->model->count();
        if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex
            d->offset = std::fmod(qreal(d->modelCount - currentIndexRemainder(d->currentIndex, d->modelCount)), qreal(d->modelCount));
    }

    d->createHighlight();
    d->regenerate();
    d->updateHighlight();
    d->updateCurrent();

    if (d->modelCount)
        emit countChanged();
}

void QQuickPathView::refill()
{
    Q_D(QQuickPathView);

    if (d->inRefill) {
        d->scheduleLayout();
        return;
    }

    d->layoutScheduled = false;

    if (!d->isValid() || !isComponentComplete())
        return;

    d->inRefill = true;

    bool currentVisible = false;
    int count = d->pathItems == -1 ? d->modelCount : qMin(d->pathItems, d->modelCount);

    // first move existing items and remove items off path
    qCDebug(lcItemViewDelegateLifecycle) << "currentIndex" << d->currentIndex << "offset" << d->offset;
    QList<QQuickItem*>::iterator it = d->items.begin();
    while (it != d->items.end()) {
        QQuickItem *item = *it;
        int idx = d->model->indexOf(item, nullptr);
        qreal pos = d->positionOfIndex(idx);
        if (lcItemViewDelegateLifecycle().isDebugEnabled()) {
            QQuickText *text = qmlobject_cast<QQuickText*>(item);
            if (text)
                qCDebug(lcItemViewDelegateLifecycle) << "idx" << idx << "@" << pos << ": QQuickText" << text->objectName() << text->text().leftRef(40);
            else
                qCDebug(lcItemViewDelegateLifecycle) << "idx" << idx << "@" << pos << ":" << item;
        }
        if (pos < 1) {
            d->updateItem(item, pos);
            if (idx == d->currentIndex) {
                currentVisible = true;
                d->currentItemOffset = pos;
            }
            ++it;
        } else {
            d->updateItem(item, pos);
            if (QQuickPathViewAttached *att = d->attached(item))
                att->setOnPath(pos < 1);
            if (!d->isInBound(pos, d->mappedRange - d->mappedCache, 1 + d->mappedCache)) {
                qCDebug(lcItemViewDelegateLifecycle) << "release" << idx << "@" << pos << ", !isInBound: lower" << (d->mappedRange - d->mappedCache) << "upper" << (1 + d->mappedCache);
                d->releaseItem(item);
                it = d->items.erase(it);
            } else {
                ++it;
            }
        }
    }

    bool waiting = false;
    if (d->modelCount) {
        // add items as needed
        if (d->items.count() < count+d->cacheSize) {
            int endIdx = 0;
            qreal endPos;
            int startIdx = 0;
            qreal startPos = 0;
            const bool wasEmpty = d->items.isEmpty();
            if (!wasEmpty) {
                //Find the beginning and end, items may not be in sorted order
                endPos = -1;
                startPos = 2;

                for (QQuickItem * item : qAsConst(d->items)) {
                    int idx = d->model->indexOf(item, nullptr);
                    qreal curPos = d->positionOfIndex(idx);
                    if (curPos > endPos) {
                        endPos = curPos;
                        endIdx = idx;
                    }

                    if (curPos < startPos) {
                        startPos = curPos;
                        startIdx = idx;
                    }
                }
            } else {
                if (d->haveHighlightRange
                            && (d->highlightRangeMode != QQuickPathView::NoHighlightRange
                                    || d->snapMode != QQuickPathView::NoSnap))
                    startPos = d->highlightRangeStart;
                // With no items, then "end" is just off the top so we populate via append
                endIdx = (qRound(d->modelCount - d->offset) - 1) % d->modelCount;
                endPos = d->positionOfIndex(endIdx);
            }
            //Append
            int idx = endIdx + 1;
            if (idx >= d->modelCount)
                idx = 0;
            qreal nextPos = d->positionOfIndex(idx);
            while ((d->isInBound(nextPos, endPos, 1 + d->mappedCache) || !d->items.count())
                    && d->items.count() < count+d->cacheSize) {
                qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
                QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1);
                if (!item) {
                    waiting = true;
                    break;
                }
                if (d->items.contains(item)) {
                    d->releaseItem(item);
                    break; //Otherwise we'd "re-add" it, and get confused
                }
                if (d->currentIndex == idx) {
                    currentVisible = true;
                    d->currentItemOffset = nextPos;
                }
                d->items.append(item);
                d->updateItem(item, nextPos);
                endIdx = idx;
                endPos = nextPos;
                ++idx;
                if (idx >= d->modelCount)
                    idx = 0;
                nextPos = d->positionOfIndex(idx);
            }

            //Prepend
            idx = (wasEmpty ? d->calcCurrentIndex() : startIdx) - 1;

            if (idx < 0)
                idx = d->modelCount - 1;
            nextPos = d->positionOfIndex(idx);
            while (!waiting && d->isInBound(nextPos, d->mappedRange - d->mappedCache, startPos)
                    && d->items.count() < count+d->cacheSize) {
                qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count();
                QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1);
                if (!item) {
                    waiting = true;
                    break;
                }
                if (d->items.contains(item)) {
                    d->releaseItem(item);
                    break; //Otherwise we'd "re-add" it, and get confused
                }
                if (d->currentIndex == idx) {
                    currentVisible = true;
                    d->currentItemOffset = nextPos;
                }
                d->items.prepend(item);
                d->updateItem(item, nextPos);
                startIdx = idx;
                startPos = nextPos;
                --idx;
                if (idx < 0)
                    idx = d->modelCount - 1;
                nextPos = d->positionOfIndex(idx);
            }

            // In rare cases, when jumping around with pathCount close to modelCount,
            // new items appear in the middle. This more generic addition iteration handles this
            // Since this is the rare case, we try append/prepend first and only do this if
            // there are gaps still left to fill.
            if (!waiting && d->items.count() < count+d->cacheSize) {
                qCDebug(lcItemViewDelegateLifecycle) << "Checking for pathview middle inserts, items count was" << d->items.count();
                idx = startIdx;
                QQuickItem *lastItem = d->items.at(0);
                while (idx != endIdx) {
                    nextPos = d->positionOfIndex(idx);
                    if (d->isInBound(nextPos, d->mappedRange - d->mappedCache, 1 + d->mappedCache)) {
                        //This gets the reference from the delegate model, and will not re-create
                        QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1);
                        if (!item) {
                            waiting = true;
                            break;
                        }

                        if (!d->items.contains(item)) { //We found a hole
                            qCDebug(lcItemViewDelegateLifecycle) << "middle insert" << idx << "@" << nextPos
                                                                 << (d->currentIndex == idx ? "current" : "")
                                                                 << "items count was" << d->items.count();
                            if (d->currentIndex == idx) {
                                currentVisible = true;
                                d->currentItemOffset = nextPos;
                            }
                            int lastListIdx = d->items.indexOf(lastItem);
                            d->items.insert(lastListIdx + 1, item);
                            d->updateItem(item, nextPos);
                        } else {
                            d->releaseItem(item);
                        }

                        lastItem = item;
                    }

                    ++idx;
                    if (idx >= d->modelCount)
                        idx = 0;
                }
            }
        }
    }

    bool currentChanged = false;
    if (!currentVisible) {
        d->currentItemOffset = 1;
        if (d->currentItem) {
            d->updateItem(d->currentItem, 1);
        } else if (!waiting && d->currentIndex >= 0 && d->currentIndex < d->modelCount) {
            if ((d->currentItem = d->getItem(d->currentIndex, d->currentIndex))) {
                currentChanged = true;
                d->updateItem(d->currentItem, 1);
                if (QQuickPathViewAttached *att = d->attached(d->currentItem))
                    att->setIsCurrentItem(true);
            }
        }
    } else if (!waiting && !d->currentItem) {
        if ((d->currentItem = d->getItem(d->currentIndex, d->currentIndex))) {
            currentChanged = true;
            d->currentItem->setFocus(true);
            if (QQuickPathViewAttached *att = d->attached(d->currentItem))
                att->setIsCurrentItem(true);
        }
    }

    if (d->highlightItem && d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
        d->updateItem(d->highlightItem, d->highlightRangeStart);
        if (QQuickPathViewAttached *att = d->attached(d->highlightItem))
            att->setOnPath(true);
    } else if (d->highlightItem && d->moveReason != QQuickPathViewPrivate::SetIndex) {
        d->updateItem(d->highlightItem, d->currentItemOffset);
        if (QQuickPathViewAttached *att = d->attached(d->highlightItem))
            att->setOnPath(currentVisible);
    }
    for (QQuickItem *item : qAsConst(d->itemCache))
        d->releaseItem(item);
    d->itemCache.clear();

    d->inRefill = false;
    if (currentChanged)
        emit currentItemChanged();
}

void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
{
    Q_D(QQuickPathView);
    if (!d->model || !d->model->isValid() || !d->path || !isComponentComplete())
        return;

    if (reset) {
        d->modelCount = d->model->count();
        d->regenerate();
        emit countChanged();
        return;
    }

    if (changeSet.removes().isEmpty() && changeSet.inserts().isEmpty())
        return;

    const int modelCount = d->modelCount;
    int moveId = -1;
    int moveOffset = 0;
    bool currentChanged = false;
    bool changedOffset = false;
    for (const QQmlChangeSet::Change &r : changeSet.removes()) {
        if (moveId == -1 && d->currentIndex >= r.index + r.count) {
            d->currentIndex -= r.count;
            currentChanged = true;
        } else if (moveId == -1 && d->currentIndex >= r.index && d->currentIndex < r.index + r.count) {
            // current item has been removed.
            if (r.isMove()) {
                moveId = r.moveId;
                moveOffset = d->currentIndex - r.index;
            } else if (d->currentItem) {
                if (QQuickPathViewAttached *att = d->attached(d->currentItem))
                    att->setIsCurrentItem(true);
                d->releaseItem(d->currentItem);
                d->currentItem = nullptr;
            }
            d->currentIndex = qMin(r.index, d->modelCount - r.count - 1);
            currentChanged = true;
        }

        if (r.index > d->currentIndex) {
            changedOffset = true;
            d->offset -= r.count;
            d->offsetAdj -= r.count;
        }
        d->modelCount -= r.count;
    }
    for (const QQmlChangeSet::Change &i : changeSet.inserts()) {
        if (d->modelCount) {
            if (moveId == -1 && i.index <= d->currentIndex) {
                d->currentIndex += i.count;
                currentChanged = true;
            } else {
                if (moveId != -1 && moveId == i.moveId) {
                    d->currentIndex = i.index + moveOffset;
                    currentChanged = true;
                }
                if (i.index > d->currentIndex) {
                    d->offset += i.count;
                    d->offsetAdj += i.count;
                    changedOffset = true;
                }
            }
        }
        d->modelCount += i.count;
    }

    d->offset = std::fmod(d->offset, qreal(d->modelCount));
    if (d->offset < 0)
        d->offset += d->modelCount;
    if (d->currentIndex == -1)
        d->currentIndex = d->calcCurrentIndex();

    d->itemCache += d->items;
    d->items.clear();

    if (!d->modelCount) {
        for (QQuickItem * item : qAsConst(d->itemCache))
            d->releaseItem(item);
        d->itemCache.clear();
        d->offset = 0;
        changedOffset = true;
        d->tl.reset(d->moveOffset);
    } else {
        if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QQuickPathView::StrictlyEnforceRange) {
            d->offset = std::fmod(qreal(d->modelCount - d->currentIndex), qreal(d->modelCount));
            changedOffset = true;
        }
        d->updateMappedRange();
        d->scheduleLayout();
    }
    if (changedOffset)
        emit offsetChanged();
    if (currentChanged)
        emit currentIndexChanged();
    if (d->modelCount != modelCount)
        emit countChanged();
}

void QQuickPathView::destroyingItem(QObject *item)
{
    Q_UNUSED(item);
}

void QQuickPathView::ticked()
{
    Q_D(QQuickPathView);
    d->updateCurrent();
}

void QQuickPathView::movementEnding()
{
    Q_D(QQuickPathView);
    if (d->flicking) {
        d->flicking = false;
        emit flickingChanged();
        emit flickEnded();
    }
    if (d->moving && !d->stealMouse) {
        d->moving = false;
        emit movingChanged();
        emit movementEnded();
    }
    d->moveDirection = d->movementDirection;
}

// find the item closest to the snap position
int QQuickPathViewPrivate::calcCurrentIndex()
{
    int current = 0;
    if (modelCount && model && items.count()) {
        offset = std::fmod(offset, qreal(modelCount));
        if (offset < 0)
            offset += modelCount;
        current = qRound(qAbs(std::fmod(modelCount - offset, qreal(modelCount))));
        current = current % modelCount;
    }

    return current;
}

void QQuickPathViewPrivate::createCurrentItem()
{
    if (requestedIndex != -1)
        return;

    bool inItems = false;
    for (QQuickItem *item : qAsConst(items)) {
        if (model->indexOf(item, nullptr) == currentIndex) {
            inItems = true;
            break;
        }
    }

    if (inItems) {
        if ((currentItem = getItem(currentIndex, currentIndex))) {
            currentItem->setFocus(true);
            if (QQuickPathViewAttached *att = attached(currentItem))
                att->setIsCurrentItem(true);
        }
    } else if (currentIndex >= 0 && currentIndex < modelCount) {
        if ((currentItem = getItem(currentIndex, currentIndex))) {
            updateItem(currentItem, 1);
            if (QQuickPathViewAttached *att = attached(currentItem))
                att->setIsCurrentItem(true);
        }
    }
}

void QQuickPathViewPrivate::updateCurrent()
{
    Q_Q(QQuickPathView);
    if (moveReason == SetIndex)
        return;
    if (!modelCount || !haveHighlightRange || highlightRangeMode != QQuickPathView::StrictlyEnforceRange)
        return;

    int idx = calcCurrentIndex();
    if (model && (idx != currentIndex || !currentItem)) {
        if (currentItem) {
            if (QQuickPathViewAttached *att = attached(currentItem))
                att->setIsCurrentItem(false);
            releaseItem(currentItem);
        }
        int oldCurrentIndex = currentIndex;
        currentIndex = idx;
        currentItem = nullptr;
        createCurrentItem();
        if (oldCurrentIndex != currentIndex)
            emit q->currentIndexChanged();
        emit q->currentItemChanged();
    }
}

void QQuickPathViewPrivate::fixOffsetCallback(void *d)
{
    static_cast<QQuickPathViewPrivate *>(d)->fixOffset();
}

void QQuickPathViewPrivate::fixOffset()
{
    Q_Q(QQuickPathView);
    if (model && items.count()) {
        if (haveHighlightRange && (highlightRangeMode == QQuickPathView::StrictlyEnforceRange
                || snapMode != QQuickPathView::NoSnap)) {
            int curr = calcCurrentIndex();
            if (curr != currentIndex && highlightRangeMode == QQuickPathView::StrictlyEnforceRange)
                q->setCurrentIndex(curr);
            else
                snapToIndex(curr, Other);
        }
    }
}

void QQuickPathViewPrivate::snapToIndex(int index, MovementReason reason)
{
    if (!model || modelCount <= 0)
        return;

    qreal targetOffset = std::fmod(qreal(modelCount - index), qreal(modelCount));
    moveReason = reason;
    offsetAdj = 0;
    tl.reset(moveOffset);
    moveOffset.setValue(offset);

    const int duration = highlightMoveDuration;

    const qreal count = pathItems == -1 ? modelCount : qMin(pathItems, modelCount);
    const qreal averageItemLength = path->path().length() / count;
    const qreal threshold = 0.5 / averageItemLength; // if we are within .5 px, we want to immediately assign rather than animate

    if (!duration || qAbs(offset - targetOffset) < threshold || (qFuzzyIsNull(targetOffset) && qAbs(modelCount - offset) < threshold)) {
        tl.set(moveOffset, targetOffset);
    } else if (moveDirection == QQuickPathView::Positive || (moveDirection == QQuickPathView::Shortest && targetOffset - offset > modelCount/2)) {
        qreal distance = modelCount - targetOffset + offset;
        if (targetOffset > moveOffset) {
            tl.move(moveOffset, 0, QEasingCurve(QEasingCurve::InQuad), int(duration * offset / distance));
            tl.set(moveOffset, modelCount);
            tl.move(moveOffset, targetOffset, QEasingCurve(qFuzzyIsNull(offset) ? QEasingCurve::InOutQuad : QEasingCurve::OutQuad), int(duration * (modelCount-targetOffset) / distance));
        } else {
            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
        }
    } else if (moveDirection == QQuickPathView::Negative || targetOffset - offset <= -modelCount/2) {
        qreal distance = modelCount - offset + targetOffset;
        if (targetOffset < moveOffset) {
            tl.move(moveOffset, modelCount, QEasingCurve(qFuzzyIsNull(targetOffset) ? QEasingCurve::InOutQuad : QEasingCurve::InQuad), int(duration * (modelCount-offset) / distance));
            tl.set(moveOffset, 0);
            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::OutQuad), int(duration * targetOffset / distance));
        } else {
            tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
        }
    } else {
        tl.move(moveOffset, targetOffset, QEasingCurve(QEasingCurve::InOutQuad), duration);
    }
}

QQuickPathViewAttached *QQuickPathView::qmlAttachedProperties(QObject *obj)
{
    return new QQuickPathViewAttached(obj);
}

QT_END_NAMESPACE

#include "moc_qquickpathview_p.cpp"
