/****************************************************************************
**
** 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 "qquicktooltip_p.h"
#include "qquickpopup_p_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickcontrol_p_p.h"

#include <QtCore/qbasictimer.h>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/qquickwindow.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype ToolTip
    \inherits Popup
//!     \instantiates QQuickToolTip
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-popups
    \brief Provides tool tips for any control.

    A tool tip is a short piece of text that informs the user of a control's
    function. It is typically placed above or below the parent control. The
    tip text can be any \l{Rich Text Processing}{rich text} formatted string.

    \image qtquickcontrols2-tooltip.png

    \section2 Attached Tool Tips

    The most straight-forward way to setup tool tips for controls is to
    specify \l text and \l {visible}{visibility} via attached properties.
    The following example illustrates this approach:

    \snippet qtquickcontrols2-tooltip.qml 1

    Under normal circumstances, there is only one tool tip visible at a time.
    In order to save resources, all items that use the ToolTip attached property
    share the same visual tool tip label instance. Even though the visuals are
    shared, \c text, \c timeout and \c delay are stored individually for each item
    that uses the respective attached property. However, multiple items cannot
    make the shared tool tip visible at the same time. The shared tool tip is only
    shown for the last item that made it visible. The position of the shared tool
    tip is determined by the framework.

    \section2 Delay and Timeout

    Tool tips are typically transient in a sense that they are shown as a
    result of a certain external event or user interaction, and they usually
    hide after a certain timeout. It is possible to control the delay when
    a tool tip is shown, and the timeout when it is hidden. This makes it
    possible to implement varying strategies for showing and hiding tool tips.

    For example, on touch screens, it is a common pattern to show a tool tip
    as a result of pressing and holding down a button. The following example
    demonstrates how to delay showing a tool tip until the press-and-hold
    interval is reached. In this example, the tool tip hides as soon as the
    button is released.

    \snippet qtquickcontrols2-tooltip-pressandhold.qml 1

    With pointer devices, however, it might be desired to show a tool tip as
    a result of hovering a button for a while. The following example presents
    how to show a tool tip after hovering a button for a second, and hide it
    after a timeout of five seconds.

    \snippet qtquickcontrols2-tooltip-hover.qml 1

    \section2 Custom Tool Tips

    Should one need more fine-grained control over the tool tip position, or
    multiple simultaneous tool tip instances are needed, it is also possible
    to create local tool tip instances. This way, it is possible to
    \l {Customizing ToolTip}{customize} the tool tip, and the whole \l Popup
    API is available. The following example presents a tool tip that presents
    the value of a slider when the handle is dragged.

    \image qtquickcontrols2-tooltip-slider.png

    \snippet qtquickcontrols2-tooltip-slider.qml 1

    \sa {Customizing ToolTip}, {Popup Controls}
*/

class QQuickToolTipPrivate : public QQuickPopupPrivate
{
    Q_DECLARE_PUBLIC(QQuickToolTip)

public:
    void startDelay();
    void stopDelay();

    void startTimeout();
    void stopTimeout();

    int delay = 0;
    int timeout = -1;
    QString text;
    QBasicTimer delayTimer;
    QBasicTimer timeoutTimer;
};

void QQuickToolTipPrivate::startDelay()
{
    Q_Q(QQuickToolTip);
    if (delay > 0)
        delayTimer.start(delay, q);
}

void QQuickToolTipPrivate::stopDelay()
{
    delayTimer.stop();
}

void QQuickToolTipPrivate::startTimeout()
{
    Q_Q(QQuickToolTip);
    if (timeout > 0)
        timeoutTimer.start(timeout, q);
}

void QQuickToolTipPrivate::stopTimeout()
{
    timeoutTimer.stop();
}

QQuickToolTip::QQuickToolTip(QQuickItem *parent)
    : QQuickPopup(*(new QQuickToolTipPrivate), parent)
{
    Q_D(QQuickToolTip);
    d->allowVerticalFlip = true;
    d->allowHorizontalFlip = true;
    d->popupItem->setHoverEnabled(false); // QTBUG-63644
}

/*!
    \qmlproperty string QtQuick.Controls::ToolTip::text

    This property holds the text shown on the tool tip.
*/
QString QQuickToolTip::text() const
{
    Q_D(const QQuickToolTip);
    return d->text;
}

void QQuickToolTip::setText(const QString &text)
{
    Q_D(QQuickToolTip);
    if (d->text == text)
        return;

    d->text = text;
    maybeSetAccessibleName(text);
    emit textChanged();
}

/*!
    \qmlproperty int QtQuick.Controls::ToolTip::delay

    This property holds the delay (milliseconds) after which the tool tip is
    shown. A tooltip with a negative delay is shown immediately. The default
    value is \c 0.

    \sa {Delay and Timeout}
*/
int QQuickToolTip::delay() const
{
    Q_D(const QQuickToolTip);
    return d->delay;
}

void QQuickToolTip::setDelay(int delay)
{
    Q_D(QQuickToolTip);
    if (d->delay == delay)
        return;

    d->delay = delay;
    emit delayChanged();
}

/*!
    \qmlproperty int QtQuick.Controls::ToolTip::timeout

    This property holds the timeout (milliseconds) after which the tool tip is
    hidden. A tooltip with a negative timeout does not hide automatically. The
    default value is \c -1.

    \sa {Delay and Timeout}
*/
int QQuickToolTip::timeout() const
{
    Q_D(const QQuickToolTip);
    return d->timeout;
}

void QQuickToolTip::setTimeout(int timeout)
{
    Q_D(QQuickToolTip);
    if (d->timeout == timeout)
        return;

    d->timeout = timeout;

    if (timeout <= 0)
        d->stopTimeout();
    else if (isVisible())
        d->startTimeout();

    emit timeoutChanged();
}

void QQuickToolTip::setVisible(bool visible)
{
    Q_D(QQuickToolTip);
    if (visible) {
        if (!d->visible) {
            // We are being made visible, and we weren't before.
            if (d->delay > 0) {
                d->startDelay();
                return;
            }
        } else {
            // We are being made visible, even though we already were.
            // We've probably been re-opened before our exit transition could finish.
            // In that case, we need to manually start the timeout, as that is usually
            // done in itemChange(), which won't be called in this situation.
            d->startTimeout();
        }
    } else {
        d->stopDelay();
    }
    QQuickPopup::setVisible(visible);
}

QQuickToolTipAttached *QQuickToolTip::qmlAttachedProperties(QObject *object)
{
    QQuickItem *item = qobject_cast<QQuickItem *>(object);
    if (!item)
        qmlWarning(object) << "ToolTip must be attached to an Item";

    return new QQuickToolTipAttached(object);
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlmethod void QtQuick.Controls::ToolTip::show(string text, int timeout)

    This method shows the \a text as a tooltip, which times out in
    \a timeout (milliseconds).
*/
void QQuickToolTip::show(const QString &text, int ms)
{
    if (ms >= 0)
        setTimeout(ms);
    setText(text);
    open();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlmethod void QtQuick.Controls::ToolTip::hide()

    This method hides the tooltip.
*/
void QQuickToolTip::hide()
{
    close();
}

QFont QQuickToolTip::defaultFont() const
{
    return QQuickTheme::font(QQuickTheme::ToolTip);
}

QPalette QQuickToolTip::defaultPalette() const
{
    return QQuickTheme::palette(QQuickTheme::ToolTip);
}

void QQuickToolTip::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
{
    Q_D(QQuickToolTip);
    QQuickPopup::itemChange(change, data);
    if (change == QQuickItem::ItemVisibleHasChanged) {
        if (data.boolValue)
            d->startTimeout();
        else
            d->stopTimeout();

        QQuickToolTipAttached *attached = qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(d->parentItem, false));
        if (attached)
            emit attached->visibleChanged();
    }
}

void QQuickToolTip::timerEvent(QTimerEvent *event)
{
    Q_D(QQuickToolTip);
    if (event->timerId() == d->timeoutTimer.timerId()) {
        d->stopTimeout();
        QQuickPopup::setVisible(false);
        return;
    }
    if (event->timerId() == d->delayTimer.timerId()) {
        d->stopDelay();
        QQuickPopup::setVisible(true);
        return;
    }
    QQuickPopup::timerEvent(event);
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickToolTip::accessibleRole() const
{
    return QAccessible::ToolTip;
}

void QQuickToolTip::accessibilityActiveChanged(bool active)
{
    Q_D(QQuickToolTip);
    QQuickPopup::accessibilityActiveChanged(active);

    if (active)
        maybeSetAccessibleName(d->text);
}
#endif

class QQuickToolTipAttachedPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QQuickToolTipAttached)

public:
    QQuickToolTip *instance(bool create) const;

    int delay = 0;
    int timeout = -1;
    QString text;
};

QQuickToolTip *QQuickToolTipAttachedPrivate::instance(bool create) const
{
    QQmlEngine *engine = qmlEngine(parent);
    if (!engine)
        return nullptr;

    static const char *name = "_q_QQuickToolTip";

    QQuickToolTip *tip = engine->property(name).value<QQuickToolTip *>();
    if (!tip && create) {
        // TODO: a cleaner way to create the instance? QQml(Meta)Type?
        QQmlComponent component(engine);
        component.setData("import QtQuick.Controls 2.4; ToolTip { }", QUrl());

        QObject *object = component.create();
        if (object)
            object->setParent(engine);

        tip = qobject_cast<QQuickToolTip *>(object);
        if (!tip)
            delete object;
        else
            engine->setProperty(name, QVariant::fromValue(object));
    }
    return tip;
}

QQuickToolTipAttached::QQuickToolTipAttached(QObject *parent)
    : QObject(*(new QQuickToolTipAttachedPrivate), parent)
{
}

/*!
    \qmlattachedproperty string QtQuick.Controls::ToolTip::text

    This attached property holds the text of the shared tool tip.
    The property can be attached to any item.

    \sa {Attached Tool Tips}
*/
QString QQuickToolTipAttached::text() const
{
    Q_D(const QQuickToolTipAttached);
    return d->text;
}

void QQuickToolTipAttached::setText(const QString &text)
{
    Q_D(QQuickToolTipAttached);
    if (d->text == text)
        return;

    d->text = text;
    emit textChanged();

    if (isVisible())
        d->instance(true)->setText(text);
}

/*!
    \qmlattachedproperty int QtQuick.Controls::ToolTip::delay

    This attached property holds the delay (milliseconds) of the shared tool tip.
    The property can be attached to any item.

    \sa {Attached Tool Tips}, {Delay and Timeout}
*/
int QQuickToolTipAttached::delay() const
{
    Q_D(const QQuickToolTipAttached);
    return d->delay;
}

void QQuickToolTipAttached::setDelay(int delay)
{
    Q_D(QQuickToolTipAttached);
    if (d->delay == delay)
        return;

    d->delay = delay;
    emit delayChanged();

    if (isVisible())
        d->instance(true)->setDelay(delay);
}

/*!
    \qmlattachedproperty int QtQuick.Controls::ToolTip::timeout

    This attached property holds the timeout (milliseconds) of the shared tool tip.
    The property can be attached to any item.

    \sa {Attached Tool Tips}, {Delay and Timeout}
*/
int QQuickToolTipAttached::timeout() const
{
    Q_D(const QQuickToolTipAttached);
    return d->timeout;
}

void QQuickToolTipAttached::setTimeout(int timeout)
{
    Q_D(QQuickToolTipAttached);
    if (d->timeout == timeout)
        return;

    d->timeout = timeout;
    emit timeoutChanged();

    if (isVisible())
        d->instance(true)->setTimeout(timeout);
}

/*!
    \qmlattachedproperty bool QtQuick.Controls::ToolTip::visible

    This attached property holds whether the shared tool tip is visible.
    The property can be attached to any item.

    \sa {Attached Tool Tips}
*/
bool QQuickToolTipAttached::isVisible() const
{
    Q_D(const QQuickToolTipAttached);
    QQuickToolTip *tip = d->instance(false);
    if (!tip)
        return false;

    return tip->isVisible() && tip->parentItem() == parent();
}

void QQuickToolTipAttached::setVisible(bool visible)
{
    Q_D(QQuickToolTipAttached);
    if (visible)
        show(d->text);
    else
        hide();
}

/*!
    \qmlattachedproperty ToolTip QtQuick.Controls::ToolTip::toolTip

    This attached property holds the shared tool tip instance. The property
    can be attached to any item.

    \sa {Attached Tool Tips}
*/
QQuickToolTip *QQuickToolTipAttached::toolTip() const
{
    Q_D(const QQuickToolTipAttached);
    return d->instance(true);
}

/*!
    \qmlattachedmethod void QtQuick.Controls::ToolTip::show(string text, int timeout = -1)

    This attached method shows the shared tooltip with \a text and \a timeout (milliseconds).
    The method can be attached to any item.

    \sa {Attached Tool Tips}
*/
void QQuickToolTipAttached::show(const QString &text, int ms)
{
    Q_D(QQuickToolTipAttached);
    QQuickToolTip *tip = d->instance(true);
    if (!tip)
        return;

    tip->resetWidth();
    tip->resetHeight();
    tip->setParentItem(qobject_cast<QQuickItem *>(parent()));
    tip->setDelay(d->delay);
    tip->setTimeout(ms >= 0 ? ms : d->timeout);
    tip->show(text);
}

/*!
    \qmlattachedmethod void QtQuick.Controls::ToolTip::hide()

    This attached method hides the shared tooltip. The method can be attached to any item.

    \sa {Attached Tool Tips}
*/
void QQuickToolTipAttached::hide()
{
    Q_D(QQuickToolTipAttached);
    QQuickToolTip *tip = d->instance(false);
    if (!tip)
        return;
    // check the parent item to prevent unexpectedly closing tooltip by new created invisible tooltip
    if (parent() == tip->parentItem())
        tip->close();
}

QT_END_NAMESPACE
