/****************************************************************************
**
** 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 <QtCharts/qabstractaxis.h>
#include <QtCharts/qlogvalueaxis.h>
#include <QtCharts/qvalueaxis.h>
#include <QtCore/qmath.h>
#include <QtGui/qtextdocument.h>
#include <QtWidgets/qgraphicslayout.h>
#include <private/abstractchartlayout_p.h>
#include <private/abstractdomain_p.h>
#include <private/cartesianchartaxis_p.h>
#include <private/chartpresenter_p.h>
#include <private/linearrowitem_p.h>
#include <private/qabstractaxis_p.h>

QT_CHARTS_BEGIN_NAMESPACE

CartesianChartAxis::CartesianChartAxis(QAbstractAxis *axis, QGraphicsItem *item , bool intervalAxis)
    : ChartAxisElement(axis, item, intervalAxis)
{
    Q_ASSERT(item);
}


CartesianChartAxis::~CartesianChartAxis()
{
}

void CartesianChartAxis::createItems(int count)
{
    if (arrowItems().size() == 0) {
        QGraphicsLineItem *arrow = new LineArrowItem(this, this);
        arrow->setPen(axis()->linePen());
        arrowGroup()->addToGroup(arrow);
    }

    if (intervalAxis() && gridItems().size() == 0) {
        for (int i = 0 ; i < 2 ; i  ++){
            QGraphicsLineItem *item = new QGraphicsLineItem(this);
            item->setPen(axis()->gridLinePen());
            gridGroup()->addToGroup(item);
            QGraphicsRectItem *shades = new QGraphicsRectItem(this);
            shades->setPen(axis()->shadesPen());
            shades->setBrush(axis()->shadesBrush());
            shadeGroup()->addToGroup(shades);
        }
    }

    QGraphicsTextItem *title = titleItem();
    title->setFont(axis()->titleFont());
    title->setDefaultTextColor(axis()->titleBrush().color());
    title->setHtml(axis()->titleText());

    for (int i = 0; i < count; ++i) {
        QGraphicsLineItem *arrow = new QGraphicsLineItem(this);
        QGraphicsLineItem *grid = new QGraphicsLineItem(this);
        QGraphicsTextItem *label;
        if (axis()->type() == QtCharts::QAbstractAxis::AxisTypeValue) {
            label = new ValueAxisLabel(this);
            connect(static_cast<ValueAxisLabel *>(label), &ValueAxisLabel::valueChanged,
                    this, &ChartAxisElement::valueLabelEdited);
            if (labelsEditable())
                static_cast<ValueAxisLabel *>(label)->setEditable(true);
        } else if (axis()->type() == QtCharts::QAbstractAxis::AxisTypeDateTime) {
            DateTimeAxisLabel *dateTimeLabel = new DateTimeAxisLabel(this);
            label = dateTimeLabel;
            connect(dateTimeLabel, &DateTimeAxisLabel::dateTimeChanged,
                    this, &ChartAxisElement::dateTimeLabelEdited);
            if (labelsEditable())
                dateTimeLabel->setEditable(true);
            dateTimeLabel->setFormat(static_cast<QDateTimeAxis*>(axis())->format());
        } else {
            label = new QGraphicsTextItem(this);
        }

        label->document()->setDocumentMargin(ChartPresenter::textMargin());
        arrow->setPen(axis()->linePen());
        grid->setPen(axis()->gridLinePen());
        label->setFont(axis()->labelsFont());
        label->setDefaultTextColor(axis()->labelsBrush().color());
        label->setRotation(axis()->labelsAngle());
        arrowGroup()->addToGroup(arrow);
        gridGroup()->addToGroup(grid);
        labelGroup()->addToGroup(label);

        if (gridItems().size() == 1 || (((gridItems().size() + 1) % 2) && gridItems().size() > 0)) {
            QGraphicsRectItem *shades = new QGraphicsRectItem(this);
            shades->setPen(axis()->shadesPen());
            shades->setBrush(axis()->shadesBrush());
            shadeGroup()->addToGroup(shades);
        }
    }
}

void CartesianChartAxis::updateMinorTickItems()
{
    int currentCount = minorArrowItems().size();
    int expectedCount = 0;
    if (axis()->type() == QAbstractAxis::AxisTypeValue) {
        QValueAxis *valueAxis = qobject_cast<QValueAxis *>(axis());
        if (valueAxis->tickType() == QValueAxis::TicksFixed) {
            expectedCount = valueAxis->minorTickCount() * (valueAxis->tickCount() - 1);
            expectedCount = qMax(expectedCount, 0);
        } else {
            const qreal interval = valueAxis->tickInterval();
            qreal firstMajorTick = valueAxis->tickAnchor();
            const qreal max = valueAxis->max();
            const qreal min = valueAxis->min();
            const int _minorTickCount = valueAxis->minorTickCount();

            if (min < firstMajorTick)
                firstMajorTick = firstMajorTick - qCeil((firstMajorTick - min) / interval) * interval;
            else
                firstMajorTick = firstMajorTick + int((min - firstMajorTick) / interval) * interval;

            const qreal deltaMinor = interval / qreal(_minorTickCount + 1);
            qreal minorTick = firstMajorTick + deltaMinor;
            int minorCounter = 0;

            while (minorTick < min) {
                minorTick += deltaMinor;
                minorCounter++;
            }

            QVector<qreal> points;

            // Calculate the points on axis value space. Conversion to graphical points
            // will be done on axis specific geometry update function
            while (minorTick <= max || qFuzzyCompare(minorTick, max)) {
                if (minorCounter < _minorTickCount) {
                    expectedCount++;
                    minorCounter++;
                    points << (minorTick - min);
                } else {
                    minorCounter = 0;
                }
                minorTick += deltaMinor;
            }

            setDynamicMinorTickLayout(points);
        }
    } else if (axis()->type() == QAbstractAxis::AxisTypeLogValue) {
        QLogValueAxis *logValueAxis = qobject_cast<QLogValueAxis *>(axis());

        int minorTickCount = logValueAxis->minorTickCount();
        if (minorTickCount < 0)
            minorTickCount = qMax(int(qFloor(logValueAxis->base()) - 2.0), 0);

        expectedCount = minorTickCount * (logValueAxis->tickCount() + 1);
        expectedCount = qMax(expectedCount, logValueAxis->minorTickCount());
    } else {
        // minor ticks are not supported
        return;
    }

    int diff = expectedCount - currentCount;
    if (diff > 0) {
        for (int i = 0; i < diff; ++i) {
            QGraphicsLineItem *minorGridLineItem = new QGraphicsLineItem(this);
            minorGridLineItem->setPen(axis()->minorGridLinePen());
            minorGridGroup()->addToGroup(minorGridLineItem);

            QGraphicsLineItem *minorArrowLineItem = new QGraphicsLineItem(this);
            minorArrowLineItem->setPen(axis()->linePen());
            minorArrowGroup()->addToGroup(minorArrowLineItem);
        }
    } else {
        QList<QGraphicsItem *> minorGridItemsList = minorGridItems();
        QList<QGraphicsItem *> minorArrowItemsList = minorArrowItems();
        for (int i = 0; i > diff; --i) {
            if (!minorGridItemsList.isEmpty())
                delete minorGridItemsList.takeLast();

            if (!minorArrowItemsList.isEmpty())
                delete minorArrowItemsList.takeLast();
        }
    }
}

void CartesianChartAxis::deleteItems(int count)
{
    QList<QGraphicsItem *> lines = gridItems();
    QList<QGraphicsItem *> labels = labelItems();
    QList<QGraphicsItem *> shades = shadeItems();
    QList<QGraphicsItem *> axis = arrowItems();

    for (int i = 0; i < count; ++i) {
        if (lines.size() == 1 || (((lines.size() + 1) % 2) && lines.size() > 0))
            delete(shades.takeLast());
        delete(lines.takeLast());
        delete(labels.takeLast());
        delete(axis.takeLast());
    }
}

void CartesianChartAxis::updateLayout(QVector<qreal> &layout)
{
    int diff = ChartAxisElement::layout().size() - layout.size();

    if (diff > 0)
        deleteItems(diff);
    else if (diff <= 0)
        createItems(-diff);

    updateMinorTickItems();

    if (animation()) {
        switch (presenter()->state()) {
        case ChartPresenter::ZoomInState:
            animation()->setAnimationType(AxisAnimation::ZoomInAnimation);
            animation()->setAnimationPoint(presenter()->statePoint());
            break;
        case ChartPresenter::ZoomOutState:
            animation()->setAnimationType(AxisAnimation::ZoomOutAnimation);
            animation()->setAnimationPoint(presenter()->statePoint());
            break;
        case ChartPresenter::ScrollUpState:
        case ChartPresenter::ScrollLeftState:
            animation()->setAnimationType(AxisAnimation::MoveBackwordAnimation);
            break;
        case ChartPresenter::ScrollDownState:
        case ChartPresenter::ScrollRightState:
            animation()->setAnimationType(AxisAnimation::MoveForwardAnimation);
            break;
        case ChartPresenter::ShowState:
            animation()->setAnimationType(AxisAnimation::DefaultAnimation);
            break;
        }
        animation()->setValues(ChartAxisElement::layout(), layout);
        presenter()->startAnimation(animation());
    } else {
        setLayout(layout);
        updateGeometry();
    }
}

bool CartesianChartAxis::isEmpty()
{
    return axisGeometry().isEmpty()
           || gridGeometry().isEmpty()
           || qFuzzyCompare(min(), max());
}

void CartesianChartAxis::setGeometry(const QRectF &axis, const QRectF &grid)
{
    m_gridRect = grid;
    setAxisGeometry(axis);

    if (isEmpty()) {
        prepareGeometryChange();
        return;
    }

    QVector<qreal> layout = calculateLayout();
    updateLayout(layout);
}

QSizeF CartesianChartAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
    Q_UNUSED(which);
    Q_UNUSED(constraint);
    return QSizeF();
}

void CartesianChartAxis::setDateTimeLabelsFormat(const QString &format)
{
    if (max() <= min()
            || layout().size() < 1
            || axis()->type() != QAbstractAxis::AxisTypeDateTime) {
        return;
    }

    for (int i = 0; i < layout().size(); i++)
        static_cast<DateTimeAxisLabel *>(labelItems().at(i))->setFormat(format);
}

void CartesianChartAxis::handleArrowPenChanged(const QPen &pen)
{
    foreach (QGraphicsItem *item, arrowItems())
        static_cast<QGraphicsLineItem *>(item)->setPen(pen);
}

void CartesianChartAxis::handleGridPenChanged(const QPen &pen)
{
    foreach (QGraphicsItem *item, gridItems())
        static_cast<QGraphicsLineItem *>(item)->setPen(pen);
}

void CartesianChartAxis::handleMinorArrowPenChanged(const QPen &pen)
{
    foreach (QGraphicsItem *item, minorArrowItems())
        static_cast<QGraphicsLineItem *>(item)->setPen(pen);
}

void CartesianChartAxis::handleMinorGridPenChanged(const QPen &pen)
{
    foreach (QGraphicsItem *item, minorGridItems())
        static_cast<QGraphicsLineItem *>(item)->setPen(pen);
}

void CartesianChartAxis::handleGridLineColorChanged(const QColor &color)
{
    foreach (QGraphicsItem *item, gridItems()) {
        QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem *>(item);
        QPen pen = lineItem->pen();
        pen.setColor(color);
        lineItem->setPen(pen);
    }
}

void CartesianChartAxis::handleMinorGridLineColorChanged(const QColor &color)
{
    foreach (QGraphicsItem *item, minorGridItems()) {
        QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem *>(item);
        QPen pen = lineItem->pen();
        pen.setColor(color);
        lineItem->setPen(pen);
    }
}

void CartesianChartAxis::handleShadesBrushChanged(const QBrush &brush)
{
    foreach (QGraphicsItem *item, shadeItems())
        static_cast<QGraphicsRectItem *>(item)->setBrush(brush);
}

void CartesianChartAxis::handleShadesPenChanged(const QPen &pen)
{
    foreach (QGraphicsItem *item, shadeItems())
        static_cast<QGraphicsRectItem *>(item)->setPen(pen);
}

void CartesianChartAxis::updateLabelsValues(QValueAxis *axis)
{
    const QVector<qreal> &layout = ChartAxisElement::layout();
    if (layout.isEmpty())
        return;

    if (axis->tickType() == QValueAxis::TicksFixed) {
        for (int i = 0; i < layout.size(); ++i) {
            qreal value = axis->isReverse()
                    ? min() + ((layout.size() - 1 - i) * (max() - min()) / (layout.size() - 1))
                    : min() + (i * (max() - min()) / (layout.size() - 1));
            static_cast<ValueAxisLabel *>(labelItems().at(i))->setValue(value);
        }
    } else {
        qreal value = axis->tickAnchor();
        if (value > min())
            value = value - int((value - min()) / axis->tickInterval()) * axis->tickInterval();
        else
            value = value + qCeil((min() - value) / axis->tickInterval()) * axis->tickInterval();

        int i = axis->isReverse() ? labelItems().count()-1 : 0;
        while (value <= max() || qFuzzyCompare(value, max())) {
            static_cast<ValueAxisLabel *>(labelItems().at(i))->setValue(value);
            value += axis->tickInterval();
            i += axis->isReverse() ? -1 : 1;
        }
    }
}

void CartesianChartAxis::updateLabelsDateTimes()
{
    if (max() <= min() || layout().size() < 1)
        return;

    for (int i = 0; i < layout().size(); i++) {
        qreal value = min() + (i * (max() - min()) / (layout().size() - 1));
        static_cast<DateTimeAxisLabel *>(labelItems().at(i))->setValue(
                    QDateTime::fromMSecsSinceEpoch(value));
    }
}

QT_CHARTS_END_NAMESPACE

#include "moc_cartesianchartaxis_p.cpp"
