/****************************************************************************
**
** 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/chartaxiselement_p.h>
#include <private/qabstractaxis_p.h>
#include <private/chartpresenter_p.h>
#include <private/abstractchartlayout_p.h>
#include <QtCharts/QCategoryAxis>
#include <QtCore/QtMath>
#include <QtCore/QDateTime>
#include <QtCore/QRegularExpression>
#include <QtGui/QTextDocument>
#include <cmath>

QT_CHARTS_BEGIN_NAMESPACE

static const char *labelFormatMatchString = "%[\\-\\+#\\s\\d\\.\\'lhjztL]*([dicuoxfegXFEG])";
static const char *labelFormatMatchLocalizedString = "^([^%]*)%\\.(\\d+)([defgiEG])(.*)$";
static QRegularExpression *labelFormatMatcher = 0;
static QRegularExpression *labelFormatMatcherLocalized = 0;
class StaticLabelFormatMatcherDeleter
{
public:
    StaticLabelFormatMatcherDeleter() {}
    ~StaticLabelFormatMatcherDeleter() {
        delete labelFormatMatcher;
        delete labelFormatMatcherLocalized;
    }
};
static StaticLabelFormatMatcherDeleter staticLabelFormatMatcherDeleter;

ChartAxisElement::ChartAxisElement(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
    : ChartElement(item),
      m_axis(axis),
      m_animation(0),
      m_grid(new QGraphicsItemGroup(item)),
      m_arrow(new QGraphicsItemGroup(item)),
      m_minorGrid(new QGraphicsItemGroup(item)),
      m_minorArrow(new QGraphicsItemGroup(item)),
      m_shades(new QGraphicsItemGroup(item)),
      m_labels(new QGraphicsItemGroup(item)),
      m_title(new QGraphicsTextItem(item)),
      m_intervalAxis(intervalAxis)

{
    //initial initialization
    m_arrow->setHandlesChildEvents(false);
    m_arrow->setZValue(ChartPresenter::AxisZValue);
    m_minorArrow->setHandlesChildEvents(false);
    m_minorArrow->setZValue(ChartPresenter::AxisZValue);
    m_labels->setZValue(ChartPresenter::AxisZValue);
    m_shades->setZValue(ChartPresenter::ShadesZValue);
    m_grid->setZValue(ChartPresenter::GridZValue);
    m_minorGrid->setZValue(ChartPresenter::GridZValue);
    m_title->setZValue(ChartPresenter::GridZValue);
    m_title->document()->setDocumentMargin(ChartPresenter::textMargin());
    handleVisibleChanged(axis->isVisible());
    connectSlots();

    setFlag(QGraphicsItem::ItemHasNoContents, true);
}

ChartAxisElement::~ChartAxisElement()
{
}

void ChartAxisElement::connectSlots()
{
    QObject::connect(axis(), SIGNAL(visibleChanged(bool)), this, SLOT(handleVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)), this, SLOT(handleArrowVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(gridVisibleChanged(bool)), this, SLOT(handleGridVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(labelsVisibleChanged(bool)), this, SLOT(handleLabelsVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(shadesVisibleChanged(bool)), this, SLOT(handleShadesVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(labelsAngleChanged(int)), this, SLOT(handleLabelsAngleChanged(int)));
    QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this, SLOT(handleArrowPenChanged(const QPen&)));
    QObject::connect(axis(), SIGNAL(labelsBrushChanged(const QBrush&)), this, SLOT(handleLabelsBrushChanged(const QBrush&)));
    QObject::connect(axis(), SIGNAL(labelsFontChanged(const QFont&)), this, SLOT(handleLabelsFontChanged(const QFont&)));
    QObject::connect(axis(), SIGNAL(gridLinePenChanged(const QPen&)), this, SLOT(handleGridPenChanged(const QPen&)));
    QObject::connect(axis(), SIGNAL(shadesPenChanged(const QPen&)), this, SLOT(handleShadesPenChanged(const QPen&)));
    QObject::connect(axis(), SIGNAL(shadesBrushChanged(const QBrush&)), this, SLOT(handleShadesBrushChanged(const QBrush&)));
    QObject::connect(axis(), SIGNAL(titleTextChanged(const QString&)), this, SLOT(handleTitleTextChanged(const QString&)));
    QObject::connect(axis(), SIGNAL(titleFontChanged(const QFont&)), this, SLOT(handleTitleFontChanged(const QFont&)));
    QObject::connect(axis(), SIGNAL(titleBrushChanged(const QBrush&)), this, SLOT(handleTitleBrushChanged(const QBrush&)));
    QObject::connect(axis(), SIGNAL(titleVisibleChanged(bool)), this, SLOT(handleTitleVisibleChanged(bool)));
    QObject::connect(axis()->d_ptr.data(), SIGNAL(rangeChanged(qreal, qreal)), this, SLOT(handleRangeChanged(qreal, qreal)));
    QObject::connect(axis(), SIGNAL(reverseChanged(bool)), this, SLOT(handleReverseChanged(bool)));
    QObject::connect(axis(), SIGNAL(lineVisibleChanged(bool)),
                     this, SLOT(handleMinorArrowVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(linePenChanged(const QPen&)), this,
                     SLOT(handleMinorArrowPenChanged(const QPen&)));
    QObject::connect(axis(), SIGNAL(minorGridVisibleChanged(bool)),
                     this, SLOT(handleMinorGridVisibleChanged(bool)));
    QObject::connect(axis(), SIGNAL(minorGridLinePenChanged(const QPen&)),
                     this, SLOT(handleMinorGridPenChanged(const QPen&)));
    QObject::connect(axis(), SIGNAL(gridLineColorChanged(const QColor&)),
                     this, SLOT(handleGridLineColorChanged(const QColor&)));
    QObject::connect(axis(), SIGNAL(minorGridLineColorChanged(const QColor&)),
                     this, SLOT(handleMinorGridLineColorChanged(const QColor&)));

    if (axis()->type() == QAbstractAxis::AxisTypeCategory) {
        QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
        QObject::connect(categoryAxis,
                         SIGNAL(labelsPositionChanged(QCategoryAxis::AxisLabelsPosition)),
                         this, SLOT(handleLabelsPositionChanged()));
    }
}

void ChartAxisElement::handleArrowVisibleChanged(bool visible)
{
    m_arrow->setVisible(visible);
}

void ChartAxisElement::handleMinorArrowVisibleChanged(bool visible)
{
    m_minorArrow->setVisible(visible);
}

void ChartAxisElement::handleGridVisibleChanged(bool visible)
{
    m_grid->setVisible(visible);
}

void ChartAxisElement::handleMinorGridVisibleChanged(bool visible)
{
    m_minorGrid->setVisible(visible);
}

void ChartAxisElement::handleLabelsPositionChanged()
{
    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
}

void ChartAxisElement::valueLabelEdited(qreal oldValue, qreal newValue)
{
    qreal range = max() - min();
    qreal center = ((max() - min()) / 2.0) + min();
    qreal newRange = 0.0;
    auto label = static_cast<ValueAxisLabel *>(this->sender());
    if ((oldValue >= center && newValue >= min())
     || (oldValue <  center && newValue >= max() && oldValue != min())) {
        newRange = range * ((newValue - min()) / (oldValue - min()));
        if (newRange > 0) {
            m_axis->setRange(min(), min() + newRange);
            return;
        }
    } else if ((oldValue >= center && newValue <= min() && max() != oldValue)
            || (oldValue <  center && newValue <  max())) {
        newRange = range * ((max() - newValue) / (max() - oldValue));
        if (newRange > 0) {
            m_axis->setRange(max() - newRange, max());
            return;
        }
    }
    label->reloadBeforeEditContent();
}

void ChartAxisElement::dateTimeLabelEdited(const QDateTime &oldTime, const QDateTime &newTime)
{
    qreal range = max() - min();
    qreal center = ((max() - min()) / 2.0) + min();
    qreal newRange = 0.0;
    qint64 oldValue = oldTime.toMSecsSinceEpoch();
    qint64 newValue = newTime.toMSecsSinceEpoch();
    if ((oldValue >= center && newValue >= min())
     || (oldValue <  center && newValue >= max() && oldValue != min())) {
        newRange = range * ((newValue - min()) / (oldValue - min()));
        if (newRange > 0) {
            m_axis->setRange(
                        QDateTime::fromMSecsSinceEpoch(min()),
                        QDateTime::fromMSecsSinceEpoch(min() + newRange));
            return;
        }
    } else if ((oldValue >= center && newValue <= min() && max() != oldValue)
            || (oldValue <  center && newValue <  max())) {
        newRange = range * ((max() - newValue) / (max() - oldValue));
        if (newRange > 0) {
            m_axis->setRange(max() - newRange, max());
            m_axis->setRange(
                        QDateTime::fromMSecsSinceEpoch(max() - newRange),
                        QDateTime::fromMSecsSinceEpoch(max()));
            return;
        }
    }
    static_cast<DateTimeAxisLabel *>(this->sender())->reloadBeforeEditContent();
}

void ChartAxisElement::handleLabelsVisibleChanged(bool visible)
{
    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
    m_labels->setVisible(visible);
}

void ChartAxisElement::handleShadesVisibleChanged(bool visible)
{
    m_shades->setVisible(visible);
}

void ChartAxisElement::handleTitleVisibleChanged(bool visible)
{
    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
    m_title->setVisible(visible);
}

void ChartAxisElement::handleLabelsAngleChanged(int angle)
{
    foreach (QGraphicsItem *item, m_labels->childItems())
        item->setRotation(angle);

    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
}

void ChartAxisElement::handleLabelsBrushChanged(const QBrush &brush)
{
    foreach (QGraphicsItem *item, m_labels->childItems())
        static_cast<QGraphicsTextItem *>(item)->setDefaultTextColor(brush.color());
}

void ChartAxisElement::handleLabelsFontChanged(const QFont &font)
{
    foreach (QGraphicsItem *item, m_labels->childItems())
        static_cast<QGraphicsTextItem *>(item)->setFont(font);
    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
}

void ChartAxisElement::handleTitleTextChanged(const QString &title)
{
    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
    if (title.isEmpty() || !m_title->isVisible())
        m_title->setHtml(title);
}

void ChartAxisElement::handleTitleBrushChanged(const QBrush &brush)
{
    m_title->setDefaultTextColor(brush.color());
}

void ChartAxisElement::handleTitleFontChanged(const QFont &font)
{
    if (m_title->font() != font) {
        m_title->setFont(font);
        QGraphicsLayoutItem::updateGeometry();
        presenter()->layout()->invalidate();
    }
}

void ChartAxisElement::handleVisibleChanged(bool visible)
{
    setVisible(visible);
    if (!visible) {
        m_grid->setVisible(visible);
        m_arrow->setVisible(visible);
        m_minorGrid->setVisible(visible);
        m_minorArrow->setVisible(visible);
        m_shades->setVisible(visible);
        m_labels->setVisible(visible);
        m_title->setVisible(visible);
    } else {
        m_grid->setVisible(axis()->isGridLineVisible());
        m_arrow->setVisible(axis()->isLineVisible());
        m_minorGrid->setVisible(axis()->isMinorGridLineVisible());
        m_minorArrow->setVisible(axis()->isLineVisible());
        m_shades->setVisible(axis()->shadesVisible());
        m_labels->setVisible(axis()->labelsVisible());
        m_title->setVisible(axis()->isTitleVisible());
    }
    if (presenter()) {
        if (visible) {
            QSizeF before = effectiveSizeHint(Qt::PreferredSize);
            QSizeF after = sizeHint(Qt::PreferredSize);
            if (before != after)
                QGraphicsLayoutItem::updateGeometry();
        }
        presenter()->layout()->invalidate();
    }
}

void ChartAxisElement::handleRangeChanged(qreal min, qreal max)
{
    Q_UNUSED(min);
    Q_UNUSED(max);

    if (!isEmpty()) {
        QVector<qreal> layout = calculateLayout();
        updateLayout(layout);
        QSizeF before = effectiveSizeHint(Qt::PreferredSize);
        QSizeF after = sizeHint(Qt::PreferredSize);

        if (before != after) {
            QGraphicsLayoutItem::updateGeometry();
            // We don't want to call invalidate on layout, since it will change minimum size of
            // component, which we would like to avoid since it causes nasty flips when scrolling
            // or zooming, instead recalculate layout and use plotArea for extra space.
            presenter()->layout()->setGeometry(presenter()->layout()->geometry());
        }
    }
}

void ChartAxisElement::handleReverseChanged(bool reverse)
{
    Q_UNUSED(reverse);

    QGraphicsLayoutItem::updateGeometry();
    presenter()->layout()->invalidate();
}

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

qreal ChartAxisElement::min() const
{
    return m_axis->d_ptr->min();
}

qreal ChartAxisElement::max() const
{
    return m_axis->d_ptr->max();
}

qreal ChartAxisElement::tickInterval() const
{
    QValueAxis *valueAxis = qobject_cast<QValueAxis *>(m_axis);
    if (valueAxis)
        return valueAxis->tickInterval();
    else
        return 0.0;
}

qreal ChartAxisElement::tickAnchor() const
{
    QValueAxis *valueAxis = qobject_cast<QValueAxis *>(m_axis);
    if (valueAxis)
        return valueAxis->tickAnchor();
    else
        return 0.0;
}

QString ChartAxisElement::formatLabel(const QString &formatSpec, const QByteArray &array,
                                      qreal value, int precision, const QString &preStr,
                                      const QString &postStr) const
{
    QString retVal;
    if (!formatSpec.isEmpty()) {
        if (formatSpec.at(0) == QLatin1Char('d')
            || formatSpec.at(0) == QLatin1Char('i')
            || formatSpec.at(0) == QLatin1Char('c')) {
            if (presenter()->localizeNumbers())
                retVal = preStr + presenter()->locale().toString(qint64(value)) + postStr;
            else
                retVal = QString::asprintf(array.constData(), qint64(value));
        } else if (formatSpec.at(0) == QLatin1Char('u')
                 || formatSpec.at(0) == QLatin1Char('o')
                 || formatSpec.at(0) == QLatin1Char('x')
                 || formatSpec.at(0) == QLatin1Char('X')) {
            // These formats are not supported by localized numbers
            retVal = QString::asprintf(array.constData(), quint64(value));
        } else if (formatSpec.at(0) == QLatin1Char('f')
                   || formatSpec.at(0) == QLatin1Char('F')
                   || formatSpec.at(0) == QLatin1Char('e')
                   || formatSpec.at(0) == QLatin1Char('E')
                   || formatSpec.at(0) == QLatin1Char('g')
                   || formatSpec.at(0) == QLatin1Char('G')) {
            if (presenter()->localizeNumbers()) {
                retVal = preStr
                        + presenter()->locale().toString(value, formatSpec.at(0).toLatin1(),
                                                         precision)
                        + postStr;
            } else {
                retVal = QString::asprintf(array.constData(), value);
            }
        }
    }
    return retVal;
}

QStringList ChartAxisElement::createValueLabels(qreal min, qreal max, int ticks,
                                                qreal tickInterval, qreal tickAnchor,
                                                QValueAxis::TickType tickType,
                                                const QString &format) const
{
    QStringList labels;

    if (max <= min || ticks < 1)
        return labels;

    if (format.isEmpty()) {
        int n = qMax(int(-qFloor(std::log10((max - min) / (ticks - 1)))), 0) + 1;
        if (tickType == QValueAxis::TicksFixed) {
            for (int i = 0; i < ticks; i++) {
                qreal value = min + (i * (max - min) / (ticks - 1));
                labels << presenter()->numberToString(value, 'f', n);
            }
        } else {
            qreal value = tickAnchor;
            if (value > min)
                value = value - int((value - min) / tickInterval) * tickInterval;
            else
                value = value + qCeil((min - value) / tickInterval) * tickInterval;

            while (value <= max || qFuzzyCompare(value, max)) {
                labels << presenter()->numberToString(value, 'f', n);
                value += tickInterval;
            }
        }
    } else {
        QByteArray array = format.toLatin1();
        QString formatSpec;
        QString preStr;
        QString postStr;
        int precision = 6; // Six is the default precision in Qt API
        if (presenter()->localizeNumbers()) {
            if (!labelFormatMatcherLocalized)
                labelFormatMatcherLocalized
                        = new QRegularExpression(QString::fromLatin1(labelFormatMatchLocalizedString));
            QRegularExpressionMatch rmatch;
            if (format.indexOf(*labelFormatMatcherLocalized, 0, &rmatch) != -1) {
                preStr = rmatch.captured(1);
                if (!rmatch.captured(2).isEmpty())
                    precision = rmatch.captured(2).toInt();
                formatSpec = rmatch.captured(3);
                postStr = rmatch.captured(4);
            }
        } else {
            if (!labelFormatMatcher)
                labelFormatMatcher = new QRegularExpression(QString::fromLatin1(labelFormatMatchString));
            QRegularExpressionMatch rmatch;
            if (format.indexOf(*labelFormatMatcher, 0, &rmatch) != -1)
                formatSpec = rmatch.captured(1);
        }
        if (tickType == QValueAxis::TicksFixed) {
            for (int i = 0; i < ticks; i++) {
                qreal value = min + (i * (max - min) / (ticks - 1));
                labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
            }
        } else {
            qreal value = tickAnchor;
            if (value > min)
                value = value - int((value - min) / tickInterval) * tickInterval;
            else
                value = value + qCeil((min - value) / tickInterval) * tickInterval;

            while (value <= max || qFuzzyCompare(value, max)) {
                labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
                value += tickInterval;
            }
        }
    }

    return labels;
}

QStringList ChartAxisElement::createLogValueLabels(qreal min, qreal max, qreal base, int ticks,
                                                   const QString &format) const
{
    QStringList labels;

    if (max <= min || ticks < 1)
        return labels;

    int firstTick;
    if (base > 1)
        firstTick = qCeil(std::log10(min) / std::log10(base));
    else
        firstTick = qCeil(std::log10(max) / std::log10(base));

    if (format.isEmpty()) {
        int n = 0;
        if (ticks > 1)
            n = qMax(int(-qFloor(std::log10((max - min) / (ticks - 1)))), 0);
        n++;
        for (int i = firstTick; i < ticks + firstTick; i++) {
            qreal value = qPow(base, i);
            labels << presenter()->numberToString(value, 'f', n);
        }
    } else {
        QByteArray array = format.toLatin1();
        QString formatSpec;
        QString preStr;
        QString postStr;
        int precision = 6; // Six is the default precision in Qt API
        if (presenter()->localizeNumbers()) {
            if (!labelFormatMatcherLocalized)
                labelFormatMatcherLocalized =
                        new QRegularExpression(QString::fromLatin1(labelFormatMatchLocalizedString));
            QRegularExpressionMatch rmatch;
            if (format.indexOf(*labelFormatMatcherLocalized, 0, &rmatch) != -1) {
                preStr = rmatch.captured(1);
                if (!rmatch.captured(2).isEmpty())
                    precision = rmatch.captured(2).toInt();
                formatSpec = rmatch.captured(3);
                postStr = rmatch.captured(4);
            }
        } else {
            if (!labelFormatMatcher)
                labelFormatMatcher = new QRegularExpression(QString::fromLatin1(labelFormatMatchString));
            QRegularExpressionMatch rmatch;
            if (format.indexOf(*labelFormatMatcher, 0, &rmatch) != -1)
                formatSpec = rmatch.captured(1);
        }
        for (int i = firstTick; i < ticks + firstTick; i++) {
            qreal value = qPow(base, i);
            labels << formatLabel(formatSpec, array, value, precision, preStr, postStr);
        }
    }

    return labels;
}

QStringList ChartAxisElement::createDateTimeLabels(qreal min, qreal max,int ticks,
                                                   const QString &format) const
{
    QStringList labels;

    if (max <= min || ticks < 1)
        return labels;

    for (int i = 0; i < ticks; i++) {
        qreal value = min + (i * (max - min) / (ticks - 1));
        labels << presenter()->locale().toString(QDateTime::fromMSecsSinceEpoch(value), format);
    }
    return labels;
}


bool ChartAxisElement::labelsEditable() const
{
    return m_labelsEditable;
}

void ChartAxisElement::setLabelsEditable(bool labelsEditable)
{
    if (axis()->type() == QAbstractAxis::AxisTypeValue
            || axis()->type() == QAbstractAxis::AxisTypeDateTime) {
        labelGroup()->setHandlesChildEvents(!labelsEditable);
        const QList<QGraphicsItem *> childItems = labelGroup()->childItems();
        for (auto item : childItems) {
            switch (axis()->type()) {
            case QtCharts::QAbstractAxis::AxisTypeValue:
                static_cast<ValueAxisLabel *>(item)->setEditable(labelsEditable);
                break;
            case QtCharts::QAbstractAxis::AxisTypeDateTime:
                static_cast<DateTimeAxisLabel *>(item)->setEditable(labelsEditable);
                break;
            default:
                break;
            }
        }
        m_labelsEditable = labelsEditable;
    }
}

void ChartAxisElement::axisSelected()
{
    emit clicked();
}

QT_CHARTS_END_NAMESPACE

#include "moc_chartaxiselement_p.cpp"
