/****************************************************************************
**
** 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 "qquickbuttongroup_p.h"

#include <QtCore/private/qobject_p.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qvariant.h>
#include <QtQml/qqmlinfo.h>

#include "qquickabstractbutton_p_p.h"

QT_BEGIN_NAMESPACE

/*!
    \qmltype ButtonGroup
    \inherits QtObject
//!     \instantiates QQuickButtonGroup
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup utilities
    \brief Mutually-exclusive group of checkable buttons.

    ButtonGroup is a non-visual, mutually exclusive group of buttons.
    It is used with controls such as RadioButton, where only one of the options
    can be selected at a time.

    The most straight-forward way to use ButtonGroup is to assign
    a list of buttons. For example, the list of children of a
    \l{Item Positioners}{positioner} or a \l{Qt Quick Layouts}{layout}
    that manages a group of mutually exclusive buttons.

    \code
    ButtonGroup {
        buttons: column.children
    }

    Column {
        id: column

        RadioButton {
            checked: true
            text: qsTr("DAB")
        }

        RadioButton {
            text: qsTr("FM")
        }

        RadioButton {
            text: qsTr("AM")
        }
    }
    \endcode

    Mutually exclusive buttons do not always share the same parent item,
    or the parent layout may sometimes contain items that should not be
    included in the button group. Such cases are best handled using
    the \l group attached property.

    \code
    ButtonGroup { id: radioGroup }

    Column {
        Label {
            text: qsTr("Radio:")
        }

        RadioButton {
            checked: true
            text: qsTr("DAB")
            ButtonGroup.group: radioGroup
        }

        RadioButton {
            text: qsTr("FM")
            ButtonGroup.group: radioGroup
        }

        RadioButton {
            text: qsTr("AM")
            ButtonGroup.group: radioGroup
        }
    }
    \endcode

    More advanced use cases can be handled using the \c addButton() and
    \c removeButton() methods.

    \sa RadioButton, {Button Controls}
*/

/*!
    \qmlsignal QtQuick.Controls::ButtonGroup::clicked(AbstractButton button)
    \since QtQuick.Controls 2.1 (Qt 5.8)

    This signal is emitted when a \a button in the group has been clicked.

    This signal is convenient for implementing a common signal handler for
    all buttons in the same group.

    \code
    ButtonGroup {
        buttons: column.children
        onClicked: console.log("clicked:", button.text)
    }

    Column {
        id: column
        Button { text: "First" }
        Button { text: "Second" }
        Button { text: "Third" }
    }
    \endcode

    \sa AbstractButton::clicked()
*/

class QQuickButtonGroupPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QQuickButtonGroup)

public:
    void clear();
    void buttonClicked();
    void _q_updateCurrent();
    void updateCheckState();
    void setCheckState(Qt::CheckState state);

    static void buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj);
    static int buttons_count(QQmlListProperty<QQuickAbstractButton> *prop);
    static QQuickAbstractButton *buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index);
    static void buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop);

    bool complete = true;
    bool exclusive = true;
    bool settingCheckState = false;
    Qt::CheckState checkState = Qt::Unchecked;
    QPointer<QQuickAbstractButton> checkedButton;
    QVector<QQuickAbstractButton*> buttons;
};

void QQuickButtonGroupPrivate::clear()
{
    for (QQuickAbstractButton *button : qAsConst(buttons)) {
        QQuickAbstractButtonPrivate::get(button)->group = nullptr;
        QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, this, &QQuickButtonGroupPrivate::buttonClicked);
        QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, this, &QQuickButtonGroupPrivate::_q_updateCurrent);
    }
    buttons.clear();
}

void QQuickButtonGroupPrivate::buttonClicked()
{
    Q_Q(QQuickButtonGroup);
    QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender());
    if (button)
        emit q->clicked(button);
}

void QQuickButtonGroupPrivate::_q_updateCurrent()
{
    Q_Q(QQuickButtonGroup);
    if (exclusive) {
        QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender());
        if (button && button->isChecked())
            q->setCheckedButton(button);
        else if (!buttons.contains(checkedButton))
            q->setCheckedButton(nullptr);
    }
    updateCheckState();
}

void QQuickButtonGroupPrivate::updateCheckState()
{
    if (!complete || settingCheckState)
        return;

    bool anyChecked = false;
    bool allChecked = !buttons.isEmpty();
    for (QQuickAbstractButton *button : qAsConst(buttons)) {
        const bool isChecked = button->isChecked();
        anyChecked |= isChecked;
        allChecked &= isChecked;
    }
    setCheckState(Qt::CheckState(anyChecked + allChecked));
}

void QQuickButtonGroupPrivate::setCheckState(Qt::CheckState state)
{
    Q_Q(QQuickButtonGroup);
    if (checkState == state)
        return;

    checkState = state;
    emit q->checkStateChanged();
}

void QQuickButtonGroupPrivate::buttons_append(QQmlListProperty<QQuickAbstractButton> *prop, QQuickAbstractButton *obj)
{
    QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object);
    q->addButton(obj);
}

int QQuickButtonGroupPrivate::buttons_count(QQmlListProperty<QQuickAbstractButton> *prop)
{
    QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
    return p->buttons.count();
}

QQuickAbstractButton *QQuickButtonGroupPrivate::buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index)
{
    QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
    return p->buttons.value(index);
}

void QQuickButtonGroupPrivate::buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop)
{
    QQuickButtonGroupPrivate *p = static_cast<QQuickButtonGroupPrivate *>(prop->data);
    if (!p->buttons.isEmpty()) {
        p->clear();
        QQuickButtonGroup *q = static_cast<QQuickButtonGroup *>(prop->object);
        // QTBUG-52358: don't clear the checked button immediately
        QMetaObject::invokeMethod(q, "_q_updateCurrent", Qt::QueuedConnection);
        emit q->buttonsChanged();
    }
}

QQuickButtonGroup::QQuickButtonGroup(QObject *parent)
    : QObject(*(new QQuickButtonGroupPrivate), parent)
{
}

QQuickButtonGroup::~QQuickButtonGroup()
{
    Q_D(QQuickButtonGroup);
    d->clear();
}

QQuickButtonGroupAttached *QQuickButtonGroup::qmlAttachedProperties(QObject *object)
{
    return new QQuickButtonGroupAttached(object);
}

/*!
    \qmlproperty AbstractButton QtQuick.Controls::ButtonGroup::checkedButton

    This property holds the currently selected button in an exclusive group,
    or \c null if there is none or the group is non-exclusive.

    By default, it is the first checked button added to an exclusive button group.

    \sa exclusive
*/
QQuickAbstractButton *QQuickButtonGroup::checkedButton() const
{
    Q_D(const QQuickButtonGroup);
    return d->checkedButton;
}

void QQuickButtonGroup::setCheckedButton(QQuickAbstractButton *checkedButton)
{
    Q_D(QQuickButtonGroup);
    if (d->checkedButton == checkedButton)
        return;

    if (d->checkedButton)
        d->checkedButton->setChecked(false);
    d->checkedButton = checkedButton;
    if (checkedButton)
        checkedButton->setChecked(true);
    emit checkedButtonChanged();
}

/*!
    \qmlproperty list<AbstractButton> QtQuick.Controls::ButtonGroup::buttons
    \default

    This property holds the list of buttons.

    \code
    ButtonGroup {
        buttons: column.children
    }

    Column {
        id: column

        RadioButton {
            checked: true
            text: qsTr("Option A")
        }

        RadioButton {
            text: qsTr("Option B")
        }
    }
    \endcode

    \sa group
*/
QQmlListProperty<QQuickAbstractButton> QQuickButtonGroup::buttons()
{
    Q_D(QQuickButtonGroup);
    return QQmlListProperty<QQuickAbstractButton>(this, d,
        QQuickButtonGroupPrivate::buttons_append,
        QQuickButtonGroupPrivate::buttons_count,
        QQuickButtonGroupPrivate::buttons_at,
        QQuickButtonGroupPrivate::buttons_clear);
}

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

    This property holds whether the button group is exclusive. The default value is \c true.

    If this property is \c true, then only one button in the group can be checked at any given time.
    The user can click on any button to check it, and that button will replace the existing one as
    the checked button in the group.

    In an exclusive group, the user cannot uncheck the currently checked button by clicking on it;
    instead, another button in the group must be clicked to set the new checked button for that group.

    In a non-exclusive group, checking and unchecking buttons does not affect the other buttons in
    the group. Furthermore, the value of the \l checkedButton property is \c null.
*/
bool QQuickButtonGroup::isExclusive() const
{
    Q_D(const QQuickButtonGroup);
    return d->exclusive;
}

void QQuickButtonGroup::setExclusive(bool exclusive)
{
    Q_D(QQuickButtonGroup);
    if (d->exclusive == exclusive)
        return;

    d->exclusive = exclusive;
    emit exclusiveChanged();
}

/*!
    \since QtQuick.Controls 2.4 (Qt 5.11)
    \qmlproperty enumeration QtQuick.Controls::ButtonGroup::checkState

    This property holds the combined check state of the button group.

    Available states:
    \value Qt.Unchecked None of the buttons are checked.
    \value Qt.PartiallyChecked Some of the buttons are checked.
    \value Qt.Checked All of the buttons are checked.

    Setting the check state of a non-exclusive button group to \c Qt.Unchecked
    or \c Qt.Checked unchecks or checks all buttons in the group, respectively.
    \c Qt.PartiallyChecked is ignored.

    Setting the check state of an exclusive button group to \c Qt.Unchecked
    unchecks the \l checkedButton. \c Qt.Checked and \c Qt.PartiallyChecked
    are ignored.
*/
Qt::CheckState QQuickButtonGroup::checkState() const
{
    Q_D(const QQuickButtonGroup);
    return d->checkState;
}

void QQuickButtonGroup::setCheckState(Qt::CheckState state)
{
    Q_D(QQuickButtonGroup);
    if (d->checkState == state || state == Qt::PartiallyChecked)
        return;

    d->settingCheckState = true;
    if (d->exclusive) {
        if (d->checkedButton && state == Qt::Unchecked)
            setCheckedButton(nullptr);
    } else {
        for (QQuickAbstractButton *button : qAsConst(d->buttons))
            button->setChecked(state == Qt::Checked);
    }
    d->settingCheckState = false;
    d->setCheckState(state);
}

/*!
    \qmlmethod void QtQuick.Controls::ButtonGroup::addButton(AbstractButton button)

    Adds a \a button to the button group.

    \note Manually adding objects to a button group is typically unnecessary.
          The \l buttons property and the \l group attached property provide a
          convenient and declarative syntax.

    \sa buttons, group
*/
void QQuickButtonGroup::addButton(QQuickAbstractButton *button)
{
    Q_D(QQuickButtonGroup);
    if (!button || d->buttons.contains(button))
        return;

    QQuickAbstractButtonPrivate::get(button)->group = this;
    QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickButtonGroupPrivate::buttonClicked);
    QObjectPrivate::connect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::_q_updateCurrent);

    if (d->exclusive && button->isChecked())
        setCheckedButton(button);

    d->buttons.append(button);
    d->updateCheckState();
    emit buttonsChanged();
}

/*!
    \qmlmethod void QtQuick.Controls::ButtonGroup::removeButton(AbstractButton button)

    Removes a \a button from the button group.

    \note Manually removing objects from a button group is typically unnecessary.
          The \l buttons property and the \l group attached property provide a
          convenient and declarative syntax.

    \sa buttons, group
*/
void QQuickButtonGroup::removeButton(QQuickAbstractButton *button)
{
    Q_D(QQuickButtonGroup);
    if (!button || !d->buttons.contains(button))
        return;

    QQuickAbstractButtonPrivate::get(button)->group = nullptr;
    QObjectPrivate::disconnect(button, &QQuickAbstractButton::clicked, d, &QQuickButtonGroupPrivate::buttonClicked);
    QObjectPrivate::disconnect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::_q_updateCurrent);

    if (d->checkedButton == button)
        setCheckedButton(nullptr);

    d->buttons.removeOne(button);
    d->updateCheckState();
    emit buttonsChanged();
}

void QQuickButtonGroup::classBegin()
{
    Q_D(QQuickButtonGroup);
    d->complete = false;
}

void QQuickButtonGroup::componentComplete()
{
    Q_D(QQuickButtonGroup);
    d->complete = true;
    if (!d->buttons.isEmpty())
        d->updateCheckState();
}

class QQuickButtonGroupAttachedPrivate : public QObjectPrivate
{
public:
    QQuickButtonGroup *group = nullptr;
};

QQuickButtonGroupAttached::QQuickButtonGroupAttached(QObject *parent)
    : QObject(*(new QQuickButtonGroupAttachedPrivate), parent)
{
}

/*!
    \qmlattachedproperty ButtonGroup QtQuick.Controls::ButtonGroup::group

    This property attaches a button to a button group.

    \code
    ButtonGroup { id: group }

    RadioButton {
        checked: true
        text: qsTr("Option A")
        ButtonGroup.group: group
    }

    RadioButton {
        text: qsTr("Option B")
        ButtonGroup.group: group
    }
    \endcode

    \sa buttons
*/
QQuickButtonGroup *QQuickButtonGroupAttached::group() const
{
    Q_D(const QQuickButtonGroupAttached);
    return d->group;
}

void QQuickButtonGroupAttached::setGroup(QQuickButtonGroup *group)
{
    Q_D(QQuickButtonGroupAttached);
    if (d->group == group)
        return;

    if (d->group)
        d->group->removeButton(qobject_cast<QQuickAbstractButton*>(parent()));
    d->group = group;
    if (group)
        group->addButton(qobject_cast<QQuickAbstractButton*>(parent()));
    emit groupChanged();
}

QT_END_NAMESPACE

#include "moc_qquickbuttongroup_p.cpp"
