/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickstate_p_p.h"
#include "qquickstate_p.h"

#include "qquickstategroup_p.h"
#include "qquickstatechangescript_p.h"

#include <private/qqmlglobal_p.h>

#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);

QQuickStateAction::QQuickStateAction()
: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false), fromBinding(nullptr), event(nullptr),
  specifiedObject(nullptr)
{
}

QQuickStateAction::QQuickStateAction(QObject *target, const QString &propertyName,
               const QVariant &value)
: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false),
  property(target, propertyName, qmlEngine(target)), toValue(value),
  fromBinding(nullptr), event(nullptr),
  specifiedObject(target), specifiedProperty(propertyName)
{
    if (property.isValid())
        fromValue = property.read();
}

QQuickStateAction::QQuickStateAction(QObject *target, const QQmlProperty &property, const QString &propertyName, const QVariant &value)
: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false),
  property(property), toValue(value),
  fromBinding(nullptr), event(nullptr),
  specifiedObject(target), specifiedProperty(propertyName)
{
    if (property.isValid())
        fromValue = property.read();
}


QQuickStateActionEvent::~QQuickStateActionEvent()
{
}

void QQuickStateActionEvent::execute()
{
}

bool QQuickStateActionEvent::isReversable()
{
    return false;
}

void QQuickStateActionEvent::reverse()
{
}

bool QQuickStateActionEvent::changesBindings()
{
    return false;
}

void QQuickStateActionEvent::clearBindings()
{
}

bool QQuickStateActionEvent::mayOverride(QQuickStateActionEvent *other)
{
    Q_UNUSED(other);
    return false;
}

QQuickStateOperation::QQuickStateOperation(QObjectPrivate &dd, QObject *parent)
    : QObject(dd, parent)
{
}

/*!
    \qmltype State
    \instantiates QQuickState
    \inqmlmodule QtQuick
    \ingroup qtquick-states
    \brief Defines configurations of objects and properties.

    A \e state is a set of batched changes from the default configuration.

    All items have a default state that defines the default configuration of objects
    and property values. New states can be defined by adding State items to the \l {Item::states}{states} property to
    allow items to switch between different configurations. These configurations
    can, for example, be used to apply different sets of property values or execute
    different scripts.

    The following example displays a single \l Rectangle. In the default state, the rectangle
    is colored black. In the "clicked" state, a PropertyChanges object changes the
    rectangle's color to red. Clicking within the MouseArea toggles the rectangle's state
    between the default state and the "clicked" state, thus toggling the color of the
    rectangle between black and red.

    \snippet qml/state.qml 0

    Notice the default state is referred to using an empty string ("").

    States are commonly used together with \l{Animation and Transitions in Qt Quick}{Transitions} to provide
    animations when state changes occur.

    \note Setting the state of an object from within another state of the same object is
    not allowed.

    \sa {Qt Quick Examples - Animation#States}{States example}, {Qt Quick States},
    {Animation and Transitions in Qt Quick}{Transitions}, {Qt QML}
*/
QQuickState::QQuickState(QObject *parent)
: QObject(*(new QQuickStatePrivate), parent)
{
    Q_D(QQuickState);
    d->transitionManager.setState(this);
}

QQuickState::~QQuickState()
{
    Q_D(QQuickState);
    if (d->group)
        d->group->removeState(this);
}

/*!
    \qmlproperty string QtQuick::State::name
    This property holds the name of the state.

    Each state should have a unique name within its item.
*/
QString QQuickState::name() const
{
    Q_D(const QQuickState);
    return d->name;
}

void QQuickState::setName(const QString &n)
{
    Q_D(QQuickState);
    d->name = n;
    d->named = true;
}

bool QQuickState::isNamed() const
{
    Q_D(const QQuickState);
    return d->named;
}

bool QQuickState::isWhenKnown() const
{
    Q_D(const QQuickState);
    return d->whenKnown;
}

/*!
    \qmlproperty bool QtQuick::State::when
    This property holds when the state should be applied.

    This should be set to an expression that evaluates to \c true when you want the state to
    be applied. For example, the following \l Rectangle changes in and out of the "hidden"
    state when the \l MouseArea is pressed:

    \snippet qml/state-when.qml 0

    If multiple states in a group have \c when clauses that evaluate to \c true
    at the same time, the first matching state will be applied. For example, in
    the following snippet \c state1 will always be selected rather than
    \c state2 when sharedCondition becomes \c true.
    \qml
    Item {
        states: [
            State { name: "state1"; when: sharedCondition },
            State { name: "state2"; when: sharedCondition }
        ]
        // ...
    }
    \endqml
*/
bool QQuickState::when() const
{
    Q_D(const QQuickState);
    return d->when;
}

void QQuickState::setWhen(bool when)
{
    Q_D(QQuickState);
    d->whenKnown = true;
    d->when = when;
    if (d->group)
        d->group->updateAutoState();
}

/*!
    \qmlproperty string QtQuick::State::extend
    This property holds the state that this state extends.

    When a state extends another state, it inherits all the changes of that state.

    The state being extended is treated as the base state in regards to
    the changes specified by the extending state.
*/
QString QQuickState::extends() const
{
    Q_D(const QQuickState);
    return d->extends;
}

void QQuickState::setExtends(const QString &extends)
{
    Q_D(QQuickState);
    d->extends = extends;
}

/*!
    \qmlproperty list<Change> QtQuick::State::changes
    This property holds the changes to apply for this state
    \default

    By default these changes are applied against the default state. If the state
    extends another state, then the changes are applied against the state being
    extended.
*/
QQmlListProperty<QQuickStateOperation> QQuickState::changes()
{
    Q_D(QQuickState);
    return QQmlListProperty<QQuickStateOperation>(this, &d->operations,
                                                  QQuickStatePrivate::operations_append,
                                                  QQuickStatePrivate::operations_count,
                                                  QQuickStatePrivate::operations_at,
                                                  QQuickStatePrivate::operations_clear,
                                                  QQuickStatePrivate::operations_replace,
                                                  QQuickStatePrivate::operations_removeLast);
}

int QQuickState::operationCount() const
{
    Q_D(const QQuickState);
    return d->operations.count();
}

QQuickStateOperation *QQuickState::operationAt(int index) const
{
    Q_D(const QQuickState);
    return d->operations.at(index);
}

QQuickState &QQuickState::operator<<(QQuickStateOperation *op)
{
    Q_D(QQuickState);
    d->operations.append(QQuickStatePrivate::OperationGuard(op, &d->operations));
    return *this;
}

void QQuickStatePrivate::complete()
{
    Q_Q(QQuickState);

    for (int ii = 0; ii < reverting.count(); ++ii) {
        for (int jj = 0; jj < revertList.count(); ++jj) {
            const QQuickRevertAction &revert = reverting.at(ii);
            const QQuickSimpleAction &simple = revertList.at(jj);
            if ((revert.event && simple.event() == revert.event) ||
                simple.property() == revert.property) {
                revertList.removeAt(jj);
                break;
            }
        }
    }
    reverting.clear();

    if (group)
        group->stateAboutToComplete();
    emit q->completed();
}

// Generate a list of actions for this state.  This includes coelescing state
// actions that this state "extends"
QQuickStateOperation::ActionList
QQuickStatePrivate::generateActionList() const
{
    QQuickStateOperation::ActionList applyList;
    if (inState)
        return applyList;

    // Prevent "extends" recursion
    inState = true;

    if (!extends.isEmpty()) {
        QList<QQuickState *> states = group ? group->states() : QList<QQuickState *>();
        for (int ii = 0; ii < states.count(); ++ii)
            if (states.at(ii)->name() == extends) {
                qmlExecuteDeferred(states.at(ii));
                applyList = static_cast<QQuickStatePrivate*>(states.at(ii)->d_func())->generateActionList();
            }
    }

    for (QQuickStateOperation *op : operations)
        applyList << op->actions();

    inState = false;
    return applyList;
}

QQuickStateGroup *QQuickState::stateGroup() const
{
    Q_D(const QQuickState);
    return d->group;
}

void QQuickState::setStateGroup(QQuickStateGroup *group)
{
    Q_D(QQuickState);
    d->group = group;
}

void QQuickState::cancel()
{
    Q_D(QQuickState);
    d->transitionManager.cancel();
}

void QQuickStateAction::deleteFromBinding()
{
    if (fromBinding) {
        QQmlPropertyPrivate::removeBinding(property);
        fromBinding = nullptr;
    }
}

bool QQuickState::containsPropertyInRevertList(QObject *target, const QString &name) const
{
    Q_D(const QQuickState);

    if (isStateActive()) {
        for (const QQuickSimpleAction &simpleAction : d->revertList) {
            if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
                return true;
        }
    }

    return false;
}

bool QQuickState::changeValueInRevertList(QObject *target, const QString &name, const QVariant &revertValue)
{
    Q_D(QQuickState);

    if (isStateActive()) {
        for (QQuickSimpleAction &simpleAction : d->revertList) {
            if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
                    simpleAction.setValue(revertValue);
                    return true;
            }
        }
    }

    return false;
}

bool QQuickState::changeBindingInRevertList(QObject *target, const QString &name, QQmlAbstractBinding *binding)
{
    Q_D(QQuickState);

    if (isStateActive()) {
        for (QQuickSimpleAction &simpleAction : d->revertList) {
            if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) {
                simpleAction.setBinding(binding);
                return true;
            }
        }
    }

    return false;
}

bool QQuickState::removeEntryFromRevertList(QObject *target, const QString &name)
{
    Q_D(QQuickState);

    if (isStateActive()) {
        for (auto it = d->revertList.begin(), end = d->revertList.end(); it != end; ++it) {
            QQuickSimpleAction &simpleAction = *it;
            if (simpleAction.property().object() == target && simpleAction.property().name() == name) {
                QQmlPropertyPrivate::removeBinding(simpleAction.property());

                simpleAction.property().write(simpleAction.value());
                if (simpleAction.binding())
                    QQmlPropertyPrivate::setBinding(simpleAction.binding());

                d->revertList.erase(it);
                return true;
            }
        }
    }

    return false;
}

void QQuickState::addEntryToRevertList(const QQuickStateAction &action)
{
    Q_D(QQuickState);

    QQuickSimpleAction simpleAction(action);

    d->revertList.append(simpleAction);
}

void QQuickState::removeAllEntriesFromRevertList(QObject *target)
{
     Q_D(QQuickState);

     if (isStateActive()) {
         const auto actionMatchesTarget = [target](QQuickSimpleAction &simpleAction) {
             if (simpleAction.property().object() == target) {
                 QQmlPropertyPrivate::removeBinding(simpleAction.property());

                 simpleAction.property().write(simpleAction.value());
                 if (simpleAction.binding())
                     QQmlPropertyPrivate::setBinding(simpleAction.binding());

                 return true;
             }
             return false;
         };

         d->revertList.erase(std::remove_if(d->revertList.begin(), d->revertList.end(),
                                            actionMatchesTarget),
                             d->revertList.end());
     }
}

void QQuickState::addEntriesToRevertList(const QList<QQuickStateAction> &actionList)
{
    Q_D(QQuickState);
    if (isStateActive()) {
        QList<QQuickSimpleAction> simpleActionList;
        simpleActionList.reserve(actionList.count());

        for (const QQuickStateAction &action : actionList) {
            QQuickSimpleAction simpleAction(action);
            action.property.write(action.toValue);
            if (action.toBinding)
                QQmlPropertyPrivate::setBinding(action.toBinding.data());

            simpleActionList.append(simpleAction);
        }

        d->revertList.append(simpleActionList);
    }
}

QVariant QQuickState::valueInRevertList(QObject *target, const QString &name) const
{
    Q_D(const QQuickState);

    if (isStateActive()) {
        for (const QQuickSimpleAction &simpleAction : d->revertList) {
            if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
                return simpleAction.value();
        }
    }

    return QVariant();
}

QQmlAbstractBinding *QQuickState::bindingInRevertList(QObject *target, const QString &name) const
{
    Q_D(const QQuickState);

    if (isStateActive()) {
        for (const QQuickSimpleAction &simpleAction : d->revertList) {
            if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name)
                return simpleAction.binding();
        }
    }

    return nullptr;
}

bool QQuickState::isStateActive() const
{
    return stateGroup() && stateGroup()->state() == name();
}

void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
{
    Q_D(QQuickState);

    qmlExecuteDeferred(this);

    cancel();
    if (revert)
        revert->cancel();
    d->revertList.clear();
    d->reverting.clear();

    if (revert) {
        QQuickStatePrivate *revertPrivate =
            static_cast<QQuickStatePrivate*>(revert->d_func());
        d->revertList = revertPrivate->revertList;
        revertPrivate->revertList.clear();
    }

    // List of actions caused by this state
    QQuickStateOperation::ActionList applyList = d->generateActionList();

    // List of actions that need to be reverted to roll back (just) this state
    QQuickStatePrivate::SimpleActionList additionalReverts;
    // First add the reverse of all the applyList actions
    for (int ii = 0; ii < applyList.count(); ++ii) {
        QQuickStateAction &action = applyList[ii];

        if (action.event) {
            if (!action.event->isReversable())
                continue;
            bool found = false;
            for (int jj = 0; jj < d->revertList.count(); ++jj) {
                QQuickStateActionEvent *event = d->revertList.at(jj).event();
                if (event && event->type() == action.event->type()) {
                    if (action.event->mayOverride(event)) {
                        found = true;

                        if (action.event != d->revertList.at(jj).event() && action.event->needsCopy()) {
                            action.event->copyOriginals(d->revertList.at(jj).event());

                            QQuickSimpleAction r(action);
                            additionalReverts << r;
                            d->revertList.removeAt(jj);
                            --jj;
                        } else if (action.event->isRewindable())    //###why needed?
                            action.event->saveCurrentValues();

                        break;
                    }
                }
            }
            if (!found) {
                action.event->saveOriginals();
                // Only need to revert the applyList action if the previous
                // state doesn't have a higher priority revert already
                QQuickSimpleAction r(action);
                additionalReverts << r;
            }
        } else {
            bool found = false;
            action.fromBinding = QQmlPropertyPrivate::binding(action.property);

            for (int jj = 0; jj < d->revertList.count(); ++jj) {
                if (d->revertList.at(jj).property() == action.property) {
                    found = true;
                    if (d->revertList.at(jj).binding() != action.fromBinding.data()) {
                        action.deleteFromBinding();
                    }
                    break;
                }
            }

            if (!found) {
                if (!action.restore) {
                    action.deleteFromBinding();;
                } else {
                    // Only need to revert the applyList action if the previous
                    // state doesn't have a higher priority revert already
                    QQuickSimpleAction r(action);
                    additionalReverts << r;
                }
            }
        }
    }

    // Any reverts from a previous state that aren't carried forth
    // into this state need to be translated into apply actions
    for (int ii = 0; ii < d->revertList.count(); ++ii) {
        bool found = false;
        if (d->revertList.at(ii).event()) {
            QQuickStateActionEvent *event = d->revertList.at(ii).event();
            if (!event->isReversable())
                continue;
            for (int jj = 0; !found && jj < applyList.count(); ++jj) {
                const QQuickStateAction &action = applyList.at(jj);
                if (action.event && action.event->type() == event->type()) {
                    if (action.event->mayOverride(event))
                        found = true;
                }
            }
        } else {
            for (int jj = 0; !found && jj < applyList.count(); ++jj) {
                const QQuickStateAction &action = applyList.at(jj);
                if (action.property == d->revertList.at(ii).property())
                    found = true;
            }
        }
        if (!found) {
            QVariant cur = d->revertList.at(ii).property().read();
            QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property());

            QQuickStateAction a;
            a.property = d->revertList.at(ii).property();
            a.fromValue = cur;
            a.toValue = d->revertList.at(ii).value();
            a.toBinding = d->revertList.at(ii).binding();
            a.specifiedObject = d->revertList.at(ii).specifiedObject();
            a.specifiedProperty = d->revertList.at(ii).specifiedProperty();
            a.event = d->revertList.at(ii).event();
            a.reverseEvent = d->revertList.at(ii).reverseEvent();
            if (a.event && a.event->isRewindable())
                a.event->saveCurrentValues();
            applyList << a;
            // Store these special reverts in the reverting list
            if (a.event)
                d->reverting << a.event;
            else
                d->reverting << a.property;
        }
    }
    // All the local reverts now become part of the ongoing revertList
    d->revertList << additionalReverts;

#ifndef QT_NO_DEBUG_STREAM
    // Output for debugging
    if (stateChangeDebug()) {
        for (const QQuickStateAction &action : qAsConst(applyList)) {
            if (action.event)
                qWarning() << "    QQuickStateAction event:" << action.event->type();
            else
                qWarning() << "    QQuickStateAction:" << action.property.object()
                           << action.property.name() << "From:" << action.fromValue
                           << "To:" << action.toValue;
        }
    }
#endif

    d->transitionManager.transition(applyList, trans);
}

QQuickStateOperation::ActionList QQuickStateOperation::actions()
{
    return ActionList();
}

QQuickState *QQuickStateOperation::state() const
{
    Q_D(const QQuickStateOperation);
    return d->m_state;
}

void QQuickStateOperation::setState(QQuickState *state)
{
    Q_D(QQuickStateOperation);
    d->m_state = state;
}

QT_END_NAMESPACE

#include "moc_qquickstate_p.cpp"
