/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtPositioning 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 "qdeclarativepositionsource_p.h"
#include "qdeclarativeposition_p.h"

#include <QtCore/QCoreApplication>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqml.h>
#include <QtPositioning/qnmeapositioninfosource.h>
#include <qdeclarativepluginparameter_p.h>
#include <QFile>
#include <QtNetwork/QTcpSocket>
#include <QTimer>

QT_BEGIN_NAMESPACE

/*!
    \qmltype PositionSource
    //! \instantiates QDeclarativePositionSource
    \inqmlmodule QtPositioning
    \since 5.2

    \brief The PositionSource type provides the device's current position.

    The PositionSource type provides information about the user device's
    current position. The position is available as a \l{Position} type, which
    contains all the standard parameters typically available from GPS and other
    similar systems, including longitude, latitude, speed and accuracy details.

    As different position sources are available on different platforms and
    devices, these are categorized by their basic type (Satellite, NonSatellite,
    and AllPositioningMethods). The available methods for the current platform
    can be enumerated in the \l{supportedPositioningMethods} property.

    To indicate which methods are suitable for your application, set the
    \l{preferredPositioningMethods} property. If the preferred methods are not
    available, the default source of location data for the platform will be
    chosen instead. If no default source is available (because none are installed
    for the runtime platform, or because it is disabled), the \l{valid} property
    will be set to false.

    The \l updateInterval property can then be used to indicate how often your
    application wishes to receive position updates. The \l{start}(),
    \l{stop}() and \l{update}() methods can be used to control the operation
    of the PositionSource, as well as the \l{active} property, which when set
    is equivalent to calling \l{start}() or \l{stop}().

    When the PositionSource is active, position updates can be retrieved
    either by simply using the \l{position} property in a binding (as the
    value of another item's property), or by providing an implementation of
    the \c {onPositionChanged} signal-handler.

    \section2 Example Usage

    The following example shows a simple PositionSource used to receive
    updates every second and print the longitude and latitude out to
    the console.

    \code
    PositionSource {
        id: src
        updateInterval: 1000
        active: true

        onPositionChanged: {
            var coord = src.position.coordinate;
            console.log("Coordinate:", coord.longitude, coord.latitude);
        }
    }
    \endcode

    The \l{geoflickr}{GeoFlickr} example application shows how to use
    a PositionSource in your application to retrieve local data for users
    from a REST web service.

    \sa {QtPositioning::Position}, {QGeoPositionInfoSource}, {PluginParameter}

*/

/*!
    \qmlsignal PositionSource::updateTimeout()

    If \l update() was called, this signal is emitted if the current position could not be
    retrieved within a certain amount of time.

    If \l start() was called, this signal is emitted if the position engine determines that
    it is not able to provide further regular updates.

    \since Qt Positioning 5.5

    \sa QGeoPositionInfoSource::updateTimeout()
*/


QDeclarativePositionSource::QDeclarativePositionSource()
:   m_positionSource(0), m_preferredPositioningMethods(NoPositioningMethods), m_nmeaFile(0),
    m_nmeaSocket(0), m_active(false), m_singleUpdate(false), m_updateInterval(0),
    m_sourceError(NoError)
{
}

QDeclarativePositionSource::~QDeclarativePositionSource()
{
    delete m_nmeaFile;
    delete m_nmeaSocket;
    delete m_positionSource;
}


/*!
    \qmlproperty string PositionSource::name

    This property holds the unique internal name for the plugin currently
    providing position information.

    Setting the property causes the PositionSource to use a particular positioning provider.  If
    the PositionSource is active at the time that the name property is changed, it will become
    inactive.  If the specified positioning provider cannot be loaded the position source will
    become invalid.

    Changing the name property may cause the \l {updateInterval}, \l {supportedPositioningMethods}
    and \l {preferredPositioningMethods} properties to change as well.
*/


QString QDeclarativePositionSource::name() const
{
    if (m_positionSource)
        return m_positionSource->sourceName();
    else
        return m_providerName;
}

void QDeclarativePositionSource::setName(const QString &newName)
{
    if (m_positionSource && m_positionSource->sourceName() == newName)
        return;

    if (m_providerName == newName && m_providerName.isEmpty())
        return; // previously attached to a default source, now requesting the same.

    const QString previousName = name();
    m_providerName = newName;

    if (!m_componentComplete || !m_parametersInitialized) {
        if (previousName != name())
            emit nameChanged();
        return;
    }

    tryAttach(newName, false);
}

/*!
    \internal
*/
void QDeclarativePositionSource::tryAttach(const QString &newName, bool useFallback)
{
    const QString previousName = name();
    const bool sourceExisted = m_positionSource;
    m_providerName = newName;

    int previousUpdateInterval = updateInterval();
    PositioningMethods previousPositioningMethods = supportedPositioningMethods();
    PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();

    if (newName.isEmpty()) {
        setSource(QGeoPositionInfoSource::createDefaultSource(parameterMap(), this));
    } else {
        setSource(QGeoPositionInfoSource::createSource(newName, parameterMap(), this));
        if (!m_positionSource && useFallback)
            setSource(QGeoPositionInfoSource::createDefaultSource(parameterMap(), this));
    }

    if (m_positionSource) {
        connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
                this, SLOT(positionUpdateReceived(QGeoPositionInfo)));
        connect(m_positionSource, SIGNAL(error(QGeoPositionInfoSource::Error)),
                this, SLOT(sourceErrorReceived(QGeoPositionInfoSource::Error)));
        connect(m_positionSource, SIGNAL(updateTimeout()),
                this, SLOT(updateTimeoutReceived()));

        m_positionSource->setUpdateInterval(m_updateInterval);
        m_positionSource->setPreferredPositioningMethods(
            static_cast<QGeoPositionInfoSource::PositioningMethods>(int(m_preferredPositioningMethods)));

        const QGeoPositionInfo &lastKnown = m_positionSource->lastKnownPosition();
        if (lastKnown.isValid())
            setPosition(lastKnown);
    } else if (m_active) {
        m_active = false;
        emit activeChanged();
    }

    if (previousUpdateInterval != updateInterval())
        emit updateIntervalChanged();

    if (previousPreferredPositioningMethods != preferredPositioningMethods())
        emit preferredPositioningMethodsChanged();

    if (previousPositioningMethods != supportedPositioningMethods())
        emit supportedPositioningMethodsChanged();

    emit validityChanged();

    if (m_active) { // implies m_positionSource
        if (!sourceExisted) {
            QTimer::singleShot(0, this, SLOT(start())); // delay ensures all properties have been set
        } else {
            m_active = false;
            emit activeChanged();
        }
    }

    if (previousName != name())
        emit nameChanged();
}

/*!
    \qmlproperty bool PositionSource::valid

    This property is true if the PositionSource object has acquired a valid
    backend plugin to provide data. If false, other methods on the PositionSource
    will have no effect.

    Applications should check this property to determine whether positioning is
    available and enabled on the runtime platform, and react accordingly.
*/
bool QDeclarativePositionSource::isValid() const
{
    return (m_positionSource != 0);
}

void QDeclarativePositionSource::setNmeaSource(const QUrl &nmeaSource)
{
    if (nmeaSource.scheme() == QLatin1String("socket")) {
        if (m_nmeaSocket
                && nmeaSource.host() == m_nmeaSocket->peerName()
                && nmeaSource.port() == m_nmeaSocket->peerPort()) {
            return;
        }

        delete m_nmeaSocket;
        m_nmeaSocket = new QTcpSocket();

        connect(m_nmeaSocket, &QAbstractSocket::errorOccurred,
                this, &QDeclarativePositionSource::socketError);
        connect(m_nmeaSocket, &QTcpSocket::connected,
                this, &QDeclarativePositionSource::socketConnected);

        m_nmeaSocket->connectToHost(nmeaSource.host(), nmeaSource.port(), QTcpSocket::ReadOnly);
    } else {
        // Strip the filename. This is clumsy but the file may be prefixed in several
        // ways: "file:///", "qrc:///", "/", "" in platform dependent manner.
        QString localFileName = nmeaSource.toString();
        if (!QFile::exists(localFileName)) {
            if (localFileName.startsWith(QStringLiteral("qrc:///"))) {
                localFileName.remove(0, 7);
            } else if (localFileName.startsWith(QStringLiteral("file:///"))) {
                localFileName.remove(0, 7);
            } else if (localFileName.startsWith(QStringLiteral("qrc:/"))) {
                localFileName.remove(0, 5);
            }
            if (!QFile::exists(localFileName) && localFileName.startsWith('/')) {
                localFileName.remove(0,1);
            }
        }
        if (m_nmeaFileName == localFileName)
            return;
        m_nmeaFileName = localFileName;

        PositioningMethods previousPositioningMethods = supportedPositioningMethods();

        // The current position source needs to be deleted
        // because QNmeaPositionInfoSource can be bound only to a one file.
        delete m_nmeaSocket;
        m_nmeaSocket = 0;
        setSource(nullptr);
        setPosition(QGeoPositionInfo());
        // Create the NMEA source based on the given data. QML has automatically set QUrl
        // type to point to correct path. If the file is not found, check if the file actually
        // was an embedded resource file.
        delete m_nmeaFile;
        m_nmeaFile = new QFile(localFileName);
        if (!m_nmeaFile->exists()) {
            localFileName.prepend(':');
            m_nmeaFile->setFileName(localFileName);
        }
        if (m_nmeaFile->exists()) {
#ifdef QDECLARATIVE_POSITION_DEBUG
            qDebug() << "QDeclarativePositionSource NMEA File was found: " << localFileName;
#endif
            setSource(new QNmeaPositionInfoSource(QNmeaPositionInfoSource::SimulationMode));
            (qobject_cast<QNmeaPositionInfoSource *>(m_positionSource))->setUserEquivalentRangeError(2.5); // it is internally multiplied by 2 in qlocationutils_readGga
            (qobject_cast<QNmeaPositionInfoSource *>(m_positionSource))->setDevice(m_nmeaFile);
            connect(m_positionSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
                    this, SLOT(positionUpdateReceived(QGeoPositionInfo)));
            connect(m_positionSource, SIGNAL(error(QGeoPositionInfoSource::Error)),
                    this, SLOT(sourceErrorReceived(QGeoPositionInfoSource::Error)));
            connect(m_positionSource, SIGNAL(updateTimeout()),
                    this, SLOT(updateTimeoutReceived()));

            setPosition(m_positionSource->lastKnownPosition());
            if (m_active && !m_singleUpdate) {
                // Keep on updating even though source changed
                QTimer::singleShot(0, this, SLOT(start()));
            }
        } else {
            qmlWarning(this) << QStringLiteral("Nmea file not found") << localFileName;
#ifdef QDECLARATIVE_POSITION_DEBUG
            qDebug() << "QDeclarativePositionSource NMEA File was not found: " << localFileName;
#endif
            if (m_active) {
                m_active = false;
                m_singleUpdate = false;
                emit activeChanged();
            }
        }

        if (previousPositioningMethods != supportedPositioningMethods())
            emit supportedPositioningMethodsChanged();
    }

    m_nmeaSource = nmeaSource;
    emit nmeaSourceChanged();
}

/*!
    \internal
*/
void QDeclarativePositionSource::socketConnected()
{
#ifdef QDECLARATIVE_POSITION_DEBUG
    qDebug() << "Socket connected: " << m_nmeaSocket->peerName();
#endif
    PositioningMethods previousPositioningMethods = supportedPositioningMethods();

    // The current position source needs to be deleted
    // because QNmeaPositionInfoSource can be bound only to a one file.
    delete m_nmeaFile;
    m_nmeaFile = 0;
    setSource(nullptr);

    setSource(new QNmeaPositionInfoSource(QNmeaPositionInfoSource::RealTimeMode));
    (qobject_cast<QNmeaPositionInfoSource *>(m_positionSource))->setDevice(m_nmeaSocket);

    connect(m_positionSource, &QNmeaPositionInfoSource::positionUpdated,
            this, &QDeclarativePositionSource::positionUpdateReceived);
    connect(m_positionSource, SIGNAL(error(QGeoPositionInfoSource::Error)),
            this, SLOT(sourceErrorReceived(QGeoPositionInfoSource::Error)));
    connect(m_positionSource, SIGNAL(updateTimeout()),
            this, SLOT(updateTimeoutReceived()));

    setPosition(m_positionSource->lastKnownPosition());

    if (m_active && !m_singleUpdate) {
        // Keep on updating even though source changed
        QTimer::singleShot(0, this, SLOT(start()));
    }

    if (previousPositioningMethods != supportedPositioningMethods())
        emit supportedPositioningMethodsChanged();
}

/*!
    \internal
*/
void QDeclarativePositionSource::socketError(QAbstractSocket::SocketError error)
{
    m_nmeaSocket->deleteLater();
    m_nmeaSocket = nullptr;

    switch (error) {
    case QAbstractSocket::UnknownSocketError:
        m_sourceError = QDeclarativePositionSource::UnknownSourceError;
        break;
    case QAbstractSocket::SocketAccessError:
        m_sourceError = QDeclarativePositionSource::AccessError;
        break;
    case QAbstractSocket::RemoteHostClosedError:
        m_sourceError = QDeclarativePositionSource::ClosedError;
        break;
    default:
        qWarning() << "Connection failed! QAbstractSocket::SocketError" << error;
        m_sourceError = QDeclarativePositionSource::SocketError;
        break;
    }

    emit sourceErrorChanged();
}


void QDeclarativePositionSource::updateTimeoutReceived()
{
    if (!m_active)
        return;

    if (m_singleUpdate) {
        m_singleUpdate = false;

        // only singleUpdate based timeouts change activity
        // continuous updates may resume again (see QGeoPositionInfoSource::startUpdates())
        m_active = false;
        emit activeChanged();
    }

    emit updateTimeout();
}

/*!
    \internal
*/
void QDeclarativePositionSource::onParameterInitialized()
{
    m_parametersInitialized = true;
    for (QDeclarativePluginParameter *p: qAsConst(m_parameters)) {
        if (!p->isInitialized()) {
            m_parametersInitialized = false;
            break;
        }
    }

    // If here, componentComplete has been called.
    if (m_parametersInitialized)
        tryAttach(m_providerName);
}

void QDeclarativePositionSource::setPosition(const QGeoPositionInfo &pi)
{
    m_position.setPosition(pi);
    emit positionChanged();
}

void QDeclarativePositionSource::setSource(QGeoPositionInfoSource *source)
{
    if (m_positionSource)
        delete m_positionSource;

    if (!source) {
        m_positionSource = nullptr;
    } else {
        m_positionSource = source;
        connect(m_positionSource, &QGeoPositionInfoSource::supportedPositioningMethodsChanged,
                this, &QDeclarativePositionSource::supportedPositioningMethodsChanged);
    }
}

bool QDeclarativePositionSource::parametersReady()
{
    for (const QDeclarativePluginParameter *p: qAsConst(m_parameters)) {
        if (!p->isInitialized())
            return false;
    }
    return true;
}

/*!
    \internal
*/
QVariantMap QDeclarativePositionSource::parameterMap() const
{
    QVariantMap map;

    for (int i = 0; i < m_parameters.size(); ++i) {
        QDeclarativePluginParameter *parameter = m_parameters.at(i);
        map.insert(parameter->name(), parameter->value());
    }

    return map;
}

/*!
    \internal
*/
void QDeclarativePositionSource::setUpdateInterval(int updateInterval)
{
    if (m_positionSource) {
        int previousUpdateInterval = m_positionSource->updateInterval();

        m_updateInterval = updateInterval;

        if (previousUpdateInterval != updateInterval) {
            m_positionSource->setUpdateInterval(updateInterval);
            if (previousUpdateInterval != m_positionSource->updateInterval())
                emit updateIntervalChanged();
        }
    } else {
        if (m_updateInterval != updateInterval) {
            m_updateInterval = updateInterval;
            emit updateIntervalChanged();
        }
    }
}

/*!
    \qmlproperty url PositionSource::nmeaSource

    This property holds the source for NMEA (National Marine Electronics Association)
    position-specification data (file). One purpose of this property is to be of
    development convenience.

    Setting this property will override any other position source. Currently only
    files local to the .qml -file are supported. The NMEA source is created in simulation mode,
    meaning that the data and time information in the NMEA source data is used to provide
    positional updates at the rate at which the data was originally recorded.

    If nmeaSource has been set for a PositionSource object, there is no way to revert
    back to non-file sources.
*/

QUrl QDeclarativePositionSource::nmeaSource() const
{
    return m_nmeaSource;
}

/*!
    \qmlproperty int PositionSource::updateInterval

    This property holds the desired interval between updates (milliseconds).

    \sa {QGeoPositionInfoSource::updateInterval()}
*/

int QDeclarativePositionSource::updateInterval() const
{
    if (!m_positionSource)
        return m_updateInterval;

    return m_positionSource->updateInterval();
}

/*!
    \qmlproperty enumeration PositionSource::supportedPositioningMethods

    This property holds the supported positioning methods of the
    current source.

    \list
    \li PositionSource.NoPositioningMethods - No positioning methods supported (no source).
    \li PositionSource.SatellitePositioningMethods - Satellite-based positioning methods such as GPS are supported.
    \li PositionSource.NonSatellitePositioningMethods - Non-satellite-based methods are supported.
    \li PositionSource.AllPositioningMethods - Both satellite-based and non-satellite positioning methods are supported.
    \endlist

*/

QDeclarativePositionSource::PositioningMethods QDeclarativePositionSource::supportedPositioningMethods() const
{
    if (m_positionSource) {
        return static_cast<QDeclarativePositionSource::PositioningMethods>(
            int(m_positionSource->supportedPositioningMethods()));
    }
    return QDeclarativePositionSource::NoPositioningMethods;
}

/*!
    \qmlproperty enumeration PositionSource::preferredPositioningMethods

    This property holds the preferred positioning methods of the
    current source.

    \list
    \li PositionSource.NoPositioningMethods - No positioning method is preferred.
    \li PositionSource.SatellitePositioningMethods - Satellite-based positioning methods such as GPS should be preferred.
    \li PositionSource.NonSatellitePositioningMethods - Non-satellite-based methods should be preferred.
    \li PositionSource.AllPositioningMethods - Any positioning methods are acceptable.
    \endlist

*/

void QDeclarativePositionSource::setPreferredPositioningMethods(PositioningMethods methods)
{
    if (m_positionSource) {
        PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();

        m_preferredPositioningMethods = methods;

        if (previousPreferredPositioningMethods != methods) {
            m_positionSource->setPreferredPositioningMethods(
                static_cast<QGeoPositionInfoSource::PositioningMethods>(int(methods)));
            if (previousPreferredPositioningMethods != m_positionSource->preferredPositioningMethods())
                emit preferredPositioningMethodsChanged();
        }
    } else {
        if (m_preferredPositioningMethods != methods) {
            m_preferredPositioningMethods = methods;
            emit preferredPositioningMethodsChanged();
        }
    }
}

QDeclarativePositionSource::PositioningMethods QDeclarativePositionSource::preferredPositioningMethods() const
{
    if (m_positionSource) {
        return static_cast<QDeclarativePositionSource::PositioningMethods>(
            int(m_positionSource->preferredPositioningMethods()));
    }
    return m_preferredPositioningMethods;
}

/*!
    \qmlmethod PositionSource::start()

    Requests updates from the location source.
    Uses \l updateInterval if set, default interval otherwise.
    If there is no source available, this method has no effect.

    \sa stop, update, active
*/

void QDeclarativePositionSource::start()
{
    if (m_positionSource)
        m_positionSource->startUpdates();

    if (!m_active) {
        m_active = true;
        emit activeChanged();
    }
}

/*!
    \qmlmethod PositionSource::update()

    A convenience method to request single update from the location source.
    If there is no source available, this method has no effect.

    If the position source is not active, it will be activated for as
    long as it takes to receive an update, or until the request times
    out.  The request timeout period is source-specific.

    \sa start, stop, active
*/

void QDeclarativePositionSource::update()
{
    if (m_positionSource) {
        if (!m_active) {
            m_active = true;
            m_singleUpdate = true;
            emit activeChanged();
        }
        // Use default timeout value. Set active before calling the
        // update request because on some platforms there may
        // be results immediately.
        m_positionSource->requestUpdate();
    }
}

/*!
    \qmlmethod PositionSource::stop()

    Stops updates from the location source.
    If there is no source available or it is not active,
    this method has no effect.

    \sa start, update, active
*/

void QDeclarativePositionSource::stop()
{
    if (m_positionSource) {
        m_positionSource->stopUpdates();
        if (m_active) {
            m_active = false;
            emit activeChanged();
        }
    }
}

/*!
    \qmlproperty bool PositionSource::active

    This property indicates whether the position source is active.
    Setting this property to false equals calling \l stop, and
    setting this property true equals calling \l start.

    \sa start, stop, update
*/
void QDeclarativePositionSource::setActive(bool active)
{
    if (active == m_active)
        return;

    if (active)
        QTimer::singleShot(0, this, SLOT(start())); // delay ensures all properties have been set
    else
        stop();
}

bool QDeclarativePositionSource::isActive() const
{
    return m_active;
}

/*!
    \qmlproperty Position PositionSource::position

    This property holds the last known positional data.
    It is a read-only property.

    The Position type has different positional member variables,
    whose validity can be checked with appropriate validity functions
    (for example sometimes an update does not have speed or altitude data).

    However, whenever a \c {positionChanged} signal has been received, at least
    position::coordinate::latitude, position::coordinate::longitude, and position::timestamp can
    be assumed to be valid.

    \sa start, stop, update
*/

QDeclarativePosition *QDeclarativePositionSource::position()
{
    return &m_position;
}

void QDeclarativePositionSource::positionUpdateReceived(const QGeoPositionInfo &update)
{
    setPosition(update);

    if (m_singleUpdate && m_active) {
        m_active = false;
        m_singleUpdate = false;
        emit activeChanged();
    }
}


/*!
    \qmlproperty enumeration PositionSource::sourceError

    This property holds the error which last occurred with the PositionSource.

    \list
    \li PositionSource.AccessError - The connection setup to the remote positioning backend failed because the
        application lacked the required privileges.
    \li PositionSource.ClosedError - The positioning backend closed the connection, which happens for example in case
        the user is switching location services to off. As soon as the location service is re-enabled
        regular updates will resume.
    \li PositionSource.NoError - No error has occurred.
    \li PositionSource.UnknownSourceError - An unidentified error occurred.
    \li PositionSource.SocketError - An error occurred while connecting to an nmea source using a socket.
    \endlist

*/

QDeclarativePositionSource::SourceError QDeclarativePositionSource::sourceError() const
{
    return m_sourceError;
}

QGeoPositionInfoSource *QDeclarativePositionSource::positionSource() const
{
    return m_positionSource;
}

/*!
    \qmlproperty list<PluginParameter> PositionSource::parameters
    \default

    This property holds the list of plugin parameters.

    \since QtPositioning 5.14
*/
QQmlListProperty<QDeclarativePluginParameter> QDeclarativePositionSource::parameters()
{
    return QQmlListProperty<QDeclarativePluginParameter>(this,
            0,
            parameter_append,
            parameter_count,
            parameter_at,
            parameter_clear);
}

/*!
    \internal
*/
void QDeclarativePositionSource::parameter_append(QQmlListProperty<QDeclarativePluginParameter> *prop, QDeclarativePluginParameter *parameter)
{
    QDeclarativePositionSource *p = static_cast<QDeclarativePositionSource *>(prop->object);
    p->m_parameters.append(parameter);
}

/*!
    \internal
*/
int QDeclarativePositionSource::parameter_count(QQmlListProperty<QDeclarativePluginParameter> *prop)
{
    return static_cast<QDeclarativePositionSource *>(prop->object)->m_parameters.count();
}

/*!
    \internal
*/
QDeclarativePluginParameter *QDeclarativePositionSource::parameter_at(QQmlListProperty<QDeclarativePluginParameter> *prop, int index)
{
    return static_cast<QDeclarativePositionSource *>(prop->object)->m_parameters[index];
}

/*!
    \internal
*/
void QDeclarativePositionSource::parameter_clear(QQmlListProperty<QDeclarativePluginParameter> *prop)
{
    QDeclarativePositionSource *p = static_cast<QDeclarativePositionSource *>(prop->object);
    p->m_parameters.clear();
}


void QDeclarativePositionSource::componentComplete()
{
    m_componentComplete = true;
    m_parametersInitialized = true;
    for (QDeclarativePluginParameter *p: qAsConst(m_parameters)) {
        if (!p->isInitialized()) {
            m_parametersInitialized = false;
            connect(p, &QDeclarativePluginParameter::initialized,
                    this, &QDeclarativePositionSource::onParameterInitialized);
        }
    }

    if (m_parametersInitialized)
        tryAttach(m_providerName);
}

/*!
     \qmlmethod bool QtLocation::PositionSource::setBackendProperty(string name, Variant value)

    Sets the backend-specific property named \a name to \a value.
    Returns true on success, false otherwise, including if called on an uninitialized PositionSource.
    Supported backend-specific properties are listed and described in
    \l {Qt Positioning plugins#Default plugins}.

    \since Qt Positioning 5.14

    \sa backendProperty, QGeoPositionInfoSource::setBackendProperty
*/
bool QDeclarativePositionSource::setBackendProperty(const QString &name, const QVariant &value)
{
    if (m_positionSource)
        return m_positionSource->setBackendProperty(name, value);
    return false;
}

/*!
     \qmlmethod Variant QtLocation::PositionSource::backendProperty(string name)

    Returns the value of the backend-specific property named \a name, if present.
    Otherwise, including if called on an uninitialized PositionSource, the return value will be invalid.
    Supported backend-specific properties are listed and described in
    \l {Qt Positioning plugins#Default plugins}.

    \since Qt Positioning 5.14

    \sa backendProperty, QGeoPositionInfoSource::setBackendProperty
*/
QVariant QDeclarativePositionSource::backendProperty(const QString &name) const
{
    if (m_positionSource)
        return m_positionSource->backendProperty(name);
    return QVariant();
}

/*!
    \internal
*/
void QDeclarativePositionSource::sourceErrorReceived(const QGeoPositionInfoSource::Error error)
{
    if (error == QGeoPositionInfoSource::AccessError)
        m_sourceError = QDeclarativePositionSource::AccessError;
    else if (error == QGeoPositionInfoSource::ClosedError)
        m_sourceError = QDeclarativePositionSource::ClosedError;
    else if (error == QGeoPositionInfoSource::NoError)
        return; //nothing to do
    else
        m_sourceError = QDeclarativePositionSource::UnknownSourceError;

    emit sourceErrorChanged();
}

QT_END_NAMESPACE
