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

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

#include "qquickaction_p.h"
#include "qquickaction_p_p.h"

QT_BEGIN_NAMESPACE

/*!
    \qmltype ActionGroup
    \inherits QtObject
//!     \instantiates QQuickActionGroup
    \inqmlmodule QtQuick.Controls
    \since 5.10
    \ingroup utilities
    \brief Groups actions together.

    ActionGroup is a non-visual group of actions. A mutually \l exclusive
    action group is used with actions where only one of the options can be
    selected at a time.

    The most straight-forward way to use ActionGroup is to declare actions
    as children of the group.

    \code
    ActionGroup {
        id: alignmentGroup

        Action {
            checked: true
            checkable: true
            text: qsTr("Left")
        }

        Action {
            checkable: true
            text: qsTr("Center")
        }

        Action {
            checkable: true
            text: qsTr("Right")
        }
    }
    \endcode

    Alternatively, the \l group attached property allows declaring the actions
    elsewhere and assigning them to a specific group.

    \code
    ActionGroup { id: alignmentGroup }

    Action {
        checked: true
        checkable: true
        text: qsTr("Left")
        ActionGroup.group: alignmentGroup
    }

    Action {
        checkable: true
        text: qsTr("Center")
        ActionGroup.group: alignmentGroup
    }

    Action {
        checkable: true
        text: qsTr("Right")
        ActionGroup.group: alignmentGroup
    }
    \endcode

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

    \sa Action, ButtonGroup
*/

/*!
    \qmlsignal QtQuick.Controls::ActionGroup::triggered(Action action)

    This signal is emitted when an \a action in the group has been triggered.

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

    \code
    ActionGroup {
        onTriggered: console.log("triggered:", action.text)

        Action { text: "First" }
        Action { text: "Second" }
        Action { text: "Third" }
    }
    \endcode

    \sa Action::triggered()
*/

class QQuickActionGroupPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QQuickActionGroup)

public:
    void clear();
    void actionTriggered();
    void _q_updateCurrent();

    static bool changeEnabled(QQuickAction *action, bool enabled);

    static void actions_append(QQmlListProperty<QQuickAction> *prop, QQuickAction *obj);
    static int actions_count(QQmlListProperty<QQuickAction> *prop);
    static QQuickAction *actions_at(QQmlListProperty<QQuickAction> *prop, int index);
    static void actions_clear(QQmlListProperty<QQuickAction> *prop);

    bool enabled = true;
    bool exclusive = true;
    QPointer<QQuickAction> checkedAction;
    QVector<QQuickAction*> actions;
};

void QQuickActionGroupPrivate::clear()
{
    for (QQuickAction *action : qAsConst(actions)) {
        QQuickActionPrivate::get(action)->group = nullptr;
        QObjectPrivate::disconnect(action, &QQuickAction::triggered, this, &QQuickActionGroupPrivate::actionTriggered);
        QObjectPrivate::disconnect(action, &QQuickAction::checkedChanged, this, &QQuickActionGroupPrivate::_q_updateCurrent);
    }
    actions.clear();
}

void QQuickActionGroupPrivate::actionTriggered()
{
    Q_Q(QQuickActionGroup);
    QQuickAction *action = qobject_cast<QQuickAction*>(q->sender());
    if (action)
        emit q->triggered(action);
}

void QQuickActionGroupPrivate::_q_updateCurrent()
{
    Q_Q(QQuickActionGroup);
    if (!exclusive)
        return;
    QQuickAction *action = qobject_cast<QQuickAction*>(q->sender());
    if (action && action->isChecked())
        q->setCheckedAction(action);
    else if (!actions.contains(checkedAction))
        q->setCheckedAction(nullptr);
}

bool QQuickActionGroupPrivate::changeEnabled(QQuickAction *action, bool enabled)
{
    return action->isEnabled() != enabled && (!enabled || !QQuickActionPrivate::get(action)->explicitEnabled);
}

void QQuickActionGroupPrivate::actions_append(QQmlListProperty<QQuickAction> *prop, QQuickAction *obj)
{
    QQuickActionGroup *q = static_cast<QQuickActionGroup *>(prop->object);
    q->addAction(obj);
}

int QQuickActionGroupPrivate::actions_count(QQmlListProperty<QQuickAction> *prop)
{
    QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data);
    return p->actions.count();
}

QQuickAction *QQuickActionGroupPrivate::actions_at(QQmlListProperty<QQuickAction> *prop, int index)
{
    QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data);
    return p->actions.value(index);
}

void QQuickActionGroupPrivate::actions_clear(QQmlListProperty<QQuickAction> *prop)
{
    QQuickActionGroupPrivate *p = static_cast<QQuickActionGroupPrivate *>(prop->data);
    if (!p->actions.isEmpty()) {
        p->clear();
        QQuickActionGroup *q = static_cast<QQuickActionGroup *>(prop->object);
        // QTBUG-52358: don't clear the checked action immediately
        QMetaObject::invokeMethod(q, "_q_updateCurrent", Qt::QueuedConnection);
        emit q->actionsChanged();
    }
}

QQuickActionGroup::QQuickActionGroup(QObject *parent)
    : QObject(*(new QQuickActionGroupPrivate), parent)
{
}

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

QQuickActionGroupAttached *QQuickActionGroup::qmlAttachedProperties(QObject *object)
{
    return new QQuickActionGroupAttached(object);
}

/*!
    \qmlproperty Action QtQuick.Controls::ActionGroup::checkedAction

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

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

    \sa exclusive
*/
QQuickAction *QQuickActionGroup::checkedAction() const
{
    Q_D(const QQuickActionGroup);
    return d->checkedAction;
}

void QQuickActionGroup::setCheckedAction(QQuickAction *checkedAction)
{
    Q_D(QQuickActionGroup);
    if (d->checkedAction == checkedAction)
        return;

    if (d->checkedAction)
        d->checkedAction->setChecked(false);
    d->checkedAction = checkedAction;
    if (checkedAction)
        checkedAction->setChecked(true);
    emit checkedActionChanged();
}

/*!
    \qmlproperty list<Action> QtQuick.Controls::ActionGroup::actions
    \default

    This property holds the list of actions in the group.

    \sa group
*/
QQmlListProperty<QQuickAction> QQuickActionGroup::actions()
{
    Q_D(QQuickActionGroup);
    return QQmlListProperty<QQuickAction>(this, d,
        QQuickActionGroupPrivate::actions_append,
        QQuickActionGroupPrivate::actions_count,
        QQuickActionGroupPrivate::actions_at,
        QQuickActionGroupPrivate::actions_clear);
}

/*!
    \qmlproperty bool QtQuick.Controls::ActionGroup::exclusive

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

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

    In an exclusive group, the user cannot uncheck the currently checked action by triggering it;
    instead, another action in the group must be triggered to set the new checked action for that
    group.

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

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

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

/*!
    \qmlproperty bool QtQuick.Controls::ActionGroup::enabled

    This property holds whether the action group is enabled. The default value is \c true.

    If this property is \c false, then all actions in the group are disabled. If this property
    is \c true, all actions in the group are enabled, unless explicitly disabled.
*/
bool QQuickActionGroup::isEnabled() const
{
    Q_D(const QQuickActionGroup);
    return d->enabled;
}

void QQuickActionGroup::setEnabled(bool enabled)
{
    Q_D(QQuickActionGroup);
    if (d->enabled == enabled)
        return;

    for (QQuickAction *action : qAsConst(d->actions)) {
        if (d->changeEnabled(action, enabled))
            emit action->enabledChanged(enabled);
    }

    d->enabled = enabled;
    emit enabledChanged();
}

/*!
    \qmlmethod void QtQuick.Controls::ActionGroup::addAction(Action action)

    Adds an \a action to the action group.

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

    \sa actions, group
*/
void QQuickActionGroup::addAction(QQuickAction *action)
{
    Q_D(QQuickActionGroup);
    if (!action || d->actions.contains(action))
        return;

    const bool enabledChange = d->changeEnabled(action, d->enabled);

    QQuickActionPrivate::get(action)->group = this;
    QObjectPrivate::connect(action, &QQuickAction::triggered, d, &QQuickActionGroupPrivate::actionTriggered);
    QObjectPrivate::connect(action, &QQuickAction::checkedChanged, d, &QQuickActionGroupPrivate::_q_updateCurrent);

    if (d->exclusive && action->isChecked())
        setCheckedAction(action);
    if (enabledChange)
        emit action->enabledChanged(action->isEnabled());

    d->actions.append(action);
    emit actionsChanged();
}

/*!
    \qmlmethod void QtQuick.Controls::ActionGroup::removeAction(Action action)

    Removes an \a action from the action group.

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

    \sa actions, group
*/
void QQuickActionGroup::removeAction(QQuickAction *action)
{
    Q_D(QQuickActionGroup);
    if (!action || !d->actions.contains(action))
        return;

    const bool enabledChange = d->changeEnabled(action, d->enabled);

    QQuickActionPrivate::get(action)->group = nullptr;
    QObjectPrivate::disconnect(action, &QQuickAction::triggered, d, &QQuickActionGroupPrivate::actionTriggered);
    QObjectPrivate::disconnect(action, &QQuickAction::checkedChanged, d, &QQuickActionGroupPrivate::_q_updateCurrent);

    if (d->checkedAction == action)
        setCheckedAction(nullptr);
    if (enabledChange)
        emit action->enabledChanged(action->isEnabled());

    d->actions.removeOne(action);
    emit actionsChanged();
}

class QQuickActionGroupAttachedPrivate : public QObjectPrivate
{
public:
    QQuickActionGroup *group = nullptr;
};

QQuickActionGroupAttached::QQuickActionGroupAttached(QObject *parent)
    : QObject(*(new QQuickActionGroupAttachedPrivate), parent)
{
}

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

    This property attaches an action to an action group.

    \code
    ActionGroup { id: group }

    Action {
        checked: true
        text: qsTr("Option A")
        ActionGroup.group: group
    }

    Action {
        text: qsTr("Option B")
        ActionGroup.group: group
    }
    \endcode

    \sa actions
*/
QQuickActionGroup *QQuickActionGroupAttached::group() const
{
    Q_D(const QQuickActionGroupAttached);
    return d->group;
}

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

    if (d->group)
        d->group->removeAction(qobject_cast<QQuickAction*>(parent()));
    d->group = group;
    if (group)
        group->addAction(qobject_cast<QQuickAction*>(parent()));
    emit groupChanged();
}

QT_END_NAMESPACE

#include "moc_qquickactiongroup_p.cpp"
