/****************************************************************************
**
** 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/linechartitem_p.h>
#include <QtCharts/QLineSeries>
#include <private/qlineseries_p.h>
#include <private/chartpresenter_p.h>
#include <private/polardomain_p.h>
#include <private/chartthememanager_p.h>
#include <private/charttheme_p.h>
#include <QtGui/QPainter>
#include <QtWidgets/QGraphicsSceneMouseEvent>

QT_CHARTS_BEGIN_NAMESPACE

LineChartItem::LineChartItem(QLineSeries *series, QGraphicsItem *item)
    : XYChart(series,item),
      m_series(series),
      m_pointsVisible(false),
      m_chartType(QChart::ChartTypeUndefined),
      m_pointLabelsVisible(false),
      m_pointLabelsFormat(series->pointLabelsFormat()),
      m_pointLabelsFont(series->pointLabelsFont()),
      m_pointLabelsColor(series->pointLabelsColor()),
      m_pointLabelsClipping(true),
      m_mousePressed(false)
{
    setAcceptHoverEvents(true);
    setFlag(QGraphicsItem::ItemIsSelectable);
    setZValue(ChartPresenter::LineChartZValue);
    QObject::connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(opacityChanged()), this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(pointLabelsFormatChanged(QString)),
                     this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(pointLabelsVisibilityChanged(bool)),
                     this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(pointLabelsFontChanged(QFont)), this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(pointLabelsColorChanged(QColor)), this, SLOT(handleUpdated()));
    QObject::connect(series, SIGNAL(pointLabelsClippingChanged(bool)), this, SLOT(handleUpdated()));
    handleUpdated();
}

QRectF LineChartItem::boundingRect() const
{
    return m_rect;
}

QPainterPath LineChartItem::shape() const
{
    return m_shapePath;
}

void LineChartItem::updateGeometry()
{
    if (m_series->useOpenGL()) {
        if (!m_rect.isEmpty()) {
            prepareGeometryChange();
            // Changed signal seems to trigger even with empty region
            m_rect = QRectF();
        }
        update();
        return;
    }

    // Store the points to a local variable so that the old line gets properly cleared
    // when animation starts.
    m_linePoints = geometryPoints();
    const QVector<QPointF> &points = m_linePoints;

    if (points.size() == 0) {
        prepareGeometryChange();
        m_fullPath = QPainterPath();
        m_linePath = QPainterPath();
        m_rect = QRect();
        return;
    }

    QPainterPath linePath;
    QPainterPath fullPath;
    // Use worst case scenario to determine required margin.
    qreal margin = m_linePen.width() * 1.42;

    // Area series use component line series that aren't necessarily added to the chart themselves,
    // so check if chart type is forced before trying to obtain it from the chart.
    QChart::ChartType chartType = m_chartType;
    if (chartType == QChart::ChartTypeUndefined)
        chartType = m_series->chart()->chartType();

    // For polar charts, we need special handling for angular (horizontal)
    // points that are off-grid.
    if (chartType == QChart::ChartTypePolar) {
        QPainterPath linePathLeft;
        QPainterPath linePathRight;
        QPainterPath *currentSegmentPath = 0;
        QPainterPath *previousSegmentPath = 0;
        qreal minX = domain()->minX();
        qreal maxX = domain()->maxX();
        qreal minY = domain()->minY();
        QPointF currentSeriesPoint = m_series->at(0);
        QPointF currentGeometryPoint = points.at(0);
        QPointF previousGeometryPoint = points.at(0);
        int size = m_linePen.width();
        bool pointOffGrid = false;
        bool previousPointWasOffGrid = (currentSeriesPoint.x() < minX || currentSeriesPoint.x() > maxX);

        qreal domainRadius = domain()->size().height() / 2.0;
        const QPointF centerPoint(domainRadius, domainRadius);

        if (!previousPointWasOffGrid) {
            fullPath.moveTo(points.at(0));
            if (m_pointsVisible && currentSeriesPoint.y() >= minY) {
                // Do not draw ellipses for points below minimum Y.
                linePath.addEllipse(points.at(0), size, size);
                fullPath.addEllipse(points.at(0), size, size);
                linePath.moveTo(points.at(0));
                fullPath.moveTo(points.at(0));
            }
        }

        qreal leftMarginLine = centerPoint.x() - margin;
        qreal rightMarginLine = centerPoint.x() + margin;
        qreal horizontal = centerPoint.y();

        // See ScatterChartItem::updateGeometry() for explanation why seriesLastIndex is needed
        const int seriesLastIndex = m_series->count() - 1;

        for (int i = 1; i < points.size(); i++) {
            // Interpolating line fragments would be ugly when thick pen is used,
            // so we work around it by utilizing three separate
            // paths for line segments and clip those with custom regions at paint time.
            // "Right" path contains segments that cross the axis line with visible point on the
            // right side of the axis line, as well as segments that have one point within the margin
            // on the right side of the axis line and another point on the right side of the chart.
            // "Left" path contains points with similarly on the left side.
            // "Full" path contains rest of the points.
            // This doesn't yield perfect results always. E.g. when segment covers more than 90
            // degrees and both of the points are within the margin, one in the top half and one in the
            // bottom half of the chart, the bottom one gets clipped incorrectly.
            // However, this should be rare occurrence in any sensible chart.
            currentSeriesPoint = m_series->at(qMin(seriesLastIndex, i));
            currentGeometryPoint = points.at(i);
            pointOffGrid = (currentSeriesPoint.x() < minX || currentSeriesPoint.x() > maxX);

            // Draw something unless both off-grid
            if (!pointOffGrid || !previousPointWasOffGrid) {
                QPointF intersectionPoint;
                qreal y;
                if (pointOffGrid != previousPointWasOffGrid) {
                    if (currentGeometryPoint.x() == previousGeometryPoint.x()) {
                        y = currentGeometryPoint.y() + (currentGeometryPoint.y() - previousGeometryPoint.y()) / 2.0;
                    } else {
                        qreal ratio = (centerPoint.x() - currentGeometryPoint.x()) / (currentGeometryPoint.x() - previousGeometryPoint.x());
                        y = currentGeometryPoint.y() + (currentGeometryPoint.y() - previousGeometryPoint.y()) * ratio;
                    }
                    intersectionPoint = QPointF(centerPoint.x(), y);
                }

                bool dummyOk; // We know points are ok, but this is needed
                qreal currentAngle = 0;
                qreal previousAngle = 0;
                if (const PolarDomain *pd = qobject_cast<const PolarDomain *>(domain())) {
                    currentAngle = pd->toAngularCoordinate(currentSeriesPoint.x(), dummyOk);
                    previousAngle = pd->toAngularCoordinate(m_series->at(i - 1).x(), dummyOk);
                } else {
                    qWarning() << Q_FUNC_INFO << "Unexpected domain: " << domain();
                }
                if ((qAbs(currentAngle - previousAngle) > 180.0)) {
                    // If the angle between two points is over 180 degrees (half X range),
                    // any direct segment between them becomes meaningless.
                    // In this case two line segments are drawn instead, from previous
                    // point to the center and from center to current point.
                    if ((previousAngle < 0.0 || (previousAngle <= 180.0 && previousGeometryPoint.x() < rightMarginLine))
                        && previousGeometryPoint.y() < horizontal) {
                        currentSegmentPath = &linePathRight;
                    } else if ((previousAngle > 360.0 || (previousAngle > 180.0 && previousGeometryPoint.x() > leftMarginLine))
                                && previousGeometryPoint.y() < horizontal) {
                        currentSegmentPath = &linePathLeft;
                    } else if (previousAngle > 0.0 && previousAngle < 360.0) {
                        currentSegmentPath = &linePath;
                    } else {
                        currentSegmentPath = 0;
                    }

                    if (currentSegmentPath) {
                        if (previousSegmentPath != currentSegmentPath)
                            currentSegmentPath->moveTo(previousGeometryPoint);
                        if (previousPointWasOffGrid)
                            fullPath.moveTo(intersectionPoint);

                        currentSegmentPath->lineTo(centerPoint);
                        fullPath.lineTo(centerPoint);
                    }

                    previousSegmentPath = currentSegmentPath;

                    if ((currentAngle < 0.0 || (currentAngle <= 180.0 && currentGeometryPoint.x() < rightMarginLine))
                        && currentGeometryPoint.y() < horizontal) {
                        currentSegmentPath = &linePathRight;
                    } else if ((currentAngle > 360.0 || (currentAngle > 180.0 &&currentGeometryPoint.x() > leftMarginLine))
                                && currentGeometryPoint.y() < horizontal) {
                        currentSegmentPath = &linePathLeft;
                    } else if (currentAngle > 0.0 && currentAngle < 360.0) {
                        currentSegmentPath = &linePath;
                    } else {
                        currentSegmentPath = 0;
                    }

                    if (currentSegmentPath) {
                        if (previousSegmentPath != currentSegmentPath)
                            currentSegmentPath->moveTo(centerPoint);
                        if (!previousSegmentPath)
                            fullPath.moveTo(centerPoint);

                        currentSegmentPath->lineTo(currentGeometryPoint);
                        if (pointOffGrid)
                            fullPath.lineTo(intersectionPoint);
                        else
                            fullPath.lineTo(currentGeometryPoint);
                    }
                } else {
                    if (previousAngle < 0.0 || currentAngle < 0.0
                        || ((previousAngle <= 180.0 && currentAngle <= 180.0)
                            && ((previousGeometryPoint.x() < rightMarginLine && previousGeometryPoint.y() < horizontal)
                                || (currentGeometryPoint.x() < rightMarginLine && currentGeometryPoint.y() < horizontal)))) {
                        currentSegmentPath = &linePathRight;
                    } else if (previousAngle > 360.0 || currentAngle > 360.0
                               || ((previousAngle > 180.0 && currentAngle > 180.0)
                                   && ((previousGeometryPoint.x() > leftMarginLine && previousGeometryPoint.y() < horizontal)
                                       || (currentGeometryPoint.x() > leftMarginLine && currentGeometryPoint.y() < horizontal)))) {
                        currentSegmentPath = &linePathLeft;
                    } else {
                        currentSegmentPath = &linePath;
                    }

                    if (currentSegmentPath != previousSegmentPath)
                        currentSegmentPath->moveTo(previousGeometryPoint);
                    if (previousPointWasOffGrid)
                        fullPath.moveTo(intersectionPoint);

                    if (pointOffGrid)
                        fullPath.lineTo(intersectionPoint);
                    else
                        fullPath.lineTo(currentGeometryPoint);
                    currentSegmentPath->lineTo(currentGeometryPoint);
                }
            } else {
                currentSegmentPath = 0;
            }

            previousPointWasOffGrid = pointOffGrid;
            if (m_pointsVisible && !pointOffGrid && currentSeriesPoint.y() >= minY) {
                linePath.addEllipse(points.at(i), size, size);
                fullPath.addEllipse(points.at(i), size, size);
                linePath.moveTo(points.at(i));
                fullPath.moveTo(points.at(i));
            }
            previousSegmentPath = currentSegmentPath;
            previousGeometryPoint = currentGeometryPoint;
        }
        m_linePathPolarRight = linePathRight;
        m_linePathPolarLeft = linePathLeft;
        // Note: This construction of m_fullpath is not perfect. The partial segments that are
        // outside left/right clip regions at axis boundary still generate hover/click events,
        // because shape doesn't get clipped. It doesn't seem possible to do sensibly.
    } else { // not polar
        linePath.moveTo(points.at(0));
        for (int i = 1; i < points.size(); i++)
            linePath.lineTo(points.at(i));
        fullPath = linePath;
    }

    QPainterPathStroker stroker;
    // QPainter::drawLine does not respect join styles, for example BevelJoin becomes MiterJoin.
    // This is why we are prepared for the "worst case" scenario, i.e. use always MiterJoin and
    // multiply line width with square root of two when defining shape and bounding rectangle.
    stroker.setWidth(margin);
    stroker.setJoinStyle(Qt::MiterJoin);
    stroker.setCapStyle(Qt::SquareCap);
    stroker.setMiterLimit(m_linePen.miterLimit());

    QPainterPath checkShapePath = stroker.createStroke(fullPath);

    // Only zoom in if the bounding rects of the paths fit inside int limits. QWidget::update() uses
    // a region that has to be compatible with QRect.
    if (checkShapePath.boundingRect().height() <= INT_MAX
            && checkShapePath.boundingRect().width() <= INT_MAX
            && linePath.boundingRect().height() <= INT_MAX
            && linePath.boundingRect().width() <= INT_MAX
            && fullPath.boundingRect().height() <= INT_MAX
            && fullPath.boundingRect().width() <= INT_MAX) {
        prepareGeometryChange();

        m_linePath = linePath;
        m_fullPath = fullPath;
        m_shapePath = checkShapePath;

        m_rect = m_shapePath.boundingRect();
    } else {
        update();
    }
}

void LineChartItem::handleUpdated()
{
    // If points visibility has changed, a geometry update is needed.
    // Also, if pen changes when points are visible, geometry update is needed.
    bool doGeometryUpdate =
        (m_pointsVisible != m_series->pointsVisible())
        || (m_series->pointsVisible() && (m_linePen != m_series->pen()));
    bool visibleChanged = m_series->isVisible() != isVisible();
    setVisible(m_series->isVisible());
    setOpacity(m_series->opacity());
    m_pointsVisible = m_series->pointsVisible();
    m_linePen = m_series->pen();
    m_pointLabelsFormat = m_series->pointLabelsFormat();
    m_pointLabelsVisible = m_series->pointLabelsVisible();
    m_pointLabelsFont = m_series->pointLabelsFont();
    m_pointLabelsColor = m_series->pointLabelsColor();
    bool labelClippingChanged = m_pointLabelsClipping != m_series->pointLabelsClipping();
    m_pointLabelsClipping = m_series->pointLabelsClipping();
    if (doGeometryUpdate)
        updateGeometry();
    else if (m_series->useOpenGL() && visibleChanged)
        refreshGlChart();

    // Update whole chart in case label clipping changed as labels can be outside series area
    if (labelClippingChanged)
        m_series->chart()->update();
    else
        update();
}

void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget)
    Q_UNUSED(option)

    if (m_series->useOpenGL())
        return;

    QRectF clipRect = QRectF(QPointF(0, 0), domain()->size());
    // Adjust clip rect half a pixel in required dimensions to make it include lines along the
    // plot area edges, but never increase clip so much that any portion of the line is draw beyond
    // the plot area.
    const qreal x1 = pos().x() - int(pos().x());
    const qreal y1 = pos().y() - int(pos().y());
    const qreal x2 = (clipRect.width() + 0.5) - int(clipRect.width() + 0.5);
    const qreal y2 = (clipRect.height() + 0.5) - int(clipRect.height() + 0.5);
    clipRect.adjust(-x1, -y1, qMax(x1, x2), qMax(y1, y2));

    painter->save();
    painter->setPen(m_linePen);
    bool alwaysUsePath = false;

    if (m_series->chart()->chartType() == QChart::ChartTypePolar) {
        qreal halfWidth = domain()->size().width() / 2.0;
        QRectF clipRectLeft = QRectF(0, 0, halfWidth, domain()->size().height());
        QRectF clipRectRight = QRectF(halfWidth, 0, halfWidth, domain()->size().height());
        QRegion fullPolarClipRegion(clipRect.toRect(), QRegion::Ellipse);
        QRegion clipRegionLeft(fullPolarClipRegion.intersected(clipRectLeft.toRect()));
        QRegion clipRegionRight(fullPolarClipRegion.intersected(clipRectRight.toRect()));
        painter->setClipRegion(clipRegionLeft);
        painter->drawPath(m_linePathPolarLeft);
        painter->setClipRegion(clipRegionRight);
        painter->drawPath(m_linePathPolarRight);
        painter->setClipRegion(fullPolarClipRegion);
        alwaysUsePath = true; // required for proper clipping
    } else {
        painter->setClipRect(clipRect);
    }

    if (m_linePen.style() != Qt::SolidLine || alwaysUsePath) {
        // If pen style is not solid line, use path painting to ensure proper pattern continuity
        painter->drawPath(m_linePath);
    } else {
        for (int i = 1; i < m_linePoints.size(); ++i)
            painter->drawLine(m_linePoints.at(i - 1), m_linePoints.at(i));
    }

    if (m_pointLabelsVisible) {
        if (m_pointLabelsClipping)
            painter->setClipping(true);
        else
            painter->setClipping(false);
        m_series->d_func()->drawSeriesPointLabels(painter, m_linePoints, m_linePen.width() / 2);
    }

    painter->restore();

    if (m_pointsVisible) {
        // draw points that lie inside clipRect only
        qreal ptSize = m_linePen.width() * 1.5;
        painter->setPen(Qt::NoPen);
        painter->setBrush(m_linePen.color());
        for (int i = 0; i < m_linePoints.size(); ++i) {
            if (clipRect.contains(m_linePoints.at(i)))
                painter->drawEllipse(m_linePoints.at(i), ptSize, ptSize);
        }
    }
}

void LineChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    emit XYChart::pressed(domain()->calculateDomainPoint(event->pos()));
    m_lastMousePos = event->pos();
    m_mousePressed = true;
    QGraphicsItem::mousePressEvent(event);
}

void LineChartItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), true);
//    event->accept();
    QGraphicsItem::hoverEnterEvent(event);
}

void LineChartItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    emit XYChart::hovered(domain()->calculateDomainPoint(event->pos()), false);
//    event->accept();
    QGraphicsItem::hoverEnterEvent(event);
}

void LineChartItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    emit XYChart::released(domain()->calculateDomainPoint(m_lastMousePos));
    if (m_mousePressed)
        emit XYChart::clicked(domain()->calculateDomainPoint(m_lastMousePos));
    m_mousePressed = false;
    QGraphicsItem::mouseReleaseEvent(event);
}

void LineChartItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    emit XYChart::doubleClicked(domain()->calculateDomainPoint(m_lastMousePos));
    QGraphicsItem::mouseDoubleClickEvent(event);
}

QT_CHARTS_END_NAMESPACE

#include "moc_linechartitem_p.cpp"
