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

#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>

#include <QtQml/qqmlinfo.h>
#include <QtQml/private/qqmllocale_p.h>
#include <QtQml/private/qqmlengine_p.h>
#include <QtQuick/private/qquicktextinput_p.h>

QT_BEGIN_NAMESPACE

// copied from qabstractbutton.cpp
static const int AUTO_REPEAT_DELAY = 300;
static const int AUTO_REPEAT_INTERVAL = 100;

/*!
    \qmltype SpinBox
    \inherits Control
//!     \instantiates QQuickSpinBox
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup input
    \ingroup qtquickcontrols2-focusscopes
    \brief Allows the user to select from a set of preset values.

    \image qtquickcontrols2-spinbox.png

    SpinBox allows the user to choose an integer value by clicking the up
    or down indicator buttons, or by pressing up or down on the keyboard.
    Optionally, SpinBox can be also made \l editable, so the user can enter
    a text value in the input field.

    By default, SpinBox provides discrete values in the range of \c [0-99]
    with a \l stepSize of \c 1.

    \snippet qtquickcontrols2-spinbox.qml 1

    \section2 Custom Values

    \image qtquickcontrols2-spinbox-textual.png

    Even though SpinBox works on integer values, it can be customized to
    accept arbitrary input values. The following snippet demonstrates how
    \l validator, \l textFromValue and \l valueFromText can be used to
    customize the default behavior.

    \snippet qtquickcontrols2-spinbox-textual.qml 1

    In the same manner, SpinBox can be customized to accept floating point
    numbers:

    \image qtquickcontrols2-spinbox-double.png

    \snippet qtquickcontrols2-spinbox-double.qml 1

    \sa Tumbler, {Customizing SpinBox}, {Focus Management in Qt Quick Controls}
*/

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlsignal QtQuick.Controls::SpinBox::valueModified()

    This signal is emitted when the spin box value has been interactively
    modified by the user by either touch, mouse, wheel, or keys.
*/

class QQuickSpinBoxPrivate : public QQuickControlPrivate
{
    Q_DECLARE_PUBLIC(QQuickSpinBox)

public:
    int boundValue(int value, bool wrap) const;
    void updateValue();
    bool setValue(int value, bool wrap, bool modified);
    bool stepBy(int steps, bool modified);
    void increase(bool modified);
    void decrease(bool modified);

    int effectiveStepSize() const;

    void updateDisplayText();
    void setDisplayText(const QString &displayText);

    bool upEnabled() const;
    void updateUpEnabled();
    bool downEnabled() const;
    void updateDownEnabled();
    void updateHover(const QPointF &pos);

    void startRepeatDelay();
    void startPressRepeat();
    void stopPressRepeat();

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

    void itemImplicitWidthChanged(QQuickItem *item) override;
    void itemImplicitHeightChanged(QQuickItem *item) override;

    bool editable = false;
    bool wrap = false;
    int from = 0;
    int to = 99;
    int value = 0;
    int stepSize = 1;
    int delayTimer = 0;
    int repeatTimer = 0;
    QString displayText;
    QQuickSpinButton *up = nullptr;
    QQuickSpinButton *down = nullptr;
    QValidator *validator = nullptr;
    mutable QJSValue textFromValue;
    mutable QJSValue valueFromText;
    Qt::InputMethodHints inputMethodHints = Qt::ImhDigitsOnly;
};

class QQuickSpinButtonPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QQuickSpinButton)

public:
    static QQuickSpinButtonPrivate *get(QQuickSpinButton *button)
    {
        return button->d_func();
    }

    void cancelIndicator();
    void executeIndicator(bool complete = false);

    bool pressed = false;
    bool hovered = false;
    QQuickDeferredPointer<QQuickItem> indicator;
};

int QQuickSpinBoxPrivate::boundValue(int value, bool wrap) const
{
    bool inverted = from > to;
    if (!wrap)
        return inverted ? qBound(to, value, from) : qBound(from, value, to);

    int f = inverted ? to : from;
    int t = inverted ? from : to;
    if (value < f)
        value = t;
    else if (value > t)
        value = f;

    return value;
}

void QQuickSpinBoxPrivate::updateValue()
{
    Q_Q(QQuickSpinBox);
    if (contentItem) {
        QVariant text = contentItem->property("text");
        if (text.isValid()) {
            int val = 0;
            QQmlEngine *engine = qmlEngine(q);
            if (engine && valueFromText.isCallable()) {
                QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine);
                QJSValue loc(v4, QQmlLocale::wrap(v4, locale));
                val = valueFromText.call(QJSValueList() << text.toString() << loc).toInt();
            } else {
                val = locale.toInt(text.toString());
            }
            setValue(val, /* allowWrap = */ false, /* modified = */ true);
        }
    }
}

bool QQuickSpinBoxPrivate::setValue(int newValue, bool allowWrap, bool modified)
{
    Q_Q(QQuickSpinBox);
    if (q->isComponentComplete())
        newValue = boundValue(newValue, allowWrap);

    if (value == newValue)
        return false;

    value = newValue;

    updateDisplayText();
    updateUpEnabled();
    updateDownEnabled();

    emit q->valueChanged();
    if (modified)
        emit q->valueModified();
    return true;
}

bool QQuickSpinBoxPrivate::stepBy(int steps, bool modified)
{
    return setValue(value + steps, wrap, modified);
}

void QQuickSpinBoxPrivate::increase(bool modified)
{
    setValue(value + effectiveStepSize(), wrap, modified);
}

void QQuickSpinBoxPrivate::decrease(bool modified)
{
    setValue(value - effectiveStepSize(), wrap, modified);
}

int QQuickSpinBoxPrivate::effectiveStepSize() const
{
    return from > to ? -1 * stepSize : stepSize;
}

void QQuickSpinBoxPrivate::updateDisplayText()
{
    Q_Q(QQuickSpinBox);
    QString text;
    QQmlEngine *engine = qmlEngine(q);
    if (engine && textFromValue.isCallable()) {
        QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine);
        QJSValue loc(v4, QQmlLocale::wrap(v4, locale));
        text = textFromValue.call(QJSValueList() << value << loc).toString();
    } else {
        text = locale.toString(value);
    }
    setDisplayText(text);
}

void QQuickSpinBoxPrivate::setDisplayText(const QString &text)
{
    Q_Q(QQuickSpinBox);
    if (displayText == text)
        return;

    displayText = text;
    emit q->displayTextChanged();
}

bool QQuickSpinBoxPrivate::upEnabled() const
{
    const QQuickItem *upIndicator = up->indicator();
    return upIndicator && upIndicator->isEnabled();
}

void QQuickSpinBoxPrivate::updateUpEnabled()
{
    QQuickItem *upIndicator = up->indicator();
    if (!upIndicator)
        return;

    upIndicator->setEnabled(wrap || (from < to ? value < to : value > to));
}

bool QQuickSpinBoxPrivate::downEnabled() const
{
    const QQuickItem *downIndicator = down->indicator();
    return downIndicator && downIndicator->isEnabled();
}

void QQuickSpinBoxPrivate::updateDownEnabled()
{
    QQuickItem *downIndicator = down->indicator();
    if (!downIndicator)
        return;

    downIndicator->setEnabled(wrap || (from < to ? value > from : value < from));
}

void QQuickSpinBoxPrivate::updateHover(const QPointF &pos)
{
    Q_Q(QQuickSpinBox);
    QQuickItem *ui = up->indicator();
    QQuickItem *di = down->indicator();
    up->setHovered(ui && ui->isEnabled() && ui->contains(q->mapToItem(ui, pos)));
    down->setHovered(di && di->isEnabled() && di->contains(q->mapToItem(di, pos)));
}

void QQuickSpinBoxPrivate::startRepeatDelay()
{
    Q_Q(QQuickSpinBox);
    stopPressRepeat();
    delayTimer = q->startTimer(AUTO_REPEAT_DELAY);
}

void QQuickSpinBoxPrivate::startPressRepeat()
{
    Q_Q(QQuickSpinBox);
    stopPressRepeat();
    repeatTimer = q->startTimer(AUTO_REPEAT_INTERVAL);
}

void QQuickSpinBoxPrivate::stopPressRepeat()
{
    Q_Q(QQuickSpinBox);
    if (delayTimer > 0) {
        q->killTimer(delayTimer);
        delayTimer = 0;
    }
    if (repeatTimer > 0) {
        q->killTimer(repeatTimer);
        repeatTimer = 0;
    }
}

void QQuickSpinBoxPrivate::handlePress(const QPointF &point)
{
    Q_Q(QQuickSpinBox);
    QQuickControlPrivate::handlePress(point);
    QQuickItem *ui = up->indicator();
    QQuickItem *di = down->indicator();
    up->setPressed(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point)));
    down->setPressed(di && di->isEnabled() && di->contains(di->mapFromItem(q, point)));

    bool pressed = up->isPressed() || down->isPressed();
    q->setAccessibleProperty("pressed", pressed);
    if (pressed)
        startRepeatDelay();
}

void QQuickSpinBoxPrivate::handleMove(const QPointF &point)
{
    Q_Q(QQuickSpinBox);
    QQuickControlPrivate::handleMove(point);
    QQuickItem *ui = up->indicator();
    QQuickItem *di = down->indicator();
    up->setHovered(ui && ui->isEnabled() && ui->contains(ui->mapFromItem(q, point)));
    up->setPressed(up->isHovered());
    down->setHovered(di && di->isEnabled() && di->contains(di->mapFromItem(q, point)));
    down->setPressed(down->isHovered());

    bool pressed = up->isPressed() || down->isPressed();
    q->setAccessibleProperty("pressed", pressed);
    if (!pressed)
        stopPressRepeat();
}

void QQuickSpinBoxPrivate::handleRelease(const QPointF &point)
{
    Q_Q(QQuickSpinBox);
    QQuickControlPrivate::handleRelease(point);
    QQuickItem *ui = up->indicator();
    QQuickItem *di = down->indicator();

    int oldValue = value;
    if (up->isPressed()) {
        up->setPressed(false);
        if (repeatTimer <= 0 && ui && ui->contains(ui->mapFromItem(q, point)))
            q->increase();
    } else if (down->isPressed()) {
        down->setPressed(false);
        if (repeatTimer <= 0 && di && di->contains(di->mapFromItem(q, point)))
            q->decrease();
    }
    if (value != oldValue)
        emit q->valueModified();

    q->setAccessibleProperty("pressed", false);
    stopPressRepeat();
}

void QQuickSpinBoxPrivate::handleUngrab()
{
    Q_Q(QQuickSpinBox);
    QQuickControlPrivate::handleUngrab();
    up->setPressed(false);
    down->setPressed(false);

    q->setAccessibleProperty("pressed", false);
    stopPressRepeat();
}

void QQuickSpinBoxPrivate::itemImplicitWidthChanged(QQuickItem *item)
{
    QQuickControlPrivate::itemImplicitWidthChanged(item);
    if (item == up->indicator())
        emit up->implicitIndicatorWidthChanged();
    else if (item == down->indicator())
        emit down->implicitIndicatorWidthChanged();
}

void QQuickSpinBoxPrivate::itemImplicitHeightChanged(QQuickItem *item)
{
    QQuickControlPrivate::itemImplicitHeightChanged(item);
    if (item == up->indicator())
        emit up->implicitIndicatorHeightChanged();
    else if (item == down->indicator())
        emit down->implicitIndicatorHeightChanged();
}

QQuickSpinBox::QQuickSpinBox(QQuickItem *parent)
    : QQuickControl(*(new QQuickSpinBoxPrivate), parent)
{
    Q_D(QQuickSpinBox);
    d->up = new QQuickSpinButton(this);
    d->down = new QQuickSpinButton(this);

    setFlag(ItemIsFocusScope);
    setFiltersChildMouseEvents(true);
    setAcceptedMouseButtons(Qt::LeftButton);
#if QT_CONFIG(cursor)
    setCursor(Qt::ArrowCursor);
#endif
}

QQuickSpinBox::~QQuickSpinBox()
{
    Q_D(QQuickSpinBox);
    d->removeImplicitSizeListener(d->up->indicator());
    d->removeImplicitSizeListener(d->down->indicator());
}

/*!
    \qmlproperty int QtQuick.Controls::SpinBox::from

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

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

void QQuickSpinBox::setFrom(int from)
{
    Q_D(QQuickSpinBox);
    if (d->from == from)
        return;

    d->from = from;
    emit fromChanged();
    if (isComponentComplete()) {
        if (!d->setValue(d->value, /* allowWrap = */ false, /* modified = */ false)) {
            d->updateUpEnabled();
            d->updateDownEnabled();
        }
    }
}

/*!
    \qmlproperty int QtQuick.Controls::SpinBox::to

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

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

void QQuickSpinBox::setTo(int to)
{
    Q_D(QQuickSpinBox);
    if (d->to == to)
        return;

    d->to = to;
    emit toChanged();
    if (isComponentComplete()) {
        if (!d->setValue(d->value, /* allowWrap = */false, /* modified = */ false)) {
            d->updateUpEnabled();
            d->updateDownEnabled();
        }
    }
}

/*!
    \qmlproperty int QtQuick.Controls::SpinBox::value

    This property holds the value in the range \c from - \c to. The default value is \c 0.
*/
int QQuickSpinBox::value() const
{
    Q_D(const QQuickSpinBox);
    return d->value;
}

void QQuickSpinBox::setValue(int value)
{
    Q_D(QQuickSpinBox);
    d->setValue(value, /* allowWrap = */ false, /* modified = */ false);
}

/*!
    \qmlproperty int QtQuick.Controls::SpinBox::stepSize

    This property holds the step size. The default value is \c 1.

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

void QQuickSpinBox::setStepSize(int step)
{
    Q_D(QQuickSpinBox);
    if (d->stepSize == step)
        return;

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

/*!
    \qmlproperty bool QtQuick.Controls::SpinBox::editable

    This property holds whether the spinbox is editable. The default value is \c false.

    \sa validator
*/
bool QQuickSpinBox::isEditable() const
{
    Q_D(const QQuickSpinBox);
    return d->editable;
}

void QQuickSpinBox::setEditable(bool editable)
{
    Q_D(QQuickSpinBox);
    if (d->editable == editable)
        return;

#if QT_CONFIG(cursor)
    if (d->contentItem) {
        if (editable)
            d->contentItem->setCursor(Qt::IBeamCursor);
        else
            d->contentItem->unsetCursor();
    }
#endif

    d->editable = editable;
    setAccessibleProperty("editable", editable);
    emit editableChanged();
}

/*!
    \qmlproperty Validator QtQuick.Controls::SpinBox::validator

    This property holds the input text validator for editable spinboxes. By
    default, SpinBox uses \l IntValidator to accept input of integer numbers.

    \code
    SpinBox {
        id: control
        validator: IntValidator {
            locale: control.locale.name
            bottom: Math.min(control.from, control.to)
            top: Math.max(control.from, control.to)
        }
    }
    \endcode

    \sa editable, textFromValue, valueFromText, {Control::locale}{locale}
*/
QValidator *QQuickSpinBox::validator() const
{
    Q_D(const QQuickSpinBox);
    return d->validator;
}

void QQuickSpinBox::setValidator(QValidator *validator)
{
    Q_D(QQuickSpinBox);
    if (d->validator == validator)
        return;

    d->validator = validator;
    emit validatorChanged();
}

/*!
    \qmlproperty function QtQuick.Controls::SpinBox::textFromValue

    This property holds a callback function that is called whenever
    an integer value needs to be converted to display text.

    The default function can be overridden to display custom text for a given
    value. This applies to both editable and non-editable spinboxes;
    for example, when using the up and down buttons or a mouse wheel to
    increment and decrement the value, the new value is converted to display
    text using this function.

    The callback function signature is \c {string function(value, locale)}.
    The function can have one or two arguments, where the first argument
    is the value to be converted, and the optional second argument is the
    locale that should be used for the conversion, if applicable.

    The default implementation does the conversion using
    \l {QtQml::Number::toLocaleString()}{Number.toLocaleString}():

    \code
    textFromValue: function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); }
    \endcode

    \note When applying a custom \c textFromValue implementation for editable
    spinboxes, a matching \l valueFromText implementation must be provided
    to be able to convert the custom text back to an integer value.

    \sa valueFromText, validator, {Control::locale}{locale}
*/
QJSValue QQuickSpinBox::textFromValue() const
{
    Q_D(const QQuickSpinBox);
    if (!d->textFromValue.isCallable()) {
        QQmlEngine *engine = qmlEngine(this);
        if (engine)
            d->textFromValue = engine->evaluate(QStringLiteral("(function(value, locale) { return Number(value).toLocaleString(locale, 'f', 0); })"));
    }
    return d->textFromValue;
}

void QQuickSpinBox::setTextFromValue(const QJSValue &callback)
{
    Q_D(QQuickSpinBox);
    if (!callback.isCallable()) {
        qmlWarning(this) << "textFromValue must be a callable function";
        return;
    }
    d->textFromValue = callback;
    emit textFromValueChanged();
}

/*!
    \qmlproperty function QtQuick.Controls::SpinBox::valueFromText

    This property holds a callback function that is called whenever
    input text needs to be converted to an integer value.

    This function only needs to be overridden when \l textFromValue
    is overridden for an editable spinbox.

    The callback function signature is \c {int function(text, locale)}.
    The function can have one or two arguments, where the first argument
    is the text to be converted, and the optional second argument is the
    locale that should be used for the conversion, if applicable.

    The default implementation does the conversion using \l {QtQml::Locale}{Number.fromLocaleString()}:

    \code
    valueFromText: function(text, locale) { return Number.fromLocaleString(locale, text); }
    \endcode

    \note When applying a custom \l textFromValue implementation for editable
    spinboxes, a matching \c valueFromText implementation must be provided
    to be able to convert the custom text back to an integer value.

    \sa textFromValue, validator, {Control::locale}{locale}
*/
QJSValue QQuickSpinBox::valueFromText() const
{
    Q_D(const QQuickSpinBox);
    if (!d->valueFromText.isCallable()) {
        QQmlEngine *engine = qmlEngine(this);
        if (engine)
            d->valueFromText = engine->evaluate(QStringLiteral("(function(text, locale) { return Number.fromLocaleString(locale, text); })"));
    }
    return d->valueFromText;
}

void QQuickSpinBox::setValueFromText(const QJSValue &callback)
{
    Q_D(QQuickSpinBox);
    if (!callback.isCallable()) {
        qmlWarning(this) << "valueFromText must be a callable function";
        return;
    }
    d->valueFromText = callback;
    emit valueFromTextChanged();
}

/*!
    \qmlpropertygroup QtQuick.Controls::SpinBox::up
    \qmlproperty bool QtQuick.Controls::SpinBox::up.pressed
    \qmlproperty Item QtQuick.Controls::SpinBox::up.indicator
    \qmlproperty bool QtQuick.Controls::SpinBox::up.hovered
    \qmlproperty real QtQuick.Controls::SpinBox::up.implicitIndicatorWidth
    \qmlproperty real QtQuick.Controls::SpinBox::up.implicitIndicatorHeight

    These properties hold the up indicator item and whether it is pressed or
    hovered. The \c up.hovered property was introduced in QtQuick.Controls 2.1,
    and the \c up.implicitIndicatorWidth and \c up.implicitIndicatorHeight
    properties were introduced in QtQuick.Controls 2.5.

    \sa increase()
*/
QQuickSpinButton *QQuickSpinBox::up() const
{
    Q_D(const QQuickSpinBox);
    return d->up;
}

/*!
    \qmlpropertygroup QtQuick.Controls::SpinBox::down
    \qmlproperty bool QtQuick.Controls::SpinBox::down.pressed
    \qmlproperty Item QtQuick.Controls::SpinBox::down.indicator
    \qmlproperty bool QtQuick.Controls::SpinBox::down.hovered
    \qmlproperty real QtQuick.Controls::SpinBox::down.implicitIndicatorWidth
    \qmlproperty real QtQuick.Controls::SpinBox::down.implicitIndicatorHeight

    These properties hold the down indicator item and whether it is pressed or
    hovered. The \c down.hovered property was introduced in QtQuick.Controls 2.1,
    and the \c down.implicitIndicatorWidth and \c down.implicitIndicatorHeight
    properties were introduced in QtQuick.Controls 2.5.

    \sa decrease()
*/
QQuickSpinButton *QQuickSpinBox::down() const
{
    Q_D(const QQuickSpinBox);
    return d->down;
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty flags QtQuick.Controls::SpinBox::inputMethodHints

    This property provides hints to the input method about the expected content
    of the spin box and how it should operate.

    The default value is \c Qt.ImhDigitsOnly.

    \include inputmethodhints.qdocinc
*/
Qt::InputMethodHints QQuickSpinBox::inputMethodHints() const
{
    Q_D(const QQuickSpinBox);
    return d->inputMethodHints;
}

void QQuickSpinBox::setInputMethodHints(Qt::InputMethodHints hints)
{
    Q_D(QQuickSpinBox);
    if (d->inputMethodHints == hints)
        return;

    d->inputMethodHints = hints;
    emit inputMethodHintsChanged();
}

/*!
    \since QtQuick.Controls 2.2 (Qt 5.9)
    \qmlproperty bool QtQuick.Controls::SpinBox::inputMethodComposing
    \readonly

    This property holds whether an editable spin box has partial text input from an input method.

    While it is composing, an input method may rely on mouse or key events from the spin box to
    edit or commit the partial text. This property can be used to determine when to disable event
    handlers that may interfere with the correct operation of an input method.
*/
bool QQuickSpinBox::isInputMethodComposing() const
{
    Q_D(const QQuickSpinBox);
    return d->contentItem && d->contentItem->property("inputMethodComposing").toBool();
}

/*!
    \since QtQuick.Controls 2.3 (Qt 5.10)
    \qmlproperty bool QtQuick.Controls::SpinBox::wrap

    This property holds whether the spinbox wraps. The default value is \c false.

    If wrap is \c true, stepping past \l to changes the value to \l from and vice versa.
*/
bool QQuickSpinBox::wrap() const
{
    Q_D(const QQuickSpinBox);
    return d->wrap;
}

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

    d->wrap = wrap;
    if (d->value == d->from || d->value == d->to) {
        d->updateUpEnabled();
        d->updateDownEnabled();
    }
    emit wrapChanged();
}

/*!
    \since QtQuick.Controls 2.4 (Qt 5.11)
    \qmlproperty string QtQuick.Controls::SpinBox::displayText
    \readonly

    This property holds the textual value of the spinbox.

    The value of the property is based on \l textFromValue and \l {Control::}
    {locale}, and equal to:
    \badcode
    var text = spinBox.textFromValue(spinBox.value, spinBox.locale)
    \endcode

    \sa textFromValue
*/
QString QQuickSpinBox::displayText() const
{
    Q_D(const QQuickSpinBox);
    return d->displayText;
}

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

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

    \sa stepSize
*/
void QQuickSpinBox::increase()
{
    Q_D(QQuickSpinBox);
    d->increase(false);
}

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

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

    \sa stepSize
*/
void QQuickSpinBox::decrease()
{
    Q_D(QQuickSpinBox);
    d->decrease(false);
}

void QQuickSpinBox::focusInEvent(QFocusEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::focusInEvent(event);

    // When an editable SpinBox gets focus, it must pass on the focus to its editor.
    if (d->editable && d->contentItem && !d->contentItem->hasActiveFocus())
        d->contentItem->forceActiveFocus(event->reason());
}

void QQuickSpinBox::hoverEnterEvent(QHoverEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::hoverEnterEvent(event);
    d->updateHover(event->posF());
}

void QQuickSpinBox::hoverMoveEvent(QHoverEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::hoverMoveEvent(event);
    d->updateHover(event->posF());
}

void QQuickSpinBox::hoverLeaveEvent(QHoverEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::hoverLeaveEvent(event);
    d->down->setHovered(false);
    d->up->setHovered(false);
}

void QQuickSpinBox::keyPressEvent(QKeyEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::keyPressEvent(event);

    switch (event->key()) {
    case Qt::Key_Up:
        if (d->upEnabled()) {
            d->increase(true);
            d->up->setPressed(true);
            event->accept();
        }
        break;

    case Qt::Key_Down:
        if (d->downEnabled()) {
            d->decrease(true);
            d->down->setPressed(true);
            event->accept();
        }
        break;

    default:
        break;
    }

    setAccessibleProperty("pressed", d->up->isPressed() || d->down->isPressed());
}

void QQuickSpinBox::keyReleaseEvent(QKeyEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::keyReleaseEvent(event);

    if (d->editable && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return))
        d->updateValue();

    d->up->setPressed(false);
    d->down->setPressed(false);
    setAccessibleProperty("pressed", false);
}

void QQuickSpinBox::timerEvent(QTimerEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::timerEvent(event);
    if (event->timerId() == d->delayTimer) {
        d->startPressRepeat();
    } else if (event->timerId() == d->repeatTimer) {
        if (d->up->isPressed())
            d->increase(true);
        else if (d->down->isPressed())
            d->decrease(true);
    }
}

#if QT_CONFIG(wheelevent)
void QQuickSpinBox::wheelEvent(QWheelEvent *event)
{
    Q_D(QQuickSpinBox);
    QQuickControl::wheelEvent(event);
    if (d->wheelEnabled) {
        const QPointF angle = event->angleDelta();
        const qreal delta = (qFuzzyIsNull(angle.y()) ? angle.x() : angle.y()) / QWheelEvent::DefaultDeltasPerStep;
        d->stepBy(qRound(d->effectiveStepSize() * delta), true);
    }
}
#endif

void QQuickSpinBox::classBegin()
{
    Q_D(QQuickSpinBox);
    QQuickControl::classBegin();

    QQmlContext *context = qmlContext(this);
    if (context) {
        QQmlEngine::setContextForObject(d->up, context);
        QQmlEngine::setContextForObject(d->down, context);
    }
}

void QQuickSpinBox::componentComplete()
{
    Q_D(QQuickSpinBox);
    QQuickSpinButtonPrivate::get(d->up)->executeIndicator(true);
    QQuickSpinButtonPrivate::get(d->down)->executeIndicator(true);

    QQuickControl::componentComplete();
    if (!d->setValue(d->value, /* allowWrap = */ false, /* modified = */ false)) {
        d->updateDisplayText();
        d->updateUpEnabled();
        d->updateDownEnabled();
    }
}

void QQuickSpinBox::itemChange(ItemChange change, const ItemChangeData &value)
{
    Q_D(QQuickSpinBox);
    QQuickControl::itemChange(change, value);
    if (d->editable && change == ItemActiveFocusHasChanged && !value.boolValue)
        d->updateValue();
}

void QQuickSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
{
    Q_D(QQuickSpinBox);
    if (QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem))
        disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickSpinBox::inputMethodComposingChanged);

    if (newItem) {
        newItem->setActiveFocusOnTab(true);
        if (d->activeFocus)
            newItem->forceActiveFocus(d->focusReason);
#if QT_CONFIG(cursor)
        if (d->editable)
            newItem->setCursor(Qt::IBeamCursor);
#endif

        if (QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem))
            connect(newInput, &QQuickTextInput::inputMethodComposingChanged, this, &QQuickSpinBox::inputMethodComposingChanged);
    }
}

void QQuickSpinBox::localeChange(const QLocale &newLocale, const QLocale &oldLocale)
{
    Q_D(QQuickSpinBox);
    QQuickControl::localeChange(newLocale, oldLocale);
    d->updateDisplayText();
}

QFont QQuickSpinBox::defaultFont() const
{
    return QQuickTheme::font(QQuickTheme::SpinBox);
}

QPalette QQuickSpinBox::defaultPalette() const
{
    return QQuickTheme::palette(QQuickTheme::SpinBox);
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickSpinBox::accessibleRole() const
{
    return QAccessible::SpinBox;
}

void QQuickSpinBox::accessibilityActiveChanged(bool active)
{
    Q_D(QQuickSpinBox);
    QQuickControl::accessibilityActiveChanged(active);

    if (active)
        setAccessibleProperty("editable", d->editable);
}
#endif

static inline QString indicatorName() { return QStringLiteral("indicator"); }

void QQuickSpinButtonPrivate::cancelIndicator()
{
    Q_Q(QQuickSpinButton);
    quickCancelDeferred(q, indicatorName());
}

void QQuickSpinButtonPrivate::executeIndicator(bool complete)
{
    Q_Q(QQuickSpinButton);
    if (indicator.wasExecuted())
        return;

    if (!indicator || complete)
        quickBeginDeferred(q, indicatorName(), indicator);
    if (complete)
        quickCompleteDeferred(q, indicatorName(), indicator);
}

QQuickSpinButton::QQuickSpinButton(QQuickSpinBox *parent)
    : QObject(*(new QQuickSpinButtonPrivate), parent)
{
}

bool QQuickSpinButton::isPressed() const
{
    Q_D(const QQuickSpinButton);
    return d->pressed;
}

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

    d->pressed = pressed;
    emit pressedChanged();
}

QQuickItem *QQuickSpinButton::indicator() const
{
    QQuickSpinButtonPrivate *d = const_cast<QQuickSpinButtonPrivate *>(d_func());
    if (!d->indicator)
        d->executeIndicator();
    return d->indicator;
}

void QQuickSpinButton::setIndicator(QQuickItem *indicator)
{
    Q_D(QQuickSpinButton);
    if (d->indicator == indicator)
        return;

    if (!d->indicator.isExecuting())
        d->cancelIndicator();

    const qreal oldImplicitIndicatorWidth = implicitIndicatorWidth();
    const qreal oldImplicitIndicatorHeight = implicitIndicatorHeight();

    QQuickSpinBox *spinBox = static_cast<QQuickSpinBox *>(parent());
    QQuickSpinBoxPrivate::get(spinBox)->removeImplicitSizeListener(d->indicator);
    QQuickControlPrivate::hideOldItem(d->indicator);
    d->indicator = indicator;

    if (indicator) {
        if (!indicator->parentItem())
            indicator->setParentItem(spinBox);
        QQuickSpinBoxPrivate::get(spinBox)->addImplicitSizeListener(indicator);
    }

    if (!qFuzzyCompare(oldImplicitIndicatorWidth, implicitIndicatorWidth()))
        emit implicitIndicatorWidthChanged();
    if (!qFuzzyCompare(oldImplicitIndicatorHeight, implicitIndicatorHeight()))
        emit implicitIndicatorHeightChanged();
    if (!d->indicator.isExecuting())
        emit indicatorChanged();
}

bool QQuickSpinButton::isHovered() const
{
    Q_D(const QQuickSpinButton);
    return d->hovered;
}

void QQuickSpinButton::setHovered(bool hovered)
{
    Q_D(QQuickSpinButton);
    if (d->hovered == hovered)
        return;

    d->hovered = hovered;
    emit hoveredChanged();
}

qreal QQuickSpinButton::implicitIndicatorWidth() const
{
    Q_D(const QQuickSpinButton);
    if (!d->indicator)
        return 0;
    return d->indicator->implicitWidth();
}

qreal QQuickSpinButton::implicitIndicatorHeight() const
{
    Q_D(const QQuickSpinButton);
    if (!d->indicator)
        return 0;
    return d->indicator->implicitHeight();
}

QT_END_NAMESPACE
