/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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 "splineeditor.h"
#include "segmentproperties.h"

#include <QPainter>
#include <QPainterPath>
#include <QMouseEvent>
#include <QContextMenuEvent>
#include <QDebug>
#include <QApplication>
#include <QVector>
#include <QPainterPath>

const int canvasWidth = 640;
const int canvasHeight = 320;

const int canvasMargin = 160;

SplineEditor::SplineEditor(QWidget *parent) :
    QWidget(parent), m_pointListWidget(nullptr), m_block(false)
{
    setFixedSize(canvasWidth + canvasMargin * 2, canvasHeight + canvasMargin * 2);

    m_controlPoints.append(QPointF(0.4, 0.075));
    m_controlPoints.append(QPointF(0.45,0.24));
    m_controlPoints.append(QPointF(0.5,0.5));

    m_controlPoints.append(QPointF(0.55,0.76));
    m_controlPoints.append(QPointF(0.7,0.9));
    m_controlPoints.append(QPointF(1.0, 1.0));

    m_numberOfSegments = 2;

    m_activeControlPoint = -1;

    m_mouseDrag = false;

    m_pointContextMenu = new QMenu(this);
    m_deleteAction = new QAction(tr("Delete point"), m_pointContextMenu);
    m_smoothAction = new QAction(tr("Smooth point"), m_pointContextMenu);
    m_cornerAction = new QAction(tr("Corner point"), m_pointContextMenu);

    m_smoothAction->setCheckable(true);

    m_pointContextMenu->addAction(m_deleteAction);
    m_pointContextMenu->addAction(m_smoothAction);
    m_pointContextMenu->addAction(m_cornerAction);

    m_curveContextMenu = new QMenu(this);

    m_addPoint = new QAction(tr("Add point"), m_pointContextMenu);

    m_curveContextMenu->addAction(m_addPoint);

    initPresets();

    invalidateSmoothList();
}

static inline QPointF mapToCanvas(const QPointF &point)
{
    return QPointF(point.x() * canvasWidth + canvasMargin,
                   canvasHeight - point.y() * canvasHeight + canvasMargin);
}

static inline QPointF mapFromCanvas(const QPointF &point)
{
    return QPointF((point.x() - canvasMargin) / canvasWidth ,
                   1 - (point.y() - canvasMargin) / canvasHeight);
}

static inline void paintControlPoint(const QPointF &controlPoint, QPainter *painter, bool edit,
                                     bool realPoint, bool active, bool smooth)
{
    int pointSize = 4;

    if (active)
        painter->setBrush(QColor(140, 140, 240, 255));
    else
        painter->setBrush(QColor(120, 120, 220, 255));

    if (realPoint) {
        pointSize = 6;
        painter->setBrush(QColor(80, 80, 210, 150));
    }

    painter->setPen(QColor(50, 50, 50, 140));

    if (!edit)
        painter->setBrush(QColor(160, 80, 80, 250));

    if (smooth) {
        painter->drawEllipse(QRectF(mapToCanvas(controlPoint).x() - pointSize + 0.5,
                                    mapToCanvas(controlPoint).y() - pointSize + 0.5,
                                    pointSize * 2, pointSize * 2));
    } else {
        painter->drawRect(QRectF(mapToCanvas(controlPoint).x() - pointSize + 0.5,
                                 mapToCanvas(controlPoint).y() - pointSize + 0.5,
                                 pointSize * 2, pointSize * 2));
    }
}

static inline bool indexIsRealPoint(int i)
{
    return  !((i + 1) % 3);
}

static inline int pointForControlPoint(int i)
{
    if ((i % 3) == 0)
        return i - 1;

    if ((i % 3) == 1)
        return i + 1;

    return i;
}

void drawCleanLine(QPainter *painter, const QPoint p1, QPoint p2)
{
    painter->drawLine(p1 + QPointF(0.5 , 0.5), p2 + QPointF(0.5, 0.5));
}

void SplineEditor::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    QPen pen(Qt::black);
    pen.setWidth(1);
    painter.fillRect(0,0,width() - 1, height() - 1, QBrush(Qt::white));
    painter.drawRect(0,0,width() - 1, height() - 1);

    painter.setRenderHint(QPainter::Antialiasing);

    pen = QPen(Qt::gray);
    pen.setWidth(1);
    pen.setStyle(Qt::DashLine);
    painter.setPen(pen);
    drawCleanLine(&painter,mapToCanvas(QPoint(0, 0)).toPoint(), mapToCanvas(QPoint(1, 0)).toPoint());
    drawCleanLine(&painter,mapToCanvas(QPoint(0, 1)).toPoint(), mapToCanvas(QPoint(1, 1)).toPoint());

    for (int i = 0; i < m_numberOfSegments; i++) {
        QPainterPath path;
        QPointF p0;

        if (i == 0)
            p0 = mapToCanvas(QPointF(0.0, 0.0));
        else
            p0 = mapToCanvas(m_controlPoints.at(i * 3 - 1));

        path.moveTo(p0);

        QPointF p1 = mapToCanvas(m_controlPoints.at(i * 3));
        QPointF p2 = mapToCanvas(m_controlPoints.at(i * 3 + 1));
        QPointF p3 = mapToCanvas(m_controlPoints.at(i * 3 + 2));
        path.cubicTo(p1, p2, p3);
        painter.strokePath(path, QPen(QBrush(Qt::black), 2));

        QPen pen(Qt::black);
        pen.setWidth(1);
        pen.setStyle(Qt::DashLine);
        painter.setPen(pen);
        painter.drawLine(p0, p1);
        painter.drawLine(p3, p2);
    }

    paintControlPoint(QPointF(0.0, 0.0), &painter, false, true, false, false);
    paintControlPoint(QPointF(1.0, 1.0), &painter, false, true, false, false);

    for (int i = 0; i < m_controlPoints.count() - 1; ++i)
        paintControlPoint(m_controlPoints.at(i),
                          &painter,
                          true,
                          indexIsRealPoint(i),
                          i == m_activeControlPoint,
                          isControlPointSmooth(i));
}

void SplineEditor::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton) {
        m_activeControlPoint = findControlPoint(e->pos());

        if (m_activeControlPoint != -1) {
            mouseMoveEvent(e);
        }
        m_mousePress = e->pos();
        e->accept();
    }
}

void SplineEditor::mouseReleaseEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton) {
        m_activeControlPoint = -1;

        m_mouseDrag = false;
        e->accept();
    }
}

#if QT_CONFIG(contextmenu)
void SplineEditor::contextMenuEvent(QContextMenuEvent *e)
{
    int index = findControlPoint(e->pos());

    if (index > 0 && indexIsRealPoint(index)) {
        m_smoothAction->setChecked(isControlPointSmooth(index));
        QAction* action = m_pointContextMenu->exec(e->globalPos());
        if (action == m_deleteAction)
            deletePoint(index);
        else if (action == m_smoothAction)
            smoothPoint(index);
        else if (action == m_cornerAction)
            cornerPoint(index);
    } else {
        QAction* action = m_curveContextMenu->exec(e->globalPos());
        if (action == m_addPoint)
            addPoint(e->pos());
    }
}
#endif // contextmenu

void SplineEditor::invalidate()
{
    QEasingCurve easingCurve(QEasingCurve::BezierSpline);

    for (int i = 0; i < m_numberOfSegments; ++i) {
        easingCurve.addCubicBezierSegment(m_controlPoints.at(i * 3),
                                          m_controlPoints.at(i * 3 + 1),
                                          m_controlPoints.at(i * 3 + 2));
    }
    setEasingCurve(easingCurve);
    invalidateSegmentProperties();
}

void SplineEditor::invalidateSmoothList()
{
    m_smoothList.clear();

    for (int i = 0; i < (m_numberOfSegments - 1); ++i)
        m_smoothList.append(isSmooth(i * 3 + 2));

}

void SplineEditor::invalidateSegmentProperties()
{
    for (int i = 0; i < m_numberOfSegments; ++i) {
        SegmentProperties *segmentProperties = m_segmentProperties.at(i);
        bool smooth = false;
        if (i < (m_numberOfSegments - 1)) {
            smooth = m_smoothList.at(i);
        }
        segmentProperties->setSegment(i, m_controlPoints.mid(i * 3, 3), smooth, i == (m_numberOfSegments - 1));
    }
}

QHash<QString, QEasingCurve> SplineEditor::presets() const
{
    return m_presets;
}

QString SplineEditor::generateCode()
{
    QString s = QLatin1String("[");
    for (const QPointF &point : qAsConst(m_controlPoints)) {
        s += QString::number(point.x(), 'g', 2) + QLatin1Char(',')
             + QString::number(point.y(), 'g', 3) + QLatin1Char(',');
    }
    s.chop(1); //removing last ","
    s += QLatin1Char(']');

    return s;
}

QStringList SplineEditor::presetNames() const
{
    return m_presets.keys();
}

QWidget *SplineEditor::pointListWidget()
{
    if (!m_pointListWidget) {
        setupPointListWidget();
    }

    return m_pointListWidget;
}

int SplineEditor::findControlPoint(const QPoint &point)
{
    int pointIndex = -1;
    qreal distance = -1;
    for (int i = 0; i<m_controlPoints.size() - 1; ++i) {
        qreal d = QLineF(point, mapToCanvas(m_controlPoints.at(i))).length();
        if ((distance < 0 && d < 10) || d < distance) {
            distance = d;
            pointIndex = i;
        }
    }
    return pointIndex;
}

static inline bool veryFuzzyCompare(qreal r1, qreal r2)
{
    if (qFuzzyCompare(r1, 2))
        return true;

    int r1i = qRound(r1 * 20);
    int r2i = qRound(r2 * 20);

    if (qFuzzyCompare(qreal(r1i) / 20, qreal(r2i) / 20))
        return true;

    return false;
}

bool SplineEditor::isSmooth(int i) const
{
    if (i == 0)
        return false;

    QPointF p = m_controlPoints.at(i);
    QPointF p_before = m_controlPoints.at(i - 1);
    QPointF p_after = m_controlPoints.at(i + 1);

    QPointF v1 = p_after - p;
    v1 = v1 / v1.manhattanLength(); //normalize

    QPointF v2 = p - p_before;
    v2 = v2 / v2.manhattanLength(); //normalize

    return veryFuzzyCompare(v1.x(), v2.x()) && veryFuzzyCompare(v1.y(), v2.y());
}

void SplineEditor::smoothPoint(int index)
{
    if (m_smoothAction->isChecked()) {

        QPointF before = QPointF(0,0);
        if (index > 3)
            before = m_controlPoints.at(index - 3);

        QPointF after = QPointF(1.0, 1.0);
        if ((index + 3) < m_controlPoints.count())
            after = m_controlPoints.at(index + 3);

        QPointF tangent = (after - before) / 6;

        QPointF thisPoint =  m_controlPoints.at(index);

        if (index > 0)
            m_controlPoints[index - 1] = thisPoint - tangent;

        if (index + 1  < m_controlPoints.count())
            m_controlPoints[index + 1] = thisPoint + tangent;

        m_smoothList[index / 3] = true;
    } else {
        m_smoothList[index / 3] = false;
    }
    invalidate();
    update();
}

void SplineEditor::cornerPoint(int index)
{
    QPointF before = QPointF(0,0);
    if (index > 3)
        before = m_controlPoints.at(index - 3);

    QPointF after = QPointF(1.0, 1.0);
    if ((index + 3) < m_controlPoints.count())
        after = m_controlPoints.at(index + 3);

    QPointF thisPoint =  m_controlPoints.at(index);

    if (index > 0)
        m_controlPoints[index - 1] = (before - thisPoint) / 3 + thisPoint;

    if (index + 1  < m_controlPoints.count())
        m_controlPoints[index + 1] = (after - thisPoint) / 3 + thisPoint;

    m_smoothList[(index) / 3] = false;
    invalidate();
}

void SplineEditor::deletePoint(int index)
{
    m_controlPoints.remove(index - 1, 3);
    m_numberOfSegments--;

    invalidateSmoothList();
    setupPointListWidget();
    invalidate();
}

void SplineEditor::addPoint(const QPointF point)
{
    QPointF newPos = mapFromCanvas(point);
    int splitIndex = 0;
    for (int i=0; i < m_controlPoints.size() - 1; ++i) {
        if (indexIsRealPoint(i) && m_controlPoints.at(i).x() > newPos.x()) {
            break;
        } else if (indexIsRealPoint(i))
            splitIndex = i;
    }
    QPointF before = QPointF(0,0);
    if (splitIndex > 0)
        before = m_controlPoints.at(splitIndex);

    QPointF after = QPointF(1.0, 1.0);
    if ((splitIndex + 3) < m_controlPoints.count())
        after = m_controlPoints.at(splitIndex + 3);

    if (splitIndex > 0) {
        m_controlPoints.insert(splitIndex + 2, (newPos + after) / 2);
        m_controlPoints.insert(splitIndex + 2, newPos);
        m_controlPoints.insert(splitIndex + 2, (newPos + before) / 2);
    } else {
        m_controlPoints.insert(splitIndex + 1, (newPos + after) / 2);
        m_controlPoints.insert(splitIndex + 1, newPos);
        m_controlPoints.insert(splitIndex + 1, (newPos + before) / 2);
    }
    m_numberOfSegments++;

    invalidateSmoothList();
    setupPointListWidget();
    invalidate();
}

void SplineEditor::initPresets()
{
    const QPointF endPoint(1.0, 1.0);
    {
        QEasingCurve easingCurve(QEasingCurve::BezierSpline);
        easingCurve.addCubicBezierSegment(QPointF(0.4, 0.075), QPointF(0.45, 0.24), QPointF(0.5, 0.5));
        easingCurve.addCubicBezierSegment(QPointF(0.55, 0.76), QPointF(0.7, 0.9), endPoint);
        m_presets.insert(tr("Standard Easing"), easingCurve);
    }

    {
        QEasingCurve easingCurve(QEasingCurve::BezierSpline);
        easingCurve.addCubicBezierSegment(QPointF(0.43, 0.0025), QPointF(0.65, 1), endPoint);
        m_presets.insert(tr("Simple"), easingCurve);
    }

    {
        QEasingCurve easingCurve(QEasingCurve::BezierSpline);
        easingCurve.addCubicBezierSegment(QPointF(0.43, 0.0025), QPointF(0.38, 0.51), QPointF(0.57, 0.99));
        easingCurve.addCubicBezierSegment(QPointF(0.8, 0.69), QPointF(0.65, 1), endPoint);
        m_presets.insert(tr("Simple Bounce"), easingCurve);
    }

    {
        QEasingCurve easingCurve(QEasingCurve::BezierSpline);
        easingCurve.addCubicBezierSegment(QPointF(0.4, 0.075), QPointF(0.64, -0.0025), QPointF(0.74, 0.23));
        easingCurve.addCubicBezierSegment(QPointF(0.84, 0.46), QPointF(0.91, 0.77), endPoint);
        m_presets.insert(tr("Slow in fast out"), easingCurve);
    }

    {
        QEasingCurve easingCurve(QEasingCurve::BezierSpline);
        easingCurve.addCubicBezierSegment(QPointF(0.43, 0.0025), QPointF(0.47, 0.51), QPointF(0.59, 0.94));
        easingCurve.addCubicBezierSegment(QPointF(0.84, 0.95), QPointF( 0.99, 0.94), endPoint);
        m_presets.insert(tr("Snapping"), easingCurve);
    }

    {
        QEasingCurve easingCurve(QEasingCurve::BezierSpline);
        easingCurve.addCubicBezierSegment(QPointF( 0.38, 0.35),QPointF(0.38, 0.7), QPointF(0.45, 0.99));
        easingCurve.addCubicBezierSegment(QPointF(0.48, 0.66), QPointF(0.62, 0.62), QPointF(0.66, 0.99));
        easingCurve.addCubicBezierSegment(QPointF(0.69, 0.76), QPointF(0.77, 0.76), QPointF(0.79, 0.99));
        easingCurve.addCubicBezierSegment(QPointF(0.83, 0.91), QPointF(0.87, 0.92), QPointF(0.91, 0.99));
        easingCurve.addCubicBezierSegment(QPointF(0.95, 0.95), QPointF(0.97, 0.94), endPoint);
        m_presets.insert(tr("Complex Bounce"), easingCurve);
    }

    {
        QEasingCurve easingCurve4(QEasingCurve::BezierSpline);
        easingCurve4.addCubicBezierSegment(QPointF(0.12, -0.12),QPointF(0.23, -0.19), QPointF( 0.35, -0.09));
        easingCurve4.addCubicBezierSegment(QPointF(0.47, 0.005), QPointF(0.52, 1), QPointF(0.62, 1.1));
        easingCurve4.addCubicBezierSegment(QPointF(0.73, 1.2), QPointF(0.91,1 ), endPoint);
        m_presets.insert(tr("Overshoot"), easingCurve4);
    }
}

void SplineEditor::setupPointListWidget()
{
    if (!m_pointListWidget)
        m_pointListWidget = new QScrollArea(this);

    if (m_pointListWidget->widget())
        delete m_pointListWidget->widget();

    m_pointListWidget->setFrameStyle(QFrame::NoFrame);
    m_pointListWidget->setWidgetResizable(true);
    m_pointListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    m_pointListWidget->setWidget(new QWidget(m_pointListWidget));
    QVBoxLayout *layout = new QVBoxLayout(m_pointListWidget->widget());
    layout->setContentsMargins(QMargins());
    layout->setSpacing(2);
    m_pointListWidget->widget()->setLayout(layout);

    m_segmentProperties.clear();

    { //implicit 0,0
        QWidget *widget = new QWidget(m_pointListWidget->widget());
        Ui_Pane pane;
        pane.setupUi(widget);
        pane.p1_x->setValue(0);
        pane.p1_y->setValue(0);
        layout->addWidget(widget);
        pane.label->setText("p0");
        widget->setEnabled(false);
    }

    for (int i = 0; i < m_numberOfSegments; ++i) {
        SegmentProperties *segmentProperties = new SegmentProperties(m_pointListWidget->widget());
        layout->addWidget(segmentProperties);
        bool smooth = false;
        if (i < (m_numberOfSegments - 1)) {
            smooth = m_smoothList.at(i);
        }
        segmentProperties->setSegment(i, m_controlPoints.mid(i * 3, 3), smooth, i == (m_numberOfSegments - 1));
        segmentProperties->setSplineEditor(this);
        m_segmentProperties << segmentProperties;
    }
    layout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding));

    m_pointListWidget->viewport()->show();
    m_pointListWidget->viewport()->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    m_pointListWidget->show();
}

bool SplineEditor::isControlPointSmooth(int i) const
{
    if (i == 0)
        return false;

    if (i == m_controlPoints.count() - 1)
        return false;

    if (m_numberOfSegments == 1)
        return false;

    int index = pointForControlPoint(i);

    if (index == 0)
        return false;

    if (index == m_controlPoints.count() - 1)
        return false;

    return m_smoothList.at(index / 3);
}

QPointF limitToCanvas(const QPointF point)
{
    qreal left = -qreal( canvasMargin) / qreal(canvasWidth);
    qreal width = 1.0 - 2.0 * left;

    qreal top = -qreal( canvasMargin) / qreal(canvasHeight);
    qreal height = 1.0 - 2.0 * top;

    QPointF p = point;
    QRectF r(left, top, width, height);

    if (p.x() > r.right()) {
        p.setX(r.right());
    }
    if (p.x() < r.left()) {
        p.setX(r.left());
    }
    if (p.y() < r.top()) {
        p.setY(r.top());
    }
    if (p.y() > r.bottom()) {
        p.setY(r.bottom());
    }
    return p;
}

void SplineEditor::mouseMoveEvent(QMouseEvent *e)
{
    // If we've moved more then 25 pixels, assume user is dragging
    if (!m_mouseDrag && QPoint(m_mousePress - e->pos()).manhattanLength() > qApp->startDragDistance())
        m_mouseDrag = true;

    QPointF p = mapFromCanvas(e->pos());

    if (m_mouseDrag && m_activeControlPoint >= 0 && m_activeControlPoint < m_controlPoints.size()) {
        p = limitToCanvas(p);
        if (indexIsRealPoint(m_activeControlPoint)) {
            //move also the tangents
            QPointF targetPoint = p;
            QPointF distance = targetPoint - m_controlPoints.at(m_activeControlPoint);
            m_controlPoints[m_activeControlPoint] = targetPoint;
            m_controlPoints[m_activeControlPoint - 1] += distance;
            m_controlPoints[m_activeControlPoint + 1] += distance;
        } else {
            if (!isControlPointSmooth(m_activeControlPoint)) {
                m_controlPoints[m_activeControlPoint] = p;
            } else {
                QPointF targetPoint = p;
                QPointF distance = targetPoint - m_controlPoints.at(m_activeControlPoint);
                m_controlPoints[m_activeControlPoint] = p;

                if ((m_activeControlPoint > 1) && (m_activeControlPoint % 3) == 0) { //right control point
                    m_controlPoints[m_activeControlPoint - 2] -= distance;
                } else if ((m_activeControlPoint < (m_controlPoints.count() - 2)) //left control point
                           && (m_activeControlPoint % 3) == 1) {
                    m_controlPoints[m_activeControlPoint + 2] -= distance;
                }
            }
        }
        invalidate();
    }
}

void SplineEditor::setEasingCurve(const QEasingCurve &easingCurve)
{
    if (m_easingCurve == easingCurve)
        return;
    m_block = true;
    m_easingCurve = easingCurve;
    m_controlPoints = m_easingCurve.toCubicSpline();
    m_numberOfSegments = m_controlPoints.count() / 3;
    update();
    emit easingCurveChanged();

    const QString code = generateCode();
    emit easingCurveCodeChanged(code);

    m_block = false;
}

void SplineEditor::setPreset(const QString &name)
{
    setEasingCurve(m_presets.value(name));
    invalidateSmoothList();
    setupPointListWidget();
}

void SplineEditor::setEasingCurve(const QString &code)
{
    if (m_block)
        return;
    if (code.startsWith(QLatin1Char('[')) && code.endsWith(QLatin1Char(']'))) {
        const QStringRef cleanCode(&code, 1, code.size() - 2);
        const auto stringList = cleanCode.split(QLatin1Char(','), Qt::SkipEmptyParts);
        if (stringList.count() >= 6 && (stringList.count() % 6 == 0)) {
            QVector<qreal> realList;
            realList.reserve(stringList.count());
            for (const QStringRef &string : stringList) {
                bool ok;
                realList.append(string.toDouble(&ok));
                if (!ok)
                    return;
            }
            QVector<QPointF> points;
            const int count = realList.count() / 2;
            points.reserve(count);
            for (int i = 0; i < count; ++i)
                points.append(QPointF(realList.at(i * 2), realList.at(i * 2 + 1)));
            if (points.constLast() == QPointF(1.0, 1.0)) {
                QEasingCurve easingCurve(QEasingCurve::BezierSpline);

                for (int i = 0; i < points.count() / 3; ++i) {
                    easingCurve.addCubicBezierSegment(points.at(i * 3),
                                                      points.at(i * 3 + 1),
                                                      points.at(i * 3 + 2));
                }
                setEasingCurve(easingCurve);
                invalidateSmoothList();
                setupPointListWidget();
            }
        }
    }
}

#include "moc_splineeditor.cpp"
