/****************************************************************************
**
** Copyright (C) 2016 Jolla Ltd.
** Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
** 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 <QtCore/QtNumeric>
#include "qdeclarativeposition_p.h"
#include <QtQml/qqml.h>
#include <qnmeapositioninfosource.h>
#include <QFile>

QT_BEGIN_NAMESPACE

/*!
    \qmltype Position
    //! \instantiates QDeclarativePosition
    \inqmlmodule QtPositioning
    \since 5.2

    \brief The Position type holds positional data at a particular point in time,
    such as coordinate (longitude, latitude, altitude) and speed.

    The Position type holds values related to geographic location such as
    a \l coordinate (longitude, latitude, and altitude), the \l timestamp when
    the Position was obtained, the \l speed at that time, and the accuracy of
    the data.

    Primarily, it is used in the \l{PositionSource::position}{position} property
    of a \l{PositionSource}, as the basic unit of data available from the system
    location data source.

    Not all properties of a Position object are necessarily valid or available
    (for example latitude and longitude may be valid, but speed update has not been
    received or set manually). As a result, corresponding "valid" properties
    are available (for example \l{coordinate} and \l{longitudeValid}, \l{latitudeValid}
    etc) to discern whether the data is available and valid in this position
    update.

    Position objects are read-only and can only be produced by a PositionSource.

    \section2 Example Usage

    See the example given for the \l{PositionSource} type, or the
    \l{geoflickr}{GeoFlickr} example application.

    \sa PositionSource, coordinate
*/

namespace
{

bool equalOrNaN(qreal a, qreal b)
{
    return a == b || (qIsNaN(a) && qIsNaN(b));
}

bool exclusiveNaN(qreal a, qreal b)
{
    return qIsNaN(a) != qIsNaN(b);
}

}

QDeclarativePosition::QDeclarativePosition(QObject *parent)
:   QObject(parent)
{
}

QDeclarativePosition::~QDeclarativePosition()
{
}

void QDeclarativePosition::setPosition(const QGeoPositionInfo &info)
{
    // timestamp
    const QDateTime pTimestamp = m_info.timestamp();
    const QDateTime timestamp = info.timestamp();
    bool emitTimestampChanged = pTimestamp != timestamp;

    // coordinate
    const QGeoCoordinate pCoordinate = m_info.coordinate();
    const QGeoCoordinate coordinate = info.coordinate();
    bool emitCoordinateChanged = pCoordinate != coordinate;
    bool emitLatitudeValidChanged = exclusiveNaN(pCoordinate.latitude(), coordinate.latitude());
    bool emitLongitudeValidChanged = exclusiveNaN(pCoordinate.longitude(), coordinate.longitude());
    bool emitAltitudeValidChanged = exclusiveNaN(pCoordinate.altitude(), coordinate.altitude());

    // direction
    const qreal pDirection = m_info.attribute(QGeoPositionInfo::Direction);
    const qreal direction = info.attribute(QGeoPositionInfo::Direction);
    bool emitDirectionChanged = !equalOrNaN(pDirection, direction);
    bool emitDirectionValidChanged = exclusiveNaN(pDirection, direction);

    // ground speed
    const qreal pSpeed = m_info.attribute(QGeoPositionInfo::GroundSpeed);
    const qreal speed = info.attribute(QGeoPositionInfo::GroundSpeed);
    bool emitSpeedChanged = !equalOrNaN(pSpeed, speed);
    bool emitSpeedValidChanged = exclusiveNaN(pSpeed, speed);

    // vertical speed
    const qreal pVerticalSpeed = m_info.attribute(QGeoPositionInfo::VerticalSpeed);
    const qreal verticalSpeed = info.attribute(QGeoPositionInfo::VerticalSpeed);
    bool emitVerticalSpeedChanged = !equalOrNaN(pVerticalSpeed, verticalSpeed);
    bool emitVerticalSpeedValidChanged = exclusiveNaN(pVerticalSpeed, verticalSpeed);

    // magnetic variation
    const qreal pMagneticVariation = m_info.attribute(QGeoPositionInfo::MagneticVariation);
    const qreal magneticVariation = info.attribute(QGeoPositionInfo::MagneticVariation);
    bool emitMagneticVariationChanged = !equalOrNaN(pMagneticVariation, magneticVariation);
    bool emitMagneticVariationValidChanged = exclusiveNaN(pMagneticVariation, magneticVariation);

    // horizontal accuracy
    const qreal pHorizontalAccuracy = m_info.attribute(QGeoPositionInfo::HorizontalAccuracy);
    const qreal horizontalAccuracy = info.attribute(QGeoPositionInfo::HorizontalAccuracy);
    bool emitHorizontalAccuracyChanged = !equalOrNaN(pHorizontalAccuracy, horizontalAccuracy);
    bool emitHorizontalAccuracyValidChanged = exclusiveNaN(pHorizontalAccuracy, horizontalAccuracy);

    // vertical accuracy
    const qreal pVerticalAccuracy = m_info.attribute(QGeoPositionInfo::VerticalAccuracy);
    const qreal verticalAccuracy = info.attribute(QGeoPositionInfo::VerticalAccuracy);
    bool emitVerticalAccuracyChanged = !equalOrNaN(pVerticalAccuracy, verticalAccuracy);
    bool emitVerticalAccuracyValidChanged = exclusiveNaN(pVerticalAccuracy, verticalAccuracy);

    m_info = info;

    if (emitTimestampChanged)
        emit timestampChanged();
    if (emitCoordinateChanged)
        emit coordinateChanged();
    if (emitLatitudeValidChanged)
        emit latitudeValidChanged();
    if (emitLongitudeValidChanged)
        emit longitudeValidChanged();
    if (emitAltitudeValidChanged)
        emit altitudeValidChanged();
    if (emitDirectionChanged)
        emit directionChanged();
    if (emitDirectionValidChanged)
        emit directionValidChanged();
    if (emitSpeedChanged)
        emit speedChanged();
    if (emitSpeedValidChanged)
        emit speedValidChanged();
    if (emitVerticalSpeedChanged)
        emit verticalSpeedChanged();
    if (emitVerticalSpeedValidChanged)
        emit verticalSpeedValidChanged();
    if (emitHorizontalAccuracyChanged)
        emit horizontalAccuracyChanged();
    if (emitHorizontalAccuracyValidChanged)
        emit horizontalAccuracyValidChanged();
    if (emitVerticalAccuracyChanged)
        emit verticalAccuracyChanged();
    if (emitVerticalAccuracyValidChanged)
        emit verticalAccuracyValidChanged();
    if (emitMagneticVariationChanged)
        emit magneticVariationChanged();
    if (emitMagneticVariationValidChanged)
        emit magneticVariationValidChanged();
}

const QGeoPositionInfo &QDeclarativePosition::position() const
{
    return m_info;
}

/*!
    \qmlproperty coordinate Position::coordinate

    This property holds the latitude, longitude, and altitude value of the Position.

    It is a read-only property.

    \sa longitudeValid, latitudeValid, altitudeValid
*/
QGeoCoordinate QDeclarativePosition::coordinate()
{
    return m_info.coordinate();
}

/*!
    \qmlproperty bool Position::latitudeValid

    This property is true if coordinate's latitude has been set
    (to indicate whether that data has been received or not, as every update
    does not necessarily contain all data).

    \sa coordinate
*/
bool QDeclarativePosition::isLatitudeValid() const
{
    return !qIsNaN(m_info.coordinate().latitude());
}


/*!
    \qmlproperty bool Position::longitudeValid

    This property is true if coordinate's longitude has been set
    (to indicate whether that data has been received or not, as every update
    does not necessarily contain all data).

    \sa coordinate
*/
bool QDeclarativePosition::isLongitudeValid() const
{
    return !qIsNaN(m_info.coordinate().longitude());
}


/*!
    \qmlproperty bool Position::speedValid

    This property is true if \l speed has been set
    (to indicate whether that data has been received or not, as every update
    does not necessarily contain all data).

    \sa speed
*/
bool QDeclarativePosition::isSpeedValid() const
{
    return !qIsNaN(m_info.attribute(QGeoPositionInfo::GroundSpeed));
}

/*!
    \qmlproperty bool Position::altitudeValid

    This property is true if coordinate's altitude has been set
    (to indicate whether that data has been received or not, as every update
    does not necessarily contain all data).

    \sa coordinate
*/
bool QDeclarativePosition::isAltitudeValid() const
{
    return !qIsNaN(m_info.coordinate().altitude());
}

/*!
    \qmlproperty double Position::speed

    This property holds the value of speed (groundspeed, meters / second).

    It is a read-only property.

    \sa speedValid, coordinate
*/
double QDeclarativePosition::speed() const
{
    return m_info.attribute(QGeoPositionInfo::GroundSpeed);
}

/*!
    \qmlproperty real Position::horizontalAccuracy

    This property holds the horizontal accuracy of the coordinate (in meters).

    \sa horizontalAccuracyValid, coordinate
*/
void QDeclarativePosition::setHorizontalAccuracy(qreal horizontalAccuracy)
{
    const qreal pHorizontalAccuracy = m_info.attribute(QGeoPositionInfo::HorizontalAccuracy);

    if (equalOrNaN(pHorizontalAccuracy, horizontalAccuracy))
        return;

    bool validChanged = exclusiveNaN(pHorizontalAccuracy, horizontalAccuracy);

    m_info.setAttribute(QGeoPositionInfo::HorizontalAccuracy, horizontalAccuracy);
    emit horizontalAccuracyChanged();
    if (validChanged)
        emit horizontalAccuracyValidChanged();
}

qreal QDeclarativePosition::horizontalAccuracy() const
{
    return m_info.attribute(QGeoPositionInfo::HorizontalAccuracy);
}

/*!
    \qmlproperty bool Position::horizontalAccuracyValid

    This property is true if \l horizontalAccuracy has been set
    (to indicate whether that data has been received or not, as every update
    does not necessarily contain all data).

    \sa horizontalAccuracy
*/
bool QDeclarativePosition::isHorizontalAccuracyValid() const
{
    return !qIsNaN(m_info.attribute(QGeoPositionInfo::HorizontalAccuracy));
}

/*!
    \qmlproperty real Position::verticalAccuracy

    This property holds the vertical accuracy of the coordinate (in meters).

    \sa verticalAccuracyValid, coordinate
*/
void QDeclarativePosition::setVerticalAccuracy(qreal verticalAccuracy)
{
    const qreal pVerticalAccuracy = m_info.attribute(QGeoPositionInfo::VerticalAccuracy);

    if (equalOrNaN(pVerticalAccuracy, verticalAccuracy))
        return;

    bool validChanged = exclusiveNaN(pVerticalAccuracy, verticalAccuracy);

    m_info.setAttribute(QGeoPositionInfo::VerticalAccuracy, verticalAccuracy);
    emit verticalAccuracyChanged();
    if (validChanged)
        emit verticalAccuracyValidChanged();
}

qreal QDeclarativePosition::verticalAccuracy() const
{
    return m_info.attribute(QGeoPositionInfo::VerticalAccuracy);
}

/*!
    \qmlproperty bool Position::verticalAccuracyValid

    This property is true if \l verticalAccuracy has been set
    (to indicate whether that data has been received or not, as every update
    does not necessarily contain all data).

    \sa verticalAccuracy
*/
bool QDeclarativePosition::isVerticalAccuracyValid() const
{
    return !qIsNaN(m_info.attribute(QGeoPositionInfo::VerticalAccuracy));
}

/*!
    \qmlproperty date Position::timestamp

    This property holds the timestamp when this position
    was received. If the property has not been set, it is invalid.

    It is a read-only property.
*/
QDateTime QDeclarativePosition::timestamp() const
{
    return m_info.timestamp();
}

/*!
    \qmlproperty bool Position::directionValid
    \since Qt Positioning 5.3

    This property is true if \l direction has been set (to indicate whether that data has been
    received or not, as every update does not necessarily contain all data).

    \sa direction
*/
bool QDeclarativePosition::isDirectionValid() const
{
    return !qIsNaN(m_info.attribute(QGeoPositionInfo::Direction));
}

/*!
    \qmlproperty double Position::direction
    \since Qt Positioning 5.3

    This property holds the value of the direction of travel in degrees from true north.

    It is a read-only property.

    \sa directionValid
*/
double QDeclarativePosition::direction() const
{
    return m_info.attribute(QGeoPositionInfo::Direction);
}

/*!
    \qmlproperty bool Position::verticalSpeedValid
    \since Qt Positioning 5.3

    This property is true if \l verticalSpeed has been set (to indicate whether that data has been
    received or not, as every update does not necessarily contain all data).

    \sa verticalSpeed
*/
bool QDeclarativePosition::isVerticalSpeedValid() const
{
    return !qIsNaN(m_info.attribute(QGeoPositionInfo::VerticalSpeed));
}

/*!
    \qmlproperty double Position::verticalSpeed
    \since Qt Positioning 5.3

    This property holds the value of the vertical speed in meters per second.

    It is a read-only property.

    \sa verticalSpeedValid
*/
double QDeclarativePosition::verticalSpeed() const
{
    return m_info.attribute(QGeoPositionInfo::VerticalSpeed);
}

/*!
    \qmlproperty bool Position::magneticVariationValid
    \since Qt Positioning 5.4

    This property is true if \l magneticVariation has been set (to indicate whether that data has been
    received or not, as every update does not necessarily contain all data).

    \sa magneticVariation
*/
bool QDeclarativePosition::isMagneticVariationValid() const
{
    return !qIsNaN(m_info.attribute(QGeoPositionInfo::MagneticVariation));
}

/*!
    \qmlproperty double Position::magneticVariation
    \since Qt Positioning 5.4

    This property holds the angle between the horizontal component of the
    magnetic field and true north, in degrees. Also known as magnetic
    declination. A positive value indicates a clockwise direction from
    true north and a negative value indicates a counter-clockwise direction.

    It is a read-only property.

    \sa magneticVariationValid
*/
double QDeclarativePosition::magneticVariation() const
{
    return m_info.attribute(QGeoPositionInfo::MagneticVariation);
}

QT_END_NAMESPACE
