/****************************************************************************
**
** 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 "qquickgeocoordinateanimation_p.h"
#include "qquickgeocoordinateanimation_p_p.h"
#include <QtQuick/private/qquickanimation_p_p.h>
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtPositioning/private/qwebmercator_p.h>
#include <QtPositioning/private/qgeocoordinate_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmltype CoordinateAnimation
    \inherits PropertyAnimation
    \inqmlmodule QtPositioning
    \since 5.3

    \brief A PropertyAnimation for geo coordinate properties.

    A specialized \l{PropertyAnimation} that defines an animation
    between two \l{coordinate}{coordinates}.

    By default, a \l{latitude} of the \l{coordinate} is animated in the direction of shortest
    (geodesic) distance between those coordinates. Since CoordinateAnimation uses Mercator
    map projection, the \l{latitude} animation is always between -90 and 90 degrees.
    The \l{longitude} animation path is not limited and can go over 180 degrees
    in both west and east directions.

    The \l{direction} property can be set to specify the direction in which the \l{longitude}
    animation should occur.

    \sa {Animation and Transitions in Qt Quick}
*/

QVariant q_coordinateInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress)
{
    if (from == to) {
        if (progress < 0.5) {
            return QVariant::fromValue(from);
        } else {
            return QVariant::fromValue(to);
        }
    }

    QGeoCoordinate result = QWebMercator::coordinateInterpolation(from, to, progress);

    return QVariant::fromValue(result);
}

QVariant q_coordinateShortestInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress)
{
    const QGeoMercatorCoordinatePrivate* fromMercator =
            static_cast<const QGeoMercatorCoordinatePrivate*>(QGeoCoordinatePrivate::get(&from));
    const QGeoMercatorCoordinatePrivate* toMercator =
            static_cast<const QGeoMercatorCoordinatePrivate*>(QGeoCoordinatePrivate::get(&to));

    double toX = toMercator->m_mercatorX;
    double toY = toMercator->m_mercatorY;
    double fromX = fromMercator->m_mercatorX;
    double fromY = fromMercator->m_mercatorY;
    double x;
    if (0.5 < qAbs(toX - fromX)) {
        // handle dateline crossing
        double ex = toX;
        double sx = fromX;
        if (ex < sx)
            sx -= 1.0;
        else if (sx < ex)
            ex -= 1.0;

        x = fromX + (toX - fromX) * progress;

        if (x < 0.0)
            x += 1.0;

    } else {
        x = fromX + (toX - fromX) * progress;
    }

    double y = fromY + (toY - fromY) * progress;

    QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y));
    result.setAltitude(from.altitude() + (to.altitude() - from.altitude()) * progress);
    return QVariant::fromValue(result);
}

QVariant q_coordinateWestInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress)
{
    const QGeoMercatorCoordinatePrivate* fromMercator =
            static_cast<const QGeoMercatorCoordinatePrivate*>(QGeoCoordinatePrivate::get(&from));
    const QGeoMercatorCoordinatePrivate* toMercator =
            static_cast<const QGeoMercatorCoordinatePrivate*>(QGeoCoordinatePrivate::get(&to));

    double toX = toMercator->m_mercatorX;
    double toY = toMercator->m_mercatorY;
    double fromX = fromMercator->m_mercatorX;
    double fromY = fromMercator->m_mercatorY;
    double diff = toX - fromX;

    while (diff < 0.0) {
        toX += 1.0;
        diff += 1.0;
    }

    double x = fromX + (toX - fromX) * progress;
    double y = fromY + (toY - fromY) * progress;

    while (x > 1.0)
        x -= 1.0;

    QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y));
    result.setAltitude(from.altitude() + (to.altitude() - from.altitude()) * progress);

    return QVariant::fromValue(result);
}

QVariant q_coordinateEastInterpolator(const QGeoCoordinate &from, const QGeoCoordinate &to, qreal progress)
{
    const QGeoMercatorCoordinatePrivate* fromMercator =
            static_cast<const QGeoMercatorCoordinatePrivate*>(QGeoCoordinatePrivate::get(&from));
    const QGeoMercatorCoordinatePrivate* toMercator =
            static_cast<const QGeoMercatorCoordinatePrivate*>(QGeoCoordinatePrivate::get(&to));

    double toX = toMercator->m_mercatorX;
    double toY = toMercator->m_mercatorY;
    double fromX = fromMercator->m_mercatorX;
    double fromY = fromMercator->m_mercatorY;
    double diff = toX - fromX;

    while (diff > 0.0) {
        toX -= 1.0;
        diff -= 1.0;
    }

    double x = fromX + (toX - fromX) * progress;
    double y = fromY + (toY - fromY) * progress;

    while (x < 0.0)
        x += 1.0;

    QGeoCoordinate result = QWebMercator::mercatorToCoord(QDoubleVector2D(x, y));
    result.setAltitude(from.altitude() + (to.altitude() - from.altitude()) * progress);

    return QVariant::fromValue(result);
}

QQuickGeoCoordinateAnimation::QQuickGeoCoordinateAnimation(QObject *parent)
    : QQuickPropertyAnimation(*(new QQuickGeoCoordinateAnimationPrivate), parent)

{
    Q_D(QQuickGeoCoordinateAnimation);
    d->interpolatorType = qMetaTypeId<QGeoCoordinate>();
    d->defaultToInterpolatorType = true;
    d->interpolator = QVariantAnimationPrivate::getInterpolator(d->interpolatorType);
}

QQuickGeoCoordinateAnimation::~QQuickGeoCoordinateAnimation()
{
}

/*!
    \qmlproperty coordinate CoordinateAnimation::from
    This property holds the coordinate where the animation should begin.
*/
QGeoCoordinate QQuickGeoCoordinateAnimation::from() const
{
    Q_D(const QQuickGeoCoordinateAnimation);
    return d->from.value<QGeoCoordinate>();
}

void QQuickGeoCoordinateAnimation::setFrom(const QGeoCoordinate &f)
{
    QGeoMercatorCoordinatePrivate *mercator = new QGeoMercatorCoordinatePrivate();
    QDoubleVector2D fromVector = QWebMercator::coordToMercator(f);
    mercator->lat = f.latitude();
    mercator->lng = f.longitude();
    mercator->alt = f.altitude();
    mercator->m_mercatorX = fromVector.x();
    mercator->m_mercatorY = fromVector.y();
    QGeoCoordinate from(*mercator);
    QQuickPropertyAnimation::setFrom(QVariant::fromValue(from));
}

/*!
    \qmlproperty coordinate CoordinateAnimation::to
    This property holds the coordinate where the animation should end.
*/
QGeoCoordinate QQuickGeoCoordinateAnimation::to() const
{
    Q_D(const QQuickGeoCoordinateAnimation);
    return d->to.value<QGeoCoordinate>();
}

void QQuickGeoCoordinateAnimation::setTo(const QGeoCoordinate &t)
{
    QGeoMercatorCoordinatePrivate *mercator = new QGeoMercatorCoordinatePrivate();
    QDoubleVector2D toVector = QWebMercator::coordToMercator(t);
    mercator->lat = t.latitude();
    mercator->lng = t.longitude();
    mercator->alt = t.altitude();
    mercator->m_mercatorX = toVector.x();
    mercator->m_mercatorY = toVector.y();
    QGeoCoordinate to(*mercator);
    QQuickPropertyAnimation::setTo(QVariant::fromValue(to));
}

/*!
    \qmlproperty enumeration CoordinateAnimation::direction
    This property holds the direction of the \l{longitude} animation of the \l{coordinate}.

    Possible values are:

    \list
    \li CoordinateAnimation.Shortest (default) - the longitude animation goes in the direction
        that produces the shortest animation path.
    \li CoordinateAnimation.West - the longitude animation always goes into western direction
        and may cross the date line.
    \li CoordinateAnimation.East - the longitude animation always goes into eastern direction
        and may cross the date line.
    \endlist
    \since 5.5
*/


QQuickGeoCoordinateAnimation::Direction QQuickGeoCoordinateAnimation::direction() const
{
    Q_D(const QQuickGeoCoordinateAnimation);
    return d->m_direction;
}

void QQuickGeoCoordinateAnimation::setDirection(QQuickGeoCoordinateAnimation::Direction direction)
{
    Q_D( QQuickGeoCoordinateAnimation);
    if (d->m_direction == direction)
        return;

    d->m_direction = direction;
    switch (direction) {
    case West:
        d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(reinterpret_cast<void *>(&q_coordinateWestInterpolator));
        break;
    case East:
        d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(reinterpret_cast<void *>(&q_coordinateEastInterpolator));
        break;
    case Shortest:
    default:
        d->interpolator = reinterpret_cast<QVariantAnimation::Interpolator>(reinterpret_cast<void *>(&q_coordinateShortestInterpolator));
        break;
    }
    emit directionChanged();

}

QQuickGeoCoordinateAnimationPrivate::QQuickGeoCoordinateAnimationPrivate():
    m_direction(QQuickGeoCoordinateAnimation::Shortest)
{
}

QT_END_NAMESPACE
