/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 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$
**
****************************************************************************/

#include "qquickscrollview_p.h"
#include "qquickpane_p_p.h"
#include "qquickscrollbar_p_p.h"

#include <QtQuick/private/qquickflickable_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype ScrollView
    \inherits Pane
//!     \instantiates QQuickScrollView
    \inqmlmodule QtQuick.Controls
    \since 5.9
    \ingroup qtquickcontrols2-containers
    \ingroup qtquickcontrols2-focusscopes
    \brief Scrollable view.

    ScrollView provides scrolling for user-defined content. It can be used to
    either replace a \l Flickable, or to decorate an existing one.

    \image qtquickcontrols2-scrollview.png

    The first example demonstrates the simplest usage of ScrollView.

    \snippet qtquickcontrols2-scrollview.qml file

    \note ScrollView does not automatically clip its contents. If it is not used as
    a full-screen item, you should consider setting the \l {Item::}{clip} property
    to \c true, as shown above.

    The second example illustrates using an existing \l Flickable, that is,
    a \l ListView.

    \snippet qtquickcontrols2-scrollview-listview.qml file

    \section2 Sizing

    As with Flickable, there are several things to keep in mind when using
    ScrollView:
    \list
        \li If only a single item is used within a ScrollView, the content size is
            automatically calculated based on the implicit size of its contained item.
            However, if more than one item is used (or an implicit size is not
            provided), the \l {QtQuick.Controls::Pane::}{contentWidth} and
            \l {QtQuick.Controls::Pane::}{contentHeight} properties must
            be set to the combined size of its contained items.
        \li If the content size is less than or equal to the size of the ScrollView,
            it will not be flickable.
    \endlist

    \section2 Scroll Bars

    The horizontal and vertical scroll bars can be accessed and customized using
    the \l {ScrollBar::horizontal}{ScrollBar.horizontal} and \l {ScrollBar::vertical}
    {ScrollBar.vertical} attached properties. The following example adjusts the scroll
    bar policies so that the horizontal scroll bar is always off, and the vertical
    scroll bar is always on.

    \snippet qtquickcontrols2-scrollview-policy.qml file

    \section2 Touch vs. Mouse Interaction

    On touch, ScrollView enables flicking and makes the scroll bars non-interactive.

    \image qtquickcontrols2-scrollindicator.gif

    When interacted with a mouse device, flicking is disabled and the scroll bars
    are interactive.

    \image qtquickcontrols2-scrollbar.gif

    Scroll bars can be made interactive on touch, or non-interactive when interacted
    with a mouse device, by setting the \l {ScrollBar::}{interactive} property explicitly
    to \c true or \c false, respectively.

    \snippet qtquickcontrols2-scrollview-interactive.qml file

    \sa ScrollBar, ScrollIndicator, {Customizing ScrollView}, {Container Controls},
        {Focus Management in Qt Quick Controls}
*/

class QQuickScrollViewPrivate : public QQuickPanePrivate
{
    Q_DECLARE_PUBLIC(QQuickScrollView)

public:
    QQmlListProperty<QObject> contentData() override;
    QQmlListProperty<QQuickItem> contentChildren() override;
    QList<QQuickItem *> contentChildItems() const override;

    QQuickItem *getContentItem() override;

    QQuickFlickable *ensureFlickable(bool content);
    bool setFlickable(QQuickFlickable *flickable, bool content);

    void flickableContentWidthChanged();
    void flickableContentHeightChanged();

    qreal getContentWidth() const override;
    qreal getContentHeight() const override;

    QQuickScrollBar *verticalScrollBar() const;
    QQuickScrollBar *horizontalScrollBar() const;

    void setScrollBarsInteractive(bool interactive);

    static void contentData_append(QQmlListProperty<QObject> *prop, QObject *obj);
    static int contentData_count(QQmlListProperty<QObject> *prop);
    static QObject *contentData_at(QQmlListProperty<QObject> *prop, int index);
    static void contentData_clear(QQmlListProperty<QObject> *prop);

    static void contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *obj);
    static int contentChildren_count(QQmlListProperty<QQuickItem> *prop);
    static QQuickItem *contentChildren_at(QQmlListProperty<QQuickItem> *prop, int index);
    static void contentChildren_clear(QQmlListProperty<QQuickItem> *prop);

    void itemImplicitWidthChanged(QQuickItem *item) override;

    bool wasTouched = false;
    QQuickFlickable *flickable = nullptr;
    bool flickableHasExplicitContentWidth = true;
    bool flickableHasExplicitContentHeight = true;
};

QList<QQuickItem *> QQuickScrollViewPrivate::contentChildItems() const
{
    if (!flickable)
        return QList<QQuickItem *>();

    return flickable->contentItem()->childItems();
}

QQuickItem *QQuickScrollViewPrivate::getContentItem()
{
    if (!contentItem)
        executeContentItem();
    return ensureFlickable(false);
}

QQuickFlickable *QQuickScrollViewPrivate::ensureFlickable(bool content)
{
    Q_Q(QQuickScrollView);
    if (!flickable) {
        flickableHasExplicitContentWidth = false;
        flickableHasExplicitContentHeight = false;
        setFlickable(new QQuickFlickable(q), content);
    }
    return flickable;
}

bool QQuickScrollViewPrivate::setFlickable(QQuickFlickable *item, bool content)
{
    Q_Q(QQuickScrollView);
    if (item == flickable)
        return false;

    QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false));

    if (flickable) {
        flickable->removeEventFilter(q);

        if (attached)
            QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(nullptr);

        QObjectPrivate::disconnect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange);
        QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::flickableContentWidthChanged);
        QObjectPrivate::disconnect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::flickableContentHeightChanged);
    }

    flickable = item;
    if (content)
        q->setContentItem(flickable);

    if (flickable) {
        flickable->installEventFilter(q);
        if (hasContentWidth)
            flickable->setContentWidth(contentWidth);
        else
            flickableContentWidthChanged();
        if (hasContentHeight)
            flickable->setContentHeight(contentHeight);
        else
            flickableContentHeightChanged();

        if (attached)
            QQuickScrollBarAttachedPrivate::get(attached)->setFlickable(flickable);

        QObjectPrivate::connect(flickable->contentItem(), &QQuickItem::childrenChanged, this, &QQuickPanePrivate::contentChildrenChange);
        QObjectPrivate::connect(flickable, &QQuickFlickable::contentWidthChanged, this, &QQuickScrollViewPrivate::flickableContentWidthChanged);
        QObjectPrivate::connect(flickable, &QQuickFlickable::contentHeightChanged, this, &QQuickScrollViewPrivate::flickableContentHeightChanged);
    }

    return true;
}

void QQuickScrollViewPrivate::flickableContentWidthChanged()
{
    Q_Q(QQuickScrollView);
    if (!flickable || !componentComplete)
        return;

    const qreal cw = flickable->contentWidth();
    if (qFuzzyCompare(cw, implicitContentWidth))
        return;

    flickableHasExplicitContentWidth = true;
    implicitContentWidth = cw;
    emit q->implicitContentWidthChanged();
}

void QQuickScrollViewPrivate::flickableContentHeightChanged()
{
    Q_Q(QQuickScrollView);
    if (!flickable || !componentComplete)
        return;

    const qreal ch = flickable->contentHeight();
    if (qFuzzyCompare(ch, implicitContentHeight))
        return;

    flickableHasExplicitContentHeight = true;
    implicitContentHeight = ch;
    emit q->implicitContentHeightChanged();
}

qreal QQuickScrollViewPrivate::getContentWidth() const
{
    if (flickable && flickableHasExplicitContentWidth)
        return flickable->contentWidth();

    // The scrollview wraps a flickable created by us, and nobody searched for it and
    // modified its contentWidth. In that case, since the application does not control
    // this flickable, we fall back to calculate the content width based on the child
    // items inside it.
    return QQuickPanePrivate::getContentWidth();
}

qreal QQuickScrollViewPrivate::getContentHeight() const
{
    if (flickable && flickableHasExplicitContentHeight)
        return flickable->contentHeight();

    // The scrollview wraps a flickable created by us, and nobody searched for it and
    // modified its contentHeight. In that case, since the application does not control
    // this flickable, we fall back to calculate the content height based on the child
    // items inside it.
    return QQuickPanePrivate::getContentHeight();
}

QQuickScrollBar *QQuickScrollViewPrivate::verticalScrollBar() const
{
    Q_Q(const QQuickScrollView);
    QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false));
    if (!attached)
        return nullptr;
    return attached->vertical();
}

QQuickScrollBar *QQuickScrollViewPrivate::horizontalScrollBar() const
{
    Q_Q(const QQuickScrollView);
    QQuickScrollBarAttached *attached = qobject_cast<QQuickScrollBarAttached *>(qmlAttachedPropertiesObject<QQuickScrollBar>(q, false));
    if (!attached)
        return nullptr;
    return attached->horizontal();
}

void QQuickScrollViewPrivate::setScrollBarsInteractive(bool interactive)
{
    QQuickScrollBar *hbar = horizontalScrollBar();
    if (hbar) {
        QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(hbar);
        if (!p->explicitInteractive)
            p->setInteractive(interactive);
    }

    QQuickScrollBar *vbar = verticalScrollBar();
    if (vbar) {
        QQuickScrollBarPrivate *p = QQuickScrollBarPrivate::get(vbar);
        if (!p->explicitInteractive)
            p->setInteractive(interactive);
    }
}

void QQuickScrollViewPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable && p->setFlickable(qobject_cast<QQuickFlickable *>(obj), true))
        return;

    QQuickFlickable *flickable = p->ensureFlickable(true);
    Q_ASSERT(flickable);
    QQmlListProperty<QObject> data = flickable->flickableData();
    data.append(&data, obj);
}

int QQuickScrollViewPrivate::contentData_count(QQmlListProperty<QObject> *prop)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        return 0;

    QQmlListProperty<QObject> data = p->flickable->flickableData();
    return data.count(&data);
}

QObject *QQuickScrollViewPrivate::contentData_at(QQmlListProperty<QObject> *prop, int index)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        return nullptr;

    QQmlListProperty<QObject> data = p->flickable->flickableData();
    return data.at(&data, index);
}

void QQuickScrollViewPrivate::contentData_clear(QQmlListProperty<QObject> *prop)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        return;

    QQmlListProperty<QObject> data = p->flickable->flickableData();
    return data.clear(&data);
}

void QQuickScrollViewPrivate::contentChildren_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        p->setFlickable(qobject_cast<QQuickFlickable *>(item), true);

    QQuickFlickable *flickable = p->ensureFlickable(true);
    Q_ASSERT(flickable);
    QQmlListProperty<QQuickItem> children = flickable->flickableChildren();
    children.append(&children, item);
}

int QQuickScrollViewPrivate::contentChildren_count(QQmlListProperty<QQuickItem> *prop)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        return 0;

    QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren();
    return children.count(&children);
}

QQuickItem *QQuickScrollViewPrivate::contentChildren_at(QQmlListProperty<QQuickItem> *prop, int index)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        return nullptr;

    QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren();
    return children.at(&children, index);
}

void QQuickScrollViewPrivate::contentChildren_clear(QQmlListProperty<QQuickItem> *prop)
{
    QQuickScrollViewPrivate *p = static_cast<QQuickScrollViewPrivate *>(prop->data);
    if (!p->flickable)
        return;

    QQmlListProperty<QQuickItem> children = p->flickable->flickableChildren();
    children.clear(&children);
}

void QQuickScrollViewPrivate::itemImplicitWidthChanged(QQuickItem *item)
{
    // a special case for width<->height dependent content (wrapping text) in ScrollView
    if (contentWidth < 0 && !componentComplete)
        return;

    QQuickPanePrivate::itemImplicitWidthChanged(item);
}

QQuickScrollView::QQuickScrollView(QQuickItem *parent)
    : QQuickPane(*(new QQuickScrollViewPrivate), parent)
{
    Q_D(QQuickScrollView);
    d->contentWidth = -1;
    d->contentHeight = -1;

    setFiltersChildMouseEvents(true);
    setWheelEnabled(true);
}

/*!
    \qmlproperty list<Object> QtQuick.Controls::ScrollView::contentData
    \default

    This property holds the list of content data.

    The list contains all objects that have been declared in QML as children of the view.

    \note Unlike \c contentChildren, \c contentData does include non-visual QML objects.

    \sa Item::data, contentChildren
*/
QQmlListProperty<QObject> QQuickScrollViewPrivate::contentData()
{
    Q_Q(QQuickScrollView);
    return QQmlListProperty<QObject>(q, this,
                                     QQuickScrollViewPrivate::contentData_append,
                                     QQuickScrollViewPrivate::contentData_count,
                                     QQuickScrollViewPrivate::contentData_at,
                                     QQuickScrollViewPrivate::contentData_clear);
}

/*!
    \qmlproperty list<Item> QtQuick.Controls::ScrollView::contentChildren

    This property holds the list of content children.

    The list contains all items that have been declared in QML as children of the view.

    \note Unlike \c contentData, \c contentChildren does not include non-visual QML objects.

    \sa Item::children, contentData
*/
QQmlListProperty<QQuickItem> QQuickScrollViewPrivate::contentChildren()
{
    Q_Q(QQuickScrollView);
    return QQmlListProperty<QQuickItem>(q, this,
                                        QQuickScrollViewPrivate::contentChildren_append,
                                        QQuickScrollViewPrivate::contentChildren_count,
                                        QQuickScrollViewPrivate::contentChildren_at,
                                        QQuickScrollViewPrivate::contentChildren_clear);
}

bool QQuickScrollView::childMouseEventFilter(QQuickItem *item, QEvent *event)
{
    Q_D(QQuickScrollView);
    switch (event->type()) {
    case QEvent::TouchBegin:
        d->wasTouched = true;
        d->setScrollBarsInteractive(false);
        return false;

    case QEvent::TouchEnd:
        d->wasTouched = false;
        return false;

    case QEvent::MouseButtonPress:
        // NOTE: Flickable does not handle touch events, only synthesized mouse events
        if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized) {
            d->wasTouched = false;
            d->setScrollBarsInteractive(true);
            return false;
        }
        return !d->wasTouched && item == d->flickable;

    case QEvent::MouseMove:
    case QEvent::MouseButtonRelease:
        if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized)
            return item == d->flickable;
        break;

    case QEvent::HoverEnter:
    case QEvent::HoverMove:
        if (d->wasTouched && (item == d->verticalScrollBar() || item == d->horizontalScrollBar()))
            d->setScrollBarsInteractive(true);
        break;

    default:
        break;
    }

    return false;
}

bool QQuickScrollView::eventFilter(QObject *object, QEvent *event)
{
    Q_D(QQuickScrollView);
    if (event->type() == QEvent::Wheel) {
        d->setScrollBarsInteractive(true);
        if (!d->wheelEnabled)
            return true;
    }
    return QQuickPane::eventFilter(object, event);
}

void QQuickScrollView::keyPressEvent(QKeyEvent *event)
{
    Q_D(QQuickScrollView);
    QQuickPane::keyPressEvent(event);
    switch (event->key()) {
    case Qt::Key_Up:
        if (QQuickScrollBar *vbar = d->verticalScrollBar()) {
            vbar->decrease();
            event->accept();
        }
        break;
    case Qt::Key_Down:
        if (QQuickScrollBar *vbar = d->verticalScrollBar()) {
            vbar->increase();
            event->accept();
        }
        break;
    case Qt::Key_Left:
        if (QQuickScrollBar *hbar = d->horizontalScrollBar()) {
            hbar->decrease();
            event->accept();
        }
        break;
    case Qt::Key_Right:
        if (QQuickScrollBar *hbar = d->horizontalScrollBar()) {
            hbar->increase();
            event->accept();
        }
        break;
    default:
        event->ignore();
        break;
    }
}

void QQuickScrollView::componentComplete()
{
    Q_D(QQuickScrollView);
    QQuickPane::componentComplete();
    if (!d->contentItem)
        d->ensureFlickable(true);
}

void QQuickScrollView::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
    Q_D(QQuickScrollView);
    if (newItem != d->flickable) {
        // The new flickable was not created by us. In that case, we always
        // assume/require that it has an explicit content size assigned.
        d->flickableHasExplicitContentWidth = true;
        d->flickableHasExplicitContentHeight = true;
        d->setFlickable(qobject_cast<QQuickFlickable *>(newItem), false);
    }
    QQuickPane::contentItemChange(newItem, oldItem);
}

void QQuickScrollView::contentSizeChange(const QSizeF &newSize, const QSizeF &oldSize)
{
    Q_D(QQuickScrollView);
    QQuickPane::contentSizeChange(newSize, oldSize);
    if (d->flickable) {
        // Only set the content size on the flickable if the flickable doesn't
        // have an explicit assignment from before. Otherwise we can end up overwriting
        // assignments done to those properties by the application. The
        // exception is if the application has assigned a content size
        // directly to the scrollview, which will then win even if the
        // application has assigned something else to the flickable.
        if (d->hasContentWidth || !d->flickableHasExplicitContentWidth)
            d->flickable->setContentWidth(newSize.width());
        if (d->hasContentHeight || !d->flickableHasExplicitContentHeight)
            d->flickable->setContentHeight(newSize.height());
    }
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickScrollView::accessibleRole() const
{
    return QAccessible::Pane;
}
#endif

QT_END_NAMESPACE

#include "moc_qquickscrollview_p.cpp"
