/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml 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 "qqmldelegatecomponent_p.h"
#include <QtQmlModels/private/qqmladaptormodel_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype DelegateChoice
    \instantiates QQmlDelegateChoice
    \inqmlmodule Qt.labs.qmlmodels
    \brief Encapsulates a delegate and when to use it.

    The DelegateChoice type wraps a delegate and defines the circumstances
    in which it should be chosen.

    DelegateChoices can be nested inside a DelegateChooser.

    \sa DelegateChooser
*/

/*!
    \qmlproperty variant QtQml.Models::DelegateChoice::roleValue
    This property holds the value used to match the role data for the role provided by \l DelegateChooser::role.
*/
QVariant QQmlDelegateChoice::roleValue() const
{
    return m_value;
}

void QQmlDelegateChoice::setRoleValue(const QVariant &value)
{
    if (m_value == value)
        return;
    m_value = value;
    emit roleValueChanged();
    emit changed();
}

/*!
    \qmlproperty int QtQml.Models::DelegateChoice::row
    This property holds the value used to match the row value of model elements.
    With models that have only the index property (and thus only one column), this property
    should be intended as an index, and set to the desired index value.

    \note Setting both row and index has undefined behavior. The two are equivalent and only
    one should be used.

    \sa index
*/

/*!
    \qmlproperty int QtQml.Models::DelegateChoice::index
    This property holds the value used to match the index value of model elements.
    This is effectively an alias for \l row.

    \sa row
*/
int QQmlDelegateChoice::row() const
{
    return m_row;
}

void QQmlDelegateChoice::setRow(int r)
{
    if (m_row == r)
        return;
    m_row = r;
    emit rowChanged();
    emit indexChanged();
    emit changed();
}

/*!
    \qmlproperty int QtQml.Models::DelegateChoice::column
    This property holds the value used to match the column value of model elements.
*/
int QQmlDelegateChoice::column() const
{
    return m_column;
}

void QQmlDelegateChoice::setColumn(int c)
{
    if (m_column == c)
        return;
    m_column = c;
    emit columnChanged();
    emit changed();
}

QQmlComponent *QQmlDelegateChoice::delegate() const
{
    return m_delegate;
}

/*!
    \qmlproperty Component QtQml.Models::DelegateChoice::delegate
    This property holds the delegate to use if this choice matches the model item.
*/
void QQmlDelegateChoice::setDelegate(QQmlComponent *delegate)
{
    if (m_delegate == delegate)
        return;
    QQmlAbstractDelegateComponent *adc = static_cast<QQmlAbstractDelegateComponent *>(m_delegate);
    if (adc)
        disconnect(adc, &QQmlAbstractDelegateComponent::delegateChanged, this, &QQmlDelegateChoice::delegateChanged);
    m_delegate = delegate;
    adc = static_cast<QQmlAbstractDelegateComponent *>(delegate);
    if (adc)
        connect(adc, &QQmlAbstractDelegateComponent::delegateChanged, this, &QQmlDelegateChoice::delegateChanged);
    emit delegateChanged();
    emit changed();
}

bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const
{
    if (!m_value.isValid() && m_row < 0 && m_column < 0)
        return true;

    const bool roleMatched = (m_value.isValid()) ? value == m_value : true;
    const bool rowMatched = (m_row < 0 ) ? true : m_row == row;
    const bool columnMatched = (m_column < 0 ) ? true : m_column == column;
    return roleMatched && rowMatched && columnMatched;
}

/*!
    \qmltype DelegateChooser
    \instantiates QQmlDelegateChooser
    \inqmlmodule Qt.labs.qmlmodels
    \brief Allows a view to use different delegates for different types of items in the model.

    The DelegateChooser is a special \l Component type intended for those scenarios where a Component is required
    by a view and used as a delegate.
    DelegateChooser encapsulates a set of \l {DelegateChoice}s.
    These choices are used to determine the delegate that will be instantiated for each
    item in the model.
    The selection of the choice is performed based on the value that a model item has for \l role,
    and also based on index.

    DelegateChooser is commonly used when a view needs to display a set of delegates that are significantly
    different from each other. For example, a typical phone settings view might include toggle switches,
    sliders, radio buttons, and other visualizations based on the type of each setting. In this case, DelegateChooser
    could provide an easy way to associate a different type of delegate with each setting:

    \qml \QtMinorVersion
    import QtQuick 2.\1
    import QtQuick.Controls 2.\1
    import Qt.labs.qmlmodels 1.0

    ListView {
        width: 200; height: 400

        ListModel {
            id: listModel
            ListElement { type: "info"; ... }
            ListElement { type: "switch"; ... }
            ListElement { type: "swipe"; ... }
            ListElement { type: "switch"; ... }
        }

        DelegateChooser {
            id: chooser
            role: "type"
            DelegateChoice { roleValue: "info"; ItemDelegate { ... } }
            DelegateChoice { roleValue: "switch"; SwitchDelegate { ... } }
            DelegateChoice { roleValue: "swipe"; SwipeDelegate { ... } }
        }

        model: listModel
        delegate: chooser
    }
    \endqml

    \note This type is intended to transparently work only with TableView and any DelegateModel-based view.
    Views (including user-defined views) that aren't internally based on a DelegateModel need to explicitly support
    this type of component to make it function as described.

    \sa DelegateChoice
*/

/*!
    \qmlproperty string QtQml.Models::DelegateChooser::role
    This property holds the role or the property name used to determine the delegate for a given model item.

    \sa DelegateChoice
*/
void QQmlDelegateChooser::setRole(const QString &role)
{
    if (m_role == role)
        return;
    m_role = role;
    emit roleChanged();
}

/*!
    \qmlproperty list<DelegateChoice> QtQml.Models::DelegateChooser::choices
    \default

    The list of DelegateChoices for the chooser.

    The list is treated as an ordered list, where the first DelegateChoice to match
    will be used be a view.

    It should not generally be necessary to refer to the \c choices property,
    as it is the default property for DelegateChooser and thus all child items are
    automatically assigned to this property.
*/

QQmlListProperty<QQmlDelegateChoice> QQmlDelegateChooser::choices()
{
    return QQmlListProperty<QQmlDelegateChoice>(this, nullptr,
                                                QQmlDelegateChooser::choices_append,
                                                QQmlDelegateChooser::choices_count,
                                                QQmlDelegateChooser::choices_at,
                                                QQmlDelegateChooser::choices_clear,
                                                QQmlDelegateChooser::choices_replace,
                                                QQmlDelegateChooser::choices_removeLast);
}

void QQmlDelegateChooser::choices_append(QQmlListProperty<QQmlDelegateChoice> *prop, QQmlDelegateChoice *choice)
{
    QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
    q->m_choices.append(choice);
    connect(choice, &QQmlDelegateChoice::changed, q, &QQmlAbstractDelegateComponent::delegateChanged);
    q->delegateChanged();
}

int QQmlDelegateChooser::choices_count(QQmlListProperty<QQmlDelegateChoice> *prop)
{
    QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser*>(prop->object);
    return q->m_choices.count();
}

QQmlDelegateChoice *QQmlDelegateChooser::choices_at(QQmlListProperty<QQmlDelegateChoice> *prop, int index)
{
    QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser*>(prop->object);
    return q->m_choices.at(index);
}

void QQmlDelegateChooser::choices_clear(QQmlListProperty<QQmlDelegateChoice> *prop)
{
    QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
    for (QQmlDelegateChoice *choice : q->m_choices)
        disconnect(choice, &QQmlDelegateChoice::changed, q, &QQmlAbstractDelegateComponent::delegateChanged);
    q->m_choices.clear();
    q->delegateChanged();
}

void QQmlDelegateChooser::choices_replace(QQmlListProperty<QQmlDelegateChoice> *prop, int index,
                                          QQmlDelegateChoice *choice)
{
    QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
    disconnect(q->m_choices[index], &QQmlDelegateChoice::changed,
               q, &QQmlAbstractDelegateComponent::delegateChanged);
    q->m_choices[index] = choice;
    connect(choice, &QQmlDelegateChoice::changed, q,
            &QQmlAbstractDelegateComponent::delegateChanged);
    q->delegateChanged();
}

void QQmlDelegateChooser::choices_removeLast(QQmlListProperty<QQmlDelegateChoice> *prop)
{
    QQmlDelegateChooser *q = static_cast<QQmlDelegateChooser *>(prop->object);
    disconnect(q->m_choices.takeLast(), &QQmlDelegateChoice::changed,
               q, &QQmlAbstractDelegateComponent::delegateChanged);
    q->delegateChanged();
}

QQmlComponent *QQmlDelegateChooser::delegate(QQmlAdaptorModel *adaptorModel, int row, int column) const
{
    QVariant v;
    if (!m_role.isNull())
        v = value(adaptorModel, row, column, m_role);
    if (!v.isValid()) { // check if the row only has modelData, for example if the row is a QVariantMap
        v = value(adaptorModel, row, column, QStringLiteral("modelData"));

        if (v.isValid()) {
            if (v.canConvert(QMetaType::QVariantMap))
                v = v.toMap().value(m_role);
            else if (v.canConvert(QMetaType::QObjectStar))
                v = v.value<QObject*>()->property(m_role.toUtf8());
        }
    }

    // loop through choices, finding first one that fits
    for (int i = 0; i < m_choices.count(); ++i) {
        const QQmlDelegateChoice *choice = m_choices.at(i);
        if (choice->match(row, column, v))
            return choice->delegate();
    }

    return nullptr;
}

QT_END_NAMESPACE
