/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts 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 <private/splineanimation_p.h>
#include <private/splinechartitem_p.h>
#include <QtCore/QDebug>

Q_DECLARE_METATYPE(QVector<QPointF>)
Q_DECLARE_METATYPE(SplineVector)

QT_CHARTS_BEGIN_NAMESPACE

SplineAnimation::SplineAnimation(SplineChartItem *item, int duration, QEasingCurve &curve)
    : XYAnimation(item, duration, curve),
      m_item(item),
      m_valid(false)
{
}

SplineAnimation::~SplineAnimation()
{
}

void SplineAnimation::setup(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints, QVector<QPointF> &oldControlPoints, QVector<QPointF> &newControlPoints, int index)
{
    if (newPoints.count() * 2 - 2 != newControlPoints.count() || newControlPoints.count() < 2) {
        m_valid = false;
        m_dirty = false;
        m_item->setGeometryPoints(newPoints);
        m_item->setControlGeometryPoints(newControlPoints);
        m_item->setDirty(false);
        m_item->updateGeometry();
        return;
    }

    m_type = NewAnimation;

    if (state() != QAbstractAnimation::Stopped) {
        stop();
        m_dirty = false;
    }

    if (!m_dirty) {
        m_dirty = true;
        m_oldSpline.first = oldPoints;
        m_oldSpline.second = oldControlPoints;
    }

    m_newSpline.first = newPoints;
    m_newSpline.second = newControlPoints;


    int x = m_oldSpline.first.count();
    int y = m_newSpline.first.count();

    if (x - y == 1 && index >= 0 && y > 0) {
        //remove point
        if (index > 0) {
            m_newSpline.first.insert(index, newPoints[index - 1]);
            m_newSpline.second.insert((index - 1) * 2, newPoints[index - 1]);
            m_newSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]);
        } else {
            m_newSpline.first.insert(0, newPoints[index]);
            m_newSpline.second.insert(0, newPoints[index]);
            m_newSpline.second.insert(1, newPoints[index]);
        }
        m_index = index;
        m_type = RemovePointAnimation;
    }

    if (x - y == -1 && index >= 0) {
        //add point
        if (index > 0) {
            m_oldSpline.first.insert(index, newPoints[index - 1]);
            m_oldSpline.second.insert((index - 1) * 2, newPoints[index - 1]);
            m_oldSpline.second.insert((index - 1) * 2 + 1, newPoints[index - 1]);
        } else {
            m_oldSpline.first.insert(0, newPoints[index]);
            m_oldSpline.second.insert(0, newPoints[index]);
            m_oldSpline.second.insert(1, newPoints[index]);
        }
        m_index = index;
        m_type = AddPointAnimation;
    }

    x = m_oldSpline.first.count();
    y = m_newSpline.first.count();

    if (x != y) {
        m_type = NewAnimation;
    } else if (m_type == NewAnimation) {
        m_type = ReplacePointAnimation;
    }


    setKeyValueAt(0.0, QVariant::fromValue(m_oldSpline));
    setKeyValueAt(1.0, QVariant::fromValue(m_newSpline));

    m_valid = true;

}

QVariant SplineAnimation::interpolated(const QVariant &start, const QVariant &end, qreal progress) const
{

    SplineVector startPair = qvariant_cast< SplineVector >(start);
    SplineVector endPair = qvariant_cast< SplineVector >(end);
    SplineVector result;

    switch (animationType()) {
    case RemovePointAnimation:
    case AddPointAnimation:
    case ReplacePointAnimation: {
        if (startPair.first.count() != endPair.first.count())
            break;
        Q_ASSERT(startPair.first.count() * 2 - 2 == startPair.second.count());
        Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
        for (int i = 0; i < endPair.first.count(); i++) {
            qreal x = startPair.first[i].x() + ((endPair.first[i].x() - startPair.first[i].x()) * progress);
            qreal y = startPair.first[i].y() + ((endPair.first[i].y() - startPair.first[i].y()) * progress);
            result.first << QPointF(x, y);
            if (i + 1 >= endPair.first.count())
                continue;
            x = startPair.second[i * 2].x() + ((endPair.second[i * 2].x() - startPair.second[i * 2].x()) * progress);
            y = startPair.second[i * 2].y() + ((endPair.second[i * 2].y() - startPair.second[i * 2].y()) * progress);
            result.second << QPointF(x, y);
            x = startPair.second[i * 2 + 1].x() + ((endPair.second[i * 2 + 1].x() - startPair.second[i * 2 + 1].x()) * progress);
            y = startPair.second[i * 2 + 1].y() + ((endPair.second[i * 2 + 1].y() - startPair.second[i * 2 + 1].y()) * progress);
            result.second << QPointF(x, y);
        }
    }
    break;
    case NewAnimation: {
        Q_ASSERT(endPair.first.count() * 2 - 2 == endPair.second.count());
        int count = endPair.first.count() * qBound(qreal(0), progress, qreal(1));
        for (int i = 0; i < count; i++) {
            result.first << endPair.first[i];
            if (i + 1 == count)
                break;
            result.second << endPair.second[2 * i];
            result.second << endPair.second[2 * i + 1];
        }
    }
    break;
    default:
        qWarning() << "Unknown type of animation";
        break;
    }

    return QVariant::fromValue(result);
}

void SplineAnimation::updateCurrentValue(const QVariant &value)
{
    if (state() != QAbstractAnimation::Stopped && m_valid) { //workaround
        QPair<QVector<QPointF >, QVector<QPointF > > pair = qvariant_cast< QPair< QVector<QPointF>, QVector<QPointF> > >(value);
        m_item->setGeometryPoints(pair.first);
        m_item->setControlGeometryPoints(pair.second);
        m_item->updateGeometry();
        m_item->setDirty(true);
        m_dirty = false;
    }
}

void SplineAnimation::updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
{
    XYAnimation::updateState(newState, oldState);

    if (oldState == QAbstractAnimation::Running && newState == QAbstractAnimation::Stopped) {
        if (m_item->isDirty() && m_type == RemovePointAnimation) {
            if (!m_newSpline.first.isEmpty()) {
                if (m_index) {
                    m_newSpline.first.remove(m_index);
                    m_newSpline.second.remove((m_index - 1) * 2);
                    m_newSpline.second.remove((m_index - 1) * 2);
                } else {
                    m_newSpline.first.remove(0);
                    m_newSpline.second.remove(0);
                    m_newSpline.second.remove(0);
                }
            }
            m_item->setGeometryPoints(m_newSpline.first);
            m_item->setControlGeometryPoints(m_newSpline.second);
        }
    }

    if (oldState == QAbstractAnimation::Stopped && newState == QAbstractAnimation::Running) {
        if (!m_valid)
            stop();
    }
}

QT_CHARTS_END_NAMESPACE
