/****************************************************************************
**
** 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 "qquickdial_p.h"
#include "qquickdeferredexecute_p_p.h"

#include <QtCore/qmath.h>
#include <QtQuick/private/qquickflickable_p.h>
#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype Dial
    \inherits Control
//!     \instantiates QQuickDial
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-input
    \brief Circular dial that is rotated to set a value.

    The Dial is similar to a traditional dial knob that is found on devices
    such as stereos or industrial equipment. It allows the user to specify a
    value within a range.

    \image qtquickcontrols2-dial-no-wrap.gif

    The value of the dial is set with the \l value property. The range is
    set with the \l from and \l to properties. To enable or disable wrapping,
    use the \l wrap property.

    The dial can be manipulated with a keyboard. It supports the following
    actions:

    \table
    \header \li \b {Action} \li \b {Key}
    \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Left
    \row \li Decrease \l value by \l stepSize \li \c Qt.Key_Down
    \row \li Set \l value to \l from \li \c Qt.Key_Home
    \row \li Increase \l value by \l stepSize \li \c Qt.Key_Right
    \row \li Increase \l value by \l stepSize \li \c Qt.Key_Up
    \row \li Set \l value to \l to \li \c Qt.Key_End
    \endtable

    \include qquickdial.qdocinc inputMode

    \sa {Customizing Dial}, {Input Controls}
*/

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlsignal QtQuick.Controls::Dial::moved()

    This signal is emitted when the dial has been interactively moved
    by the user by either touch, mouse, or keys.
*/

static const qreal startAngleRadians = (M_PI * 2.0) * (4.0 / 6.0);
static const qreal startAngle = -140;
static const qreal endAngleRadians = (M_PI * 2.0) * (5.0 / 6.0);
static const qreal endAngle = 140;

class QQuickDialPrivate : public QQuickControlPrivate
{
    Q_DECLARE_PUBLIC(QQuickDial)

public:
    qreal valueAt(qreal position) const;
    qreal snapPosition(qreal position) const;
    qreal positionAt(const QPointF &point) const;
    qreal circularPositionAt(const QPointF &point) const;
    qreal linearPositionAt(const QPointF &point) const;
    void setPosition(qreal position);
    void updatePosition();
    bool isLargeChange(const QPointF &eventPos, qreal proposedPosition) const;
    bool isHorizontalOrVertical() const;

    void handlePress(const QPointF &point) override;
    void handleMove(const QPointF &point) override;
    void handleRelease(const QPointF &point) override;
    void handleUngrab() override;

    void cancelHandle();
    void executeHandle(bool complete = false);

    qreal from = 0;
    qreal to = 1;
    qreal value = 0;
    qreal position = 0;
    qreal angle = startAngle;
    qreal stepSize = 0;
    bool pressed = false;
    QPointF pressPoint;
    qreal positionBeforePress = 0;
    QQuickDial::SnapMode snapMode = QQuickDial::NoSnap;
    QQuickDial::InputMode inputMode = QQuickDial::Circular;
    bool wrap = false;
    bool live = true;
    QQuickDeferredPointer<QQuickItem> handle;
};

qreal QQuickDialPrivate::valueAt(qreal position) const
{
    return from + (to - from) * position;
}

qreal QQuickDialPrivate::snapPosition(qreal position) const
{
    const qreal range = to - from;
    if (qFuzzyIsNull(range))
        return position;

    const qreal effectiveStep = stepSize / range;
    if (qFuzzyIsNull(effectiveStep))
        return position;

    return qRound(position / effectiveStep) * effectiveStep;
}

qreal QQuickDialPrivate::positionAt(const QPointF &point) const
{
    return inputMode == QQuickDial::Circular ? circularPositionAt(point) : linearPositionAt(point);
}

qreal QQuickDialPrivate::circularPositionAt(const QPointF &point) const
{
    qreal yy = height / 2.0 - point.y();
    qreal xx = point.x() - width / 2.0;
    qreal angle = (xx || yy) ? std::atan2(yy, xx) : 0;

    if (angle < M_PI / -2)
        angle = angle + M_PI * 2;

    qreal normalizedAngle = (startAngleRadians - angle) / endAngleRadians;
    return normalizedAngle;
}

qreal QQuickDialPrivate::linearPositionAt(const QPointF &point) const
{
    // This value determines the range (either horizontal or vertical)
    // within which the dial can be dragged.
    // The larger this value is, the further the drag distance
    // must be to go from a position of e.g. 0.0 to 1.0.
    qreal dragArea = 0;

    // The linear input mode uses a "relative" input system,
    // where the distance from the press point is used to calculate
    // the change in position. Moving the mouse above the press
    // point increases the position (when inputMode is Vertical),
    // and vice versa. This prevents the dial from jumping when clicked.
    qreal dragDistance = 0;

    if (inputMode == QQuickDial::Horizontal) {
        dragArea = width * 2;
        dragDistance = pressPoint.x() - point.x();
    } else {
        dragArea = height * 2;
        dragDistance = point.y() - pressPoint.y();
    }
    const qreal normalisedDifference = dragDistance / dragArea;
    return qBound(qreal(0), positionBeforePress - normalisedDifference, qreal(1));
}

void QQuickDialPrivate::setPosition(qreal pos)
{
    Q_Q(QQuickDial);
    pos = qBound<qreal>(qreal(0), pos, qreal(1));
    if (qFuzzyCompare(position, pos))
        return;

    position = pos;

    angle = startAngle + position * qAbs(endAngle - startAngle);

    emit q->positionChanged();
    emit q->angleChanged();
}

void QQuickDialPrivate::updatePosition()
{
    qreal pos = 0;
    if (!qFuzzyCompare(from, to))
        pos = (value - from) / (to - from);
    setPosition(pos);
}

bool QQuickDialPrivate::isLargeChange(const QPointF &eventPos, qreal proposedPosition) const
{
    return qAbs(proposedPosition - position) >= qreal(0.5) && eventPos.y() >= height / 2;
}

bool QQuickDialPrivate::isHorizontalOrVertical() const
{
    return inputMode == QQuickDial::Horizontal || inputMode == QQuickDial::Vertical;
}

void QQuickDialPrivate::handlePress(const QPointF &point)
{
    Q_Q(QQuickDial);
    QQuickControlPrivate::handlePress(point);
    pressPoint = point;
    positionBeforePress = position;
    q->setPressed(true);
}

void QQuickDialPrivate::handleMove(const QPointF &point)
{
    Q_Q(QQuickDial);
    QQuickControlPrivate::handleMove(point);
    const qreal oldPos = position;
    qreal pos = positionAt(point);
    if (snapMode == QQuickDial::SnapAlways)
        pos = snapPosition(pos);

    if (wrap || (!wrap && (isHorizontalOrVertical() || !isLargeChange(point, pos)))) {
        if (live)
            q->setValue(valueAt(pos));
        else
            setPosition(pos);
        if (!qFuzzyCompare(pos, oldPos))
            emit q->moved();
    }
}

void QQuickDialPrivate::handleRelease(const QPointF &point)
{
    Q_Q(QQuickDial);
    QQuickControlPrivate::handleRelease(point);
    if (q->keepMouseGrab() || q->keepTouchGrab()) {
        const qreal oldPos = position;
        qreal pos = positionAt(point);
        if (snapMode != QQuickDial::NoSnap)
            pos = snapPosition(pos);

        if (wrap || (!wrap && (isHorizontalOrVertical() || !isLargeChange(point, pos))))
            q->setValue(valueAt(pos));
        if (!qFuzzyCompare(pos, oldPos))
            emit q->moved();

        q->setKeepMouseGrab(false);
        q->setKeepTouchGrab(false);
    }

    q->setPressed(false);
    pressPoint = QPointF();
    positionBeforePress = 0;
}

void QQuickDialPrivate::handleUngrab()
{
    Q_Q(QQuickDial);
    QQuickControlPrivate::handleUngrab();
    pressPoint = QPointF();
    positionBeforePress = 0;
    q->setPressed(false);
}

static inline QString handleName() { return QStringLiteral("handle"); }

void QQuickDialPrivate::cancelHandle()
{
    Q_Q(QQuickDial);
    quickCancelDeferred(q, handleName());
}

void QQuickDialPrivate::executeHandle(bool complete)
{
    Q_Q(QQuickDial);
    if (handle.wasExecuted())
        return;

    if (!handle || complete)
        quickBeginDeferred(q, handleName(), handle);
    if (complete)
        quickCompleteDeferred(q, handleName(), handle);
}

QQuickDial::QQuickDial(QQuickItem *parent)
    : QQuickControl(*(new QQuickDialPrivate), parent)
{
    setActiveFocusOnTab(true);
    setAcceptedMouseButtons(Qt::LeftButton);
#if QT_CONFIG(cursor)
    setCursor(Qt::ArrowCursor);
#endif
}

/*!
    \qmlproperty real QtQuick.Controls::Dial::from

    This property holds the starting value for the range. The default value is \c 0.0.

    \sa to, value
*/
qreal QQuickDial::from() const
{
    Q_D(const QQuickDial);
    return d->from;
}

void QQuickDial::setFrom(qreal from)
{
    Q_D(QQuickDial);
    if (qFuzzyCompare(d->from, from))
        return;

    d->from = from;
    emit fromChanged();
    if (isComponentComplete()) {
        setValue(d->value);
        d->updatePosition();
    }
}

/*!
    \qmlproperty real QtQuick.Controls::Dial::to

    This property holds the end value for the range. The default value is
    \c 1.0.

    \sa from, value
*/
qreal QQuickDial::to() const
{
    Q_D(const QQuickDial);
    return d->to;
}

void QQuickDial::setTo(qreal to)
{
    Q_D(QQuickDial);
    if (qFuzzyCompare(d->to, to))
        return;

    d->to = to;
    emit toChanged();
    if (isComponentComplete()) {
        setValue(d->value);
        d->updatePosition();
    }
}

/*!
    \qmlproperty real QtQuick.Controls::Dial::value

    This property holds the value in the range \c from - \c to. The default
    value is \c 0.0.

    \sa position, live
*/
qreal QQuickDial::value() const
{
    Q_D(const QQuickDial);
    return d->value;
}

void QQuickDial::setValue(qreal value)
{
    Q_D(QQuickDial);
    if (isComponentComplete())
        value = d->from > d->to ? qBound(d->to, value, d->from) : qBound(d->from, value, d->to);

    if (qFuzzyCompare(d->value, value))
        return;

    d->value = value;
    d->updatePosition();
    emit valueChanged();
}

/*!
    \qmlproperty real QtQuick.Controls::Dial::position
    \readonly

    This property holds the logical position of the handle.

    The position is expressed as a fraction of the control's angle range (the
    range within which the handle can be moved) in the range \c {0.0 - 1.0}.

    \sa value, angle
*/
qreal QQuickDial::position() const
{
    Q_D(const QQuickDial);
    return d->position;
}

/*!
    \qmlproperty real QtQuick.Controls::Dial::angle
    \readonly

    This property holds the angle of the handle.

    The range is from \c -140 degrees to \c 140 degrees.

    \sa position
*/
qreal QQuickDial::angle() const
{
    Q_D(const QQuickDial);
    return d->angle;
}

/*!
    \qmlproperty real QtQuick.Controls::Dial::stepSize

    This property holds the step size.

    The step size determines the amount by which the dial's value
    is increased and decreased when interacted with via the keyboard.
    For example, a step size of \c 0.2, will result in the dial's
    value increasing and decreasing in increments of \c 0.2.

    The step size is only respected for touch and mouse interaction
    when \l snapMode is set to a value other than \c Dial.NoSnap.

    The default value is \c 0.0, which results in an effective step
    size of \c 0.1 for keyboard interaction.

    \sa snapMode, increase(), decrease()
*/
qreal QQuickDial::stepSize() const
{
    Q_D(const QQuickDial);
    return d->stepSize;
}

void QQuickDial::setStepSize(qreal step)
{
    Q_D(QQuickDial);
    if (qFuzzyCompare(d->stepSize, step))
        return;

    d->stepSize = step;
    emit stepSizeChanged();
}

/*!
    \qmlproperty enumeration QtQuick.Controls::Dial::snapMode

    This property holds the snap mode.

    The snap mode works with the \l stepSize to allow the handle to snap to
    certain points along the dial.

    Possible values:
    \value Dial.NoSnap The dial does not snap (default).
    \value Dial.SnapAlways The dial snaps while the handle is dragged.
    \value Dial.SnapOnRelease The dial does not snap while being dragged, but only after the handle is released.

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

void QQuickDial::setSnapMode(SnapMode mode)
{
    Q_D(QQuickDial);
    if (d->snapMode == mode)
        return;

    d->snapMode = mode;
    emit snapModeChanged();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty enumeration QtQuick.Controls::Dial::inputMode

    This property holds the input mode.

    \include qquickdial.qdocinc inputMode

    The default value is \c Dial.Circular.
*/
QQuickDial::InputMode QQuickDial::inputMode() const
{
    Q_D(const QQuickDial);
    return d->inputMode;
}

void QQuickDial::setInputMode(QQuickDial::InputMode mode)
{
    Q_D(QQuickDial);
    if (d->inputMode == mode)
        return;

    d->inputMode = mode;
    emit inputModeChanged();
}

/*!
    \qmlproperty bool QtQuick.Controls::Dial::wrap

    This property holds whether the dial wraps when dragged.

    For example, when this property is set to \c true, dragging the dial past
    the \l to position will result in the handle being positioned at the
    \l from position, and vice versa:

    \image qtquickcontrols2-dial-wrap.gif

    When this property is \c false, it's not possible to drag the dial across
    the from and to values.

    \image qtquickcontrols2-dial-no-wrap.gif

    The default value is \c false.
*/
bool QQuickDial::wrap() const
{
    Q_D(const QQuickDial);
    return d->wrap;
}

void QQuickDial::setWrap(bool wrap)
{
    Q_D(QQuickDial);
    if (d->wrap == wrap)
        return;

    d->wrap = wrap;
    emit wrapChanged();
}

/*!
    \qmlproperty bool QtQuick.Controls::Dial::pressed

    This property holds whether the dial is pressed.

    The dial will be pressed when either the mouse is pressed over it, or a key
    such as \c Qt.Key_Left is held down. If you'd prefer not to have the dial
    be pressed upon key presses (due to styling reasons, for example), you can
    use the \l {Keys}{Keys attached property}:

    \code
    Dial {
        Keys.onLeftPressed: {}
    }
    \endcode

    This will result in pressed only being \c true upon mouse presses.
*/
bool QQuickDial::isPressed() const
{
    Q_D(const QQuickDial);
    return d->pressed;
}

void QQuickDial::setPressed(bool pressed)
{
    Q_D(QQuickDial);
    if (d->pressed == pressed)
        return;

    d->pressed = pressed;
    setAccessibleProperty("pressed", pressed);
    emit pressedChanged();
}

/*!
    \qmlproperty Item QtQuick.Controls::Dial::handle

    This property holds the handle of the dial.

    The handle acts as a visual indicator of the position of the dial.

    \sa {Customizing Dial}
*/
QQuickItem *QQuickDial::handle() const
{
    QQuickDialPrivate *d = const_cast<QQuickDialPrivate *>(d_func());
    if (!d->handle)
        d->executeHandle();
    return d->handle;
}

void QQuickDial::setHandle(QQuickItem *handle)
{
    Q_D(QQuickDial);
    if (handle == d->handle)
        return;

    if (!d->handle.isExecuting())
        d->cancelHandle();

    delete d->handle;
    d->handle = handle;
    if (d->handle && !d->handle->parentItem())
        d->handle->setParentItem(this);
    if (!d->handle.isExecuting())
        emit handleChanged();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::Dial::live

    This property holds whether the dial provides live updates for the \l value
    property while the handle is dragged.

    The default value is \c true.

    \sa value
*/
bool QQuickDial::live() const
{
    Q_D(const QQuickDial);
    return d->live;
}

void QQuickDial::setLive(bool live)
{
    Q_D(QQuickDial);
    if (d->live == live)
        return;

    d->live = live;
    emit liveChanged();
}

/*!
    \qmlmethod void QtQuick.Controls::Dial::increase()

    Increases the value by \l stepSize, or \c 0.1 if stepSize is not defined.

    \sa stepSize
*/
void QQuickDial::increase()
{
    Q_D(QQuickDial);
    qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
    setValue(d->value + step);
}

/*!
    \qmlmethod void QtQuick.Controls::Dial::decrease()

    Decreases the value by \l stepSize, or \c 0.1 if stepSize is not defined.

    \sa stepSize
*/
void QQuickDial::decrease()
{
    Q_D(QQuickDial);
    qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
    setValue(d->value - step);
}

void QQuickDial::keyPressEvent(QKeyEvent *event)
{
    Q_D(QQuickDial);
    const qreal oldValue = d->value;
    switch (event->key()) {
    case Qt::Key_Left:
    case Qt::Key_Down:
        setPressed(true);
        if (isMirrored())
            increase();
        else
            decrease();
        break;

    case Qt::Key_Right:
    case Qt::Key_Up:
        setPressed(true);
        if (isMirrored())
            decrease();
        else
            increase();
        break;

    case Qt::Key_Home:
        setPressed(true);
        setValue(isMirrored() ? d->to : d->from);
        break;

    case Qt::Key_End:
        setPressed(true);
        setValue(isMirrored() ? d->from : d->to);
        break;

    default:
        event->ignore();
        QQuickControl::keyPressEvent(event);
        break;
    }
    if (!qFuzzyCompare(d->value, oldValue))
        emit moved();
}

void QQuickDial::keyReleaseEvent(QKeyEvent *event)
{
    QQuickControl::keyReleaseEvent(event);
    setPressed(false);
}

void QQuickDial::mousePressEvent(QMouseEvent *event)
{
    Q_D(QQuickDial);
    QQuickControl::mousePressEvent(event);
    d->handleMove(event->localPos());
    setKeepMouseGrab(true);
}

#if QT_CONFIG(quicktemplates2_multitouch)
void QQuickDial::touchEvent(QTouchEvent *event)
{
    Q_D(QQuickDial);
    switch (event->type()) {
    case QEvent::TouchUpdate:
        for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
            if (!d->acceptTouch(point))
                continue;

            switch (point.state()) {
            case Qt::TouchPointMoved:
                if (!keepTouchGrab()) {
                    bool overXDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().x() - d->pressPoint.x(), Qt::XAxis, &point);
                    setKeepTouchGrab(overXDragThreshold);

                    if (!overXDragThreshold) {
                        bool overYDragThreshold = QQuickWindowPrivate::dragOverThreshold(point.pos().y() - d->pressPoint.y(), Qt::YAxis, &point);
                        setKeepTouchGrab(overYDragThreshold);
                    }
                }
                if (keepTouchGrab())
                    d->handleMove(point.pos());
                break;

            default:
                QQuickControl::touchEvent(event);
                break;
            }
        }
        break;

    default:
        QQuickControl::touchEvent(event);
        break;
    }
}
#endif

#if QT_CONFIG(wheelevent)
void QQuickDial::wheelEvent(QWheelEvent *event)
{
    Q_D(QQuickDial);
    QQuickControl::wheelEvent(event);
    if (d->wheelEnabled) {
        const qreal oldValue = d->value;
        const QPointF angle = event->angleDelta();
        const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : (event->inverted() ? -angle.y() : angle.y())) / QWheelEvent::DefaultDeltasPerStep;
        const qreal step = qFuzzyIsNull(d->stepSize) ? 0.1 : d->stepSize;
        setValue(oldValue + step * delta);
        event->setAccepted(!qFuzzyCompare(d->value, oldValue));
    }
}
#endif

void QQuickDial::mirrorChange()
{
    QQuickControl::mirrorChange();
    emit angleChanged();
}

void QQuickDial::componentComplete()
{
    Q_D(QQuickDial);
    d->executeHandle(true);
    QQuickControl::componentComplete();
    setValue(d->value);
    d->updatePosition();
}

#if QT_CONFIG(accessibility)
void QQuickDial::accessibilityActiveChanged(bool active)
{
    QQuickControl::accessibilityActiveChanged(active);

    Q_D(QQuickDial);
    if (active)
        setAccessibleProperty("pressed", d->pressed);
}

QAccessible::Role QQuickDial::accessibleRole() const
{
    return QAccessible::Dial;
}
#endif

QT_END_NAMESPACE
