/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) 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.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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qdeclarativenavigator_p.h"
#include "qdeclarativenavigator_p_p.h"
#include <QtLocation/private/qdeclarativegeomap_p.h>
#include <QtLocation/private/qdeclarativegeoserviceprovider_p.h>
#include <QtLocation/private/qnavigationmanager_p.h>
#include <QtLocation/private/qnavigationmanagerengine_p.h>
#include <QtLocation/private/qgeomapparameter_p.h>
#include <QtLocation/private/qdeclarativegeoroute_p.h>
#include <QtLocation/private/qdeclarativegeoroutemodel_p.h>
#include <QtLocation/private/qdeclarativegeoroutesegment_p.h>
#include <QtLocation/qgeoserviceprovider.h>
#include <QtPositioningQuick/private/qdeclarativepositionsource_p.h>
#include <QtQml/qqmlinfo.h>

QT_BEGIN_NAMESPACE

/*!
    \qmlmodule Qt.labs.location 1.0
    \title Qt Labs Location QML Types
    \ingroup qmlmodules
    \brief Provides experimental QtLocation QML types, such as \l Navigator and
    various map objects types (not to be confused with map items).

    To use this module, import the module with the following line:

    \code
    import Qt.labs.location 1.0
    \endcode

    \note These types are experimental and subject to source-incompatible changes from one
    Qt minor release to the next, until they are ready to be moved to the stable QtLocation QML
    module.
*/

/*!
    \qmltype Navigator
    \instantiates QDeclarativeNavigator
    \inqmlmodule Qt.labs.location
    \ingroup qml-QtLocation5-maps

    \brief The Navigator type offers functionalities to perform turn-by-turn navigation.

    The Navigator purpose is to use a plugin's turn-by-turn navigation implementation in a QML
    application in a seamless manner.
    This object may take control of the map position, orientation, tilting and zoom, as well as changing
    the map style, elements on the map such as direction information.
    In certain cases, it may also restrict user interaction with the Map and with the items on it.
*/

/*!
    \qmlproperty Plugin Qt.labs.location::Navigator::plugin

    This property holds the plugin which provides the navigation functionality.

    This is a write-once property. Once the Navigator has a plugin associated with
    it, any attempted modifications of the plugin property will be ignored.

    \sa Plugin
*/

/*!
    \qmlproperty Map Qt.labs.location::Navigator::map

    This property holds the Map that the navigator is in charge of controlling.

    This is a write-once property. Once the Navigator has a Map associated with
    it, any attempted modifications of the map property will be ignored.

    \sa Map
*/

/*!
    \qmlproperty Route Qt.labs.location::Navigator::route

    This property holds the Route that the navigator is using
    to perform the navigation.

    \note Setting this property while a navigation session is ongoing will
    stop the navigation.

    \sa Route
*/

/*!
    \qmlproperty PositionSource Qt.labs.location::Navigator::positionSource

    This property holds the PositionSource that the navigator will receive position
    updates from to perform the navigation.

    This is a write-once property. Once the Navigator has a PositionSource associated with
    it, any attempted modifications of the positionSource property will be ignored.

    \sa PositionSource
*/

/*!
    \qmlproperty bool Qt.labs.location::Navigator::active

    This property tells whether the Navigator is navigating or not.
    Set this property to \c true to start the navigation.
    Set it to \c false to stop an active navigation session.
*/

/*!
    \qmlproperty bool Qt.labs.location::Navigator::navigatorReady

    This read-only property tells whether the navigator is ready
    to start the navigation or not.
    A Navigator becomes ready once the plugin is attached and a navigation engine has been
    instantiated, and the other required properties are set to valid values.
*/

/*!
    \qmlproperty bool Qt.labs.location::Navigator::trackPositionSource

    This property tells whether the Navigator should control the Map camera to
    keep track of position source updates. This property is enabled (\c true) by
    default, and setting it to \c false is useful in cases where e.g. the user
    starts gesturing over the map area.

    Navigator plugins can also control this property directly e.g. user map
    interaction could trigger the property change. Honoring the user-specified
    value of this property is plugin dependent.
*/

/*!
    \qmlproperty bool Qt.labs.location::Navigator::automaticReroutingEnabled

    This property tells whether the Navigator should automatically recalculate
    the route when the position from \l positionSource ends too far from the route.
    The operation performed in such case is equivalent to calling \l recalculateRoutes.
    The default value is \c true.

    \note Whether this property has any effect is plugin-dependent.
    Also, whether or not it has an effect while the navigator is active is plugin-dependent.
*/

/*!
    \qmlproperty bool Qt.labs.location::Navigator::isOnRoute

    While the Navigator is in active tracking mode, this property tells
    whether the position from \l positionSource is on the route or not.
*/

/*!
    \qmlmethod void Qt.labs.location::Navigator::recalculateRoutes()

    Calling this method forces the backend to trigger a routes recalculation.

    \sa automaticReroutingEnabled
*/

/*!
    \qmlproperty enumeration Qt.labs.location::Navigator::error
    \readonly

    This read-only property holds the latest error value of the geocoding request.

    \value Navigator.NoError
           No error has occurred.
    \value Navigator.NotSupportedError
           Navigation is not supported by the service provider.
    \value Navigator.ConnectionError
           An error occurred while communicating with the service provider.
    \value Navigator.LoaderError
           The geoservice provider library could not be loaded. Setting
           QT_DEBUG_PLUGINS environment variable may help diagnosing the
           problem.
    \value Navigator.UnknownParameterError
           An unknown parameter was specified.
    \value Navigator.MissingRequiredParameterError
           Required parameter was not specified.
    \value Navigator.UnknownError
           Unknown error occurred.
*/

QDeclarativeNavigatorPrivate::QDeclarativeNavigatorPrivate(QParameterizableObject *q_)
    : q(q_), m_params(new QDeclarativeNavigatorParams), m_basicDirections(static_cast<QDeclarativeNavigator *>(q_))
{
}

QDeclarativeNavigator::QDeclarativeNavigator(QObject *parent)
    : QParameterizableObject(parent), d_ptr(new QDeclarativeNavigatorPrivate(this))
{
}

QDeclarativeNavigator::~QDeclarativeNavigator()
{
}

void QDeclarativeNavigator::classBegin()
{
}

void QDeclarativeNavigator::componentComplete()
{
    d_ptr->m_completed = true;
    // Children have been completed
    for (auto param : quickChildren<QGeoMapParameter>())
        d_ptr->m_params->m_parameters.push_back(param);
    if (d_ptr->m_plugin && d_ptr->m_plugin->isAttached())
        pluginReady();
}

QDeclarativeGeoServiceProvider *QDeclarativeNavigator::plugin() const
{
    return d_ptr->m_plugin;
}

void QDeclarativeNavigator::setMap(QDeclarativeGeoMap *map)
{
    if (d_ptr->m_params->m_map || !map) // set once prop
        return;

    d_ptr->m_params->m_map = map;
    connect(map, &QObject::destroyed, this,
            [this]() {
                this->mapChanged();
                this->updateReadyState();
            });
    emit mapChanged();
    updateReadyState();
}

QDeclarativeGeoMap *QDeclarativeNavigator::map() const
{
    return d_ptr->m_params->m_map;
}

void QDeclarativeNavigator::setRoute(QDeclarativeGeoRoute *route)
{
    if (d_ptr->m_params->m_route == route) // This isn't set-once
        return;

    const bool isReady = d_ptr->m_navigator && d_ptr->m_navigator->ready();
    const bool isActive = active();
    if (isReady && isActive)
        setActive(false); // Stop current session

    d_ptr->m_params->m_route = route;
    d_ptr->m_params->m_geoRoute = route ? route->route() : QGeoRoute();
    if (route) {
        connect(route, &QObject::destroyed,
                [this]() {
                    // Do not stop navigation if route disappears. d_ptr->m_geoRoute will still be valid.
                    // Engines can stop navigation if desired.
                    this->routeChanged();
                });
    }
    emit routeChanged();
    updateReadyState();
}

QDeclarativeGeoRoute *QDeclarativeNavigator::route() const
{
    return d_ptr->m_params->m_route;
}

void QDeclarativeNavigator::setPositionSource(QDeclarativePositionSource *positionSource)
{
    if (d_ptr->m_params->m_positionSource || !positionSource) // set once prop
        return;

    d_ptr->m_params->m_positionSource = positionSource;
    QObject::connect(positionSource, &QObject::destroyed,
            [this]() {
                this->positionSourceChanged();
                this->updateReadyState();
            }
    );
    emit positionSourceChanged();
    updateReadyState();
}

QDeclarativePositionSource *QDeclarativeNavigator::positionSource() const
{
    return d_ptr->m_params->m_positionSource;
}

// navigator automatically adjusts route when user leaves it
bool QDeclarativeNavigator::automaticReroutingEnabled() const
{
    if (d_ptr->m_navigator)
        return d_ptr->m_navigator->automaticReroutingEnabled();
    return d_ptr->m_params->m_autoRerouting;
}

// Whether or not it has an effect while the navigator is active should be plugin-dependent
void QDeclarativeNavigator::setAutomaticReroutingEnabled(bool autoRerouting)
{
    const bool autoReroutingOld = automaticReroutingEnabled();
    d_ptr->m_params->m_autoRerouting = autoRerouting;
    // Done this way, and not via signal like setTrackPositionSource because
    // plugins might not support automatic rerouting.
    if (d_ptr->m_navigator)
        d_ptr->m_navigator->setAutomaticReroutingEnabled(autoRerouting);
    if (autoRerouting != autoReroutingOld)
        emit automaticReroutingEnabledChanged();
}


bool QDeclarativeNavigator::navigatorReady() const
{
    if (d_ptr->m_navigator)
        return d_ptr->m_navigator->ready();
    return d_ptr->m_ready;
}

bool QDeclarativeNavigator::trackPositionSource() const
{
    return d_ptr->m_params->m_trackPositionSource;
}

// Navigator is in active tracking mode and the route is being followed.
// This may turn \c false if the user leaves the route.
bool QDeclarativeNavigator::isOnRoute() const
{
    if (d_ptr->m_navigator)
        return d_ptr->m_navigator->isOnRoute();
    return false;
}

void QDeclarativeNavigator::setTrackPositionSource(bool trackPositionSource)
{
    if (trackPositionSource == d_ptr->m_params->m_trackPositionSource)
        return;

    d_ptr->m_params->m_trackPositionSource = trackPositionSource;

    emit trackPositionSourceChanged(trackPositionSource);
}

QDeclarativeNavigationBasicDirections *QDeclarativeNavigator::directions() const
{
    return &d_ptr->m_basicDirections;
}

QDeclarativeNavigator::NavigationError QDeclarativeNavigator::error() const
{
    return d_ptr->m_error;
}

QString QDeclarativeNavigator::errorString() const
{
    return d_ptr->m_errorString;
}

void QDeclarativeNavigator::recalculateRoutes()
{
    if (d_ptr->m_navigator)
        d_ptr->m_navigator->recalculateRoutes();
}

/*  !NOT DOCUMENTED YET!
    \qmlproperty QAbstractNavigator *Qt.labs.location::Navigator::engineHandle

    This property returns a handle to the navigation object created by the engine.
    This object can carry engine-specific properties, signals and methods, to expose
    engine-specific features and data.

    \warning Using this property leads to writing code that's likely to work
             with only a single plugin.
*/
QAbstractNavigator *QDeclarativeNavigator::abstractNavigator() const
{
    return d_ptr->m_navigator.data();

}

bool QDeclarativeNavigator::active() const
{
    return d_ptr->m_active;
}

void QDeclarativeNavigator::setPlugin(QDeclarativeGeoServiceProvider *plugin)
{
    if (d_ptr->m_plugin)
        return; // set once property.

    d_ptr->m_plugin = plugin;
    emit pluginChanged();

    if (d_ptr->m_plugin->isAttached()) {
        pluginReady();
    } else {
        connect(d_ptr->m_plugin, &QDeclarativeGeoServiceProvider::attached,
                this, &QDeclarativeNavigator::pluginReady);
    }
}

void QDeclarativeNavigator::setActive(bool active)
{
    if (d_ptr->m_active == active)
        return;

    d_ptr->m_active = active;
    if (!d_ptr->m_plugin)
        return;

    if (active)
        start();
    else
        stop();
}

void QDeclarativeNavigator::start()
{
    if (!d_ptr->m_ready) {
        qmlWarning(this) << QStringLiteral("Navigation manager not ready.");
        return;
    }

    if (!d_ptr->m_navigator->active())
        d_ptr->m_active = d_ptr->m_navigator->start();
}

void QDeclarativeNavigator::stop()
{
    if (!ensureEngine()) { // If somebody re-set route to null or something, this may become !d_ptr->m_ready
        qmlWarning(this) << QStringLiteral("Navigation manager not ready.");
        return;
    }

    if (d_ptr->m_navigator->active())
        d_ptr->m_active = d_ptr->m_navigator->stop();

    // Cached data are cleared in response to signals emitted by m_navigator upon stop().
    // For example, m_navigator emits currentRouteChanged with an empty route,
    // and QDeclarativeNavigationBasicDirections reacts by clearing the declarative route.
}

void QDeclarativeNavigator::pluginReady()
{
    if (!d_ptr->m_completed)
        return;

    ensureEngine();
    updateReadyState();
    if (d_ptr->m_active)
        start();
}

bool QDeclarativeNavigator::ensureEngine()
{
    if (d_ptr->m_navigator)
        return true;
    if (!d_ptr->m_completed || !d_ptr->m_plugin->isAttached())
        return false;

    QGeoServiceProvider *serviceProvider = d_ptr->m_plugin->sharedGeoServiceProvider();
    // if m_plugin->isAttached(), serviceProvider cannot be null
    QNavigationManager *manager = serviceProvider->navigationManager();

    if (serviceProvider->navigationError() != QGeoServiceProvider::NoError) {
        QDeclarativeNavigator::NavigationError newError = UnknownError;
        switch (serviceProvider->navigationError()) {
        case QGeoServiceProvider::NotSupportedError:
            newError = NotSupportedError; break;
        case QGeoServiceProvider::UnknownParameterError:
            newError = UnknownParameterError; break;
        case QGeoServiceProvider::MissingRequiredParameterError:
            newError = MissingRequiredParameterError; break;
        case QGeoServiceProvider::ConnectionError:
            newError = ConnectionError; break;
        case QGeoServiceProvider::LoaderError:
            newError = LoaderError; break;
        default:
            break;
        }

        setError(newError, serviceProvider->navigationErrorString());
        return false;
    }

    if (!manager) {
        setError(NotSupportedError, tr("Plugin does not support navigation."));
        return false;
    }

    d_ptr->m_navigator.reset(manager->createNavigator(d_ptr->m_params));
    if (!d_ptr->m_navigator) {
        setError(UnknownError, tr("Failed to create a navigator object."));
        return false;
    }

    d_ptr->m_navigator->setLocale(manager->locale());
    d_ptr->m_navigator->setMeasurementSystem(manager->measurementSystem());

    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::activeChanged, this, [this](bool active){
        d_ptr->m_active = active;
        emit activeChanged(active);
    });
    connect(this, &QDeclarativeNavigator::trackPositionSourceChanged, d_ptr->m_navigator.get(), &QAbstractNavigator::setTrackPosition);

    // read-only progress info updates
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::waypointReached,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::waypointReached);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::destinationReached,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::destinationReached);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteChanged,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onCurrentRouteChanged);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteLegChanged,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentSegmentChanged,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::currentSegmentChanged);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::nextManeuverIconChanged,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::nextManeuverIconChanged);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::progressInformationChanged,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::progressInformationChanged);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::isOnRouteChanged,
            this, &QDeclarativeNavigator::isOnRouteChanged);
    connect(d_ptr->m_navigator.get(), &QAbstractNavigator::alternativeRoutesChanged,
            &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onAlternativeRoutesChanged);

    emit navigatorReadyChanged(true);
    return true;
}

void QDeclarativeNavigator::updateReadyState() {
    const bool oldReady = d_ptr->m_ready;
    if (!d_ptr->m_navigator)
        d_ptr->m_ready = false;
    else
        d_ptr->m_ready = d_ptr->m_navigator->ready();

    if (oldReady != d_ptr->m_ready)
        emit navigatorReadyChanged(d_ptr->m_ready);
}

void QDeclarativeNavigator::setError(QDeclarativeNavigator::NavigationError error, const QString &errorString)
{
    d_ptr->m_error = error;
    d_ptr->m_errorString = errorString;
    emit errorChanged();
}

QDeclarativeNavigationBasicDirections::QDeclarativeNavigationBasicDirections(QDeclarativeNavigator *parent)
:   QObject(parent), m_navigator(parent), m_routes(QByteArrayLiteral("routeData"), this)
{
    if (m_navigator)
        m_navigatorPrivate = m_navigator->d_ptr.data();
}

/*!
    \qmlpropertygroup Qt.labs.location::Navigator::directions
    \readonly
    \qmlproperty Variant Qt.labs.location::Navigator::directions.nextManeuverIcon
    \qmlproperty real Qt.labs.location::Navigator::directions.distanceToNextManeuver
    \qmlproperty real Qt.labs.location::Navigator::directions.remainingTravelDistance
    \qmlproperty real Qt.labs.location::Navigator::directions.remainingTravelDistanceToNextWaypoint
    \qmlproperty real Qt.labs.location::Navigator::directions.traveledDistance
    \qmlproperty int Qt.labs.location::Navigator::directions.timeToNextManeuver
    \qmlproperty int Qt.labs.location::Navigator::directions.remainingTravelTime
    \qmlproperty int Qt.labs.location::Navigator::directions.remainingTravelTimeToNextWaypoint
    \qmlproperty int Qt.labs.location::Navigator::directions.traveledTime
    \qmlproperty Route Qt.labs.location::Navigator::directions.currentRoute
    \qmlproperty RouteLeg Qt.labs.location::Navigator::directions.currentRouteLeg
    \qmlproperty int Qt.labs.location::Navigator::directions.currentSegment
    \qmlproperty model Qt.labs.location::Navigator::directions.alternativeRoutes

    These read-only properties are part of the \e directions property group.
    This property group holds the navigation progress information that can be
    used to access the route data and to extract directions.

    \note Some backends might not provide a full set of navigation progress
          information.

    \list
        \li The \c nextManeuverIcon property holds the next turn icon.
        \li The \c distanceToNextManeuver property holds the distance to the
            next maneuver, in meters.
        \li The \c remainingTravelDistance property holds the remaining travel
            distance, in meters.
        \li The \c remainingTravelDistanceToNextWaypoint property holds the
            remaining travel distance to the next waypoint, in meters.
        \li The \c traveledDistance property holds the traveled distance, in
            meters.
        \li The \c timeToNextManeuver property holds the time to the next
            maneuver, in milliseconds.
        \li The \c remainingTravelTime property holds the remaining travel
            time, in milliseconds.
        \li The \c remainingTravelTimeToNextWaypoint property holds the
            remaining travel time to the next waypoint, in milliseconds.
        \li The \c traveledTime property holds the traveled time, in
            milliseconds.
        \li The \c currentRoute property holds the current route the navigator
            is following. This can be the same as \l route, or can be
            different, if the navigator cannot follow the user-specified route.
            For example, if the position coming from \l positionSource is
            considerably off route, the navigation engine may recalculate and
            start to follow a new route.
        \li The \c currentRouteLeg property holds the current route leg the
            navigator is following. This is always a part of \c currentRoute,
            so the \l {RouteLeg::}{overallRoute} property of \c currentRouteLeg
            holds the same route as \c currentRoute.
        \li The \c currentSegment property holds the index of the current
            RouteSegment in the \c currentRoute.
        \li The \c alternativeRoutes property holds the list of alternative routes provided by
            the engine. If no alternative routes are present, the model will be empty.
    \endlist

    \sa directions.waypointReached(), directions.destinationReached(), Route, RouteLeg, RouteSegment, Waypoint
*/

/*!
    \qmlsignal Qt.labs.location::Navigator::directions.waypointReached(Waypoint waypoint)

    This signal is emitted when a \a waypoint has been reached.

    \sa directions, directions.destinationReached()
*/

/*!
    \qmlsignal Qt.labs.location::Navigator::directions.destinationReached()

    This signal is emitted when the last waypoint of the route, the
    destination, has been reached.

    \sa directions, directions.waypointReached()
*/
QVariant QDeclarativeNavigationBasicDirections::nextManeuverIcon() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->nextManeuverIcon();
    return QVariant();
}

qreal QDeclarativeNavigationBasicDirections::distanceToNextManeuver() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->distanceToNextManeuver();
    return qQNaN();
}

qreal QDeclarativeNavigationBasicDirections::remainingTravelDistance() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->remainingTravelDistance();
    return qQNaN();
}

qreal QDeclarativeNavigationBasicDirections::remainingTravelDistanceToNextWaypoint() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->remainingTravelDistanceToNextWaypoint();
    return qQNaN();
}

qreal QDeclarativeNavigationBasicDirections::traveledDistance() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->traveledDistance();
    return 0;
}

int QDeclarativeNavigationBasicDirections::timeToNextManeuver() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->timeToNextManeuver();
    return -1;
}

int QDeclarativeNavigationBasicDirections::remainingTravelTime() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->remainingTravelTime();
    return -1;
}

int QDeclarativeNavigationBasicDirections::remainingTravelTimeToNextWaypoint() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->remainingTravelTimeToNextWaypoint();
    return -1;
}

int QDeclarativeNavigationBasicDirections::traveledTime() const
{
    if (m_navigatorPrivate->m_navigator)
        return m_navigatorPrivate->m_navigator->traveledTime();
    return 0;
}

QDeclarativeGeoRoute *QDeclarativeNavigationBasicDirections::currentRoute() const
{
    if (!m_navigatorPrivate->m_ready
            || !m_navigatorPrivate->m_navigator
            || !m_navigatorPrivate->m_navigator->active())
        return m_navigatorPrivate->m_params->m_route.data(); // the user-specified route, if any
    return m_currentRoute;
}

QDeclarativeGeoRouteLeg *QDeclarativeNavigationBasicDirections::currentRouteLeg() const
{
    if (!m_navigatorPrivate->m_ready
            || !m_navigatorPrivate->m_navigator
            || !m_navigatorPrivate->m_navigator->active())
        return nullptr;
    return m_currentRouteLeg;
}

int QDeclarativeNavigationBasicDirections::currentSegment() const
{
    if (!m_navigatorPrivate->m_ready
            || !m_navigatorPrivate->m_navigator
            || !m_navigatorPrivate->m_navigator->active())
        return 0;
    return m_navigatorPrivate->m_navigator->currentSegment();
}

QAbstractItemModel *QDeclarativeNavigationBasicDirections::alternativeRoutes()
{
    return &m_routes;
}

void QDeclarativeNavigationBasicDirections::onCurrentRouteChanged()
{
    if (m_currentRoute)
        m_currentRoute->deleteLater();
    m_currentRoute = new QDeclarativeGeoRoute(m_navigatorPrivate->m_navigator->currentRoute(), this);
    emit currentRouteChanged();
}

void QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged()
{
    if (m_currentRouteLeg)
        m_currentRouteLeg->deleteLater();
    m_currentRouteLeg = new QDeclarativeGeoRouteLeg(m_navigatorPrivate->m_navigator->currentRouteLeg(), this);
    emit currentRouteLegChanged();
}

void QDeclarativeNavigationBasicDirections::onAlternativeRoutesChanged()
{
    const QList<QGeoRoute> &routes = m_navigatorPrivate->m_navigator->alternativeRoutes();
    QList<QDeclarativeGeoRoute *> declarativeRoutes;
    for (int i = 0; i < routes.size(); ++i) {
        QDeclarativeGeoRoute *route = new QDeclarativeGeoRoute(routes.at(i), &m_routes);
        QQmlEngine::setContextForObject(route, QQmlEngine::contextForObject(this));
        declarativeRoutes.append(route);
    }
    m_routes.updateData(declarativeRoutes);
}

QT_END_NAMESPACE

