/****************************************************************************
**
** 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, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)> (&QAbstractSocket::error),
                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)
{
    delete m_nmeaSocket;
    m_nmeaSocket = 0;

    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
