/****************************************************************************
**
** 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/QBoxPlotSeries>
#include <private/qboxplotseries_p.h>
#include <QtCharts/QBoxPlotLegendMarker>
#include <QtCharts/QBarCategoryAxis>
#include <private/boxplotchartitem_p.h>
#include <private/chartdataset_p.h>
#include <private/charttheme_p.h>
#include <QtCharts/QValueAxis>
#include <private/charttheme_p.h>
#include <private/boxplotanimation_p.h>
#include <private/qchart_p.h>
#include <QtCharts/QBoxSet>
#include <private/qboxset_p.h>

QT_CHARTS_BEGIN_NAMESPACE

/*!
    \class QBoxPlotSeries
    \inmodule QtCharts
    \brief The QBoxPlotSeries class presents data in box-and-whiskers charts.

    A box plot series acts as a container for box-and-whiskers items. Items from multiple series
    are grouped into categories according to their index value.

    The QBarCategoryAxis class is used to add the categories to the chart's axis. Category labels
    have to be unique. If the same category label is defined for several box-and-whiskers items,
    only the first one is drawn.

    See the \l {Box and Whiskers Example} {box-and-whiskers chart example} to learn how to create a
    box-and-whiskers chart.
    \image examples_boxplotchart.png

    \sa QBoxSet, QBarCategoryAxis
*/
/*!
    \fn QBoxPlotSeries::boxsetsAdded(QList<QBoxSet *> sets)
    This signal is emitted when the list of box-and-whiskers items specified by \a sets
    is added to the series.
*/
/*!
    \fn QBoxPlotSeries::boxsetsRemoved(QList<QBoxSet *> sets)
    This signal is emitted when the list of box-and-whiskers items specified by \a sets
    is removed from the series.
*/
/*!
    \fn QBoxPlotSeries::clicked(QBoxSet *boxset)
    This signal is emitted when the user clicks the box-and-whiskers item specified by
    \a boxset in the chart.
*/
/*!
    \fn QBoxPlotSeries::pressed(QBoxSet *boxset)
    This signal is emitted when the user clicks the box-and-whiskers item specified by
    \a boxset in the chart and holds down the mouse button.
*/
/*!
    \fn QBoxPlotSeries::released(QBoxSet *boxset)
    This signal is emitted when the user releases the mouse press on the box-and-whiskers
    item specified by \a boxset in the chart.
*/
/*!
    \fn QBoxPlotSeries::doubleClicked(QBoxSet *boxset)
    This signal is emitted when the user double-clicks the box-and-whiskers item specified by
    \a boxset in the chart.
*/
/*!
    \fn QBoxPlotSeries::hovered(bool status, QBoxSet *boxset)
    This signal is emitted when a mouse is hovered over the box-and-whiskers item specified by
    \a boxset in the chart. When the mouse moves over the item, \a status turns \c true, and
    when the mouse moves away again, it turns \c false.
*/
/*!
    \fn QBoxPlotSeries::countChanged()
    This signal is emitted when the number of box-and-whiskers items in the series changes.
*/
/*!
    \property QBoxPlotSeries::boxOutlineVisible
    \brief The visibility of the box outline.
*/
/*!
    \property QBoxPlotSeries::boxWidth
    \brief The width of the box-and-whiskers item. The value indicates the relative
    width of the item within its category. The value can be between 0.0 and 1.0. Negative values
    are replaced with 0.0 and values greater than 1.0 are replaced with 1.0.
*/
/*!
    \property QBoxPlotSeries::pen
    \brief The pen used to draw the lines of the box-and-whiskers items.
*/
/*!
    \property QBoxPlotSeries::brush
    \brief The brush used to fill the boxes of the box-and-whiskers items.
*/
/*!
    \property QBoxPlotSeries::count
    \brief The number of box-and-whiskers items in a box plot series.
*/

/*!
    \fn void QBoxPlotSeries::boxOutlineVisibilityChanged()
    This signal is emitted when the box outline visibility changes.
*/

/*!
    \fn void QBoxPlotSeries::boxWidthChanged()
    This signal is emitted when the width of the box-and-whiskers item changes.
*/
/*!
    \fn void QBoxPlotSeries::penChanged()
    This signal is emitted when the pen used to draw the lines of the box-and-whiskers
    items changes.
*/
/*!
    \fn void QBoxPlotSeries::brushChanged()
    This signal is emitted when the brush used to fill the boxes of the box-and-whiskers
    items changes.
*/
/*!
    \fn virtual SeriesType QBoxPlotSeries::type() const
    Returns the type of the series.
    \sa QAbstractSeries, SeriesType
*/

/*!
    Constructs an empty box plot series that is a QObject and a child of \a parent.
*/
QBoxPlotSeries::QBoxPlotSeries(QObject *parent)
    : QAbstractSeries(*new QBoxPlotSeriesPrivate(this), parent)
{
}

/*!
    Removes the series from the chart.
*/
QBoxPlotSeries::~QBoxPlotSeries()
{
    Q_D(QBoxPlotSeries);
    if (d->m_chart)
        d->m_chart->removeSeries(this);
}

/*!
    Adds a single box-and-whiskers item specified by \a set to the series and takes ownership of
    it. If the item is null or it already belongs to the series, it will not be appended.
    Returns \c true if appending succeeded.
*/
bool QBoxPlotSeries::append(QBoxSet *set)
{
    Q_D(QBoxPlotSeries);

    bool success = d->append(set);
    if (success) {
        QList<QBoxSet *> sets;
        sets.append(set);
        set->setParent(this);
        emit boxsetsAdded(sets);
        emit countChanged();
    }
    return success;
}

/*!
    Removes the box-and-whiskers item specified by \a set from the series and permanently
    deletes it if the removal succeeds. Returns \c true if the item was removed.
*/
bool QBoxPlotSeries::remove(QBoxSet *set)
{
    Q_D(QBoxPlotSeries);
    bool success = d->remove(set);
    if (success) {
        QList<QBoxSet *> sets;
        sets.append(set);
        set->setParent(0);
        emit boxsetsRemoved(sets);
        emit countChanged();
        delete set;
        set = 0;
    }
    return success;
}

/*!
    Takes the box-and-whiskers item specified by \a set from the series. Does not delete the
    item.

    \note The series remains the item's parent object. You must set the parent object to take
    full ownership.

    Returns \c true if the take operation succeeds.

*/
bool QBoxPlotSeries::take(QBoxSet *set)
{
    Q_D(QBoxPlotSeries);

    bool success = d->remove(set);
    if (success) {
        QList<QBoxSet *> sets;
        sets.append(set);
        emit boxsetsRemoved(sets);
        emit countChanged();
    }
    return success;
}

/*!
    Adds a list of box-and-whiskers items specified by \a sets to the series and takes ownership of
    them. If the list is null or the items already belong to the series, it will not be appended.
    Returns \c true if appending succeeded.
*/
bool QBoxPlotSeries::append(QList<QBoxSet *> sets)
{
    Q_D(QBoxPlotSeries);
    bool success = d->append(sets);
    if (success) {
        emit boxsetsAdded(sets);
        emit countChanged();
    }
    return success;
}

/*!
    Inserts a box-and-whiskers item specified by \a set to a series at the position specified by
    \a index and takes ownership of the item. If the item is null or already belongs to the series,
    it will not be appended. Returns \c true if inserting succeeds.
*/
bool QBoxPlotSeries::insert(int index, QBoxSet *set)
{
    Q_D(QBoxPlotSeries);
    bool success = d->insert(index, set);
    if (success) {
        QList<QBoxSet *> sets;
        sets.append(set);
        emit boxsetsAdded(sets);
        emit countChanged();
    }
    return success;
}

/*!
    Removes all box-and-whiskers items from the series and permanently deletes them.
*/
void QBoxPlotSeries::clear()
{
    Q_D(QBoxPlotSeries);
    QList<QBoxSet *> sets = boxSets();
    bool success = d->remove(sets);
    if (success) {
        emit boxsetsRemoved(sets);
        emit countChanged();
        foreach (QBoxSet *set, sets)
            delete set;
    }
}

/*!
    Returns the number of box-and-whiskers items in a box plot series.
*/
int QBoxPlotSeries::count() const
{
    Q_D(const QBoxPlotSeries);
    return d->m_boxSets.count();
}

/*!
    Returns a list of box-and-whiskers items in a box plot series. Keeps the ownership of the items.
 */
QList<QBoxSet *> QBoxPlotSeries::boxSets() const
{
    Q_D(const QBoxPlotSeries);
    return d->m_boxSets;
}

/*
    Returns QAbstractSeries::SeriesTypeBoxPlot.
*/
QAbstractSeries::SeriesType QBoxPlotSeries::type() const
{
    return QAbstractSeries::SeriesTypeBoxPlot;
}

void QBoxPlotSeries::setBoxOutlineVisible(bool visible)
{
    Q_D(QBoxPlotSeries);

    if (d->m_boxOutlineVisible != visible) {
        d->m_boxOutlineVisible = visible;
        emit d->updated();
        emit boxOutlineVisibilityChanged();
    }
}

bool QBoxPlotSeries::boxOutlineVisible()
{
    Q_D(QBoxPlotSeries);

    return d->m_boxOutlineVisible;
}

void QBoxPlotSeries::setBoxWidth(qreal width)
{
    Q_D(QBoxPlotSeries);

    if (width != d->m_boxWidth) {
        if (width < 0.0)
            width = 0.0;
        if (width > 1.0)
            width = 1.0;
        d->m_boxWidth = width;
        emit d->updatedLayout();
        emit boxWidthChanged();
    }
}

qreal QBoxPlotSeries::boxWidth()
{
    Q_D(QBoxPlotSeries);

    return d->m_boxWidth;
}

void QBoxPlotSeries::setBrush(const QBrush &brush)
{
    Q_D(QBoxPlotSeries);

    if (d->m_brush != brush) {
        d->m_brush = brush;
        emit d->updated();
        emit brushChanged();
    }
}

QBrush QBoxPlotSeries::brush() const
{
    Q_D(const QBoxPlotSeries);

    return d->m_brush;
}

void QBoxPlotSeries::setPen(const QPen &pen)
{
    Q_D(QBoxPlotSeries);

    if (d->m_pen != pen) {
        d->m_pen = pen;
        emit d->updated();
        emit penChanged();
    }
}

QPen QBoxPlotSeries::pen() const
{
    Q_D(const QBoxPlotSeries);

    return d->m_pen;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

QBoxPlotSeriesPrivate::QBoxPlotSeriesPrivate(QBoxPlotSeries *q)
    : QAbstractSeriesPrivate(q),
      m_pen(QChartPrivate::defaultPen()),
      m_brush(QChartPrivate::defaultBrush()),
      m_boxOutlineVisible(true),
      m_boxWidth(0.5)
{
}

QBoxPlotSeriesPrivate::~QBoxPlotSeriesPrivate()
{
    disconnect(this, 0, 0, 0);
}

void QBoxPlotSeriesPrivate::initializeDomain()
{
    qreal minX(domain()->minX());
    qreal minY(domain()->minY());
    qreal maxX(domain()->maxX());
    qreal maxY(domain()->maxY());

    qreal x = m_boxSets.count();
    minX = qMin(minX, qreal(-0.5));
    minY = qMin(minY, min());
    maxX = qMax(maxX, x - qreal(0.5));
    maxY = qMax(maxY, max());

    domain()->setRange(minX, maxX, minY, maxY);
}

void QBoxPlotSeriesPrivate::initializeAxes()
{
    foreach (QAbstractAxis* axis, m_axes) {
        if (axis->type() == QAbstractAxis::AxisTypeBarCategory) {
            if (axis->orientation() == Qt::Horizontal)
                populateCategories(qobject_cast<QBarCategoryAxis *>(axis));
        }
    }
}

QAbstractAxis::AxisType QBoxPlotSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
{
    if (orientation == Qt::Horizontal)
        return QAbstractAxis::AxisTypeBarCategory;

    return QAbstractAxis::AxisTypeValue;
}

QAbstractAxis* QBoxPlotSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
{
    if (defaultAxisType(orientation) == QAbstractAxis::AxisTypeBarCategory)
        return new QBarCategoryAxis;
    else
        return new QValueAxis;
}

void QBoxPlotSeriesPrivate::populateCategories(QBarCategoryAxis *axis)
{
    QStringList categories;
    if (axis->categories().isEmpty()) {
        for (int i(1); i < m_boxSets.count() + 1; i++) {
            QBoxSet *set = m_boxSets.at(i - 1);
            if (set->label().isEmpty())
                categories << presenter()->numberToString(i);
            else
                categories << set->label();
        }
        axis->append(categories);
    }
}

void QBoxPlotSeriesPrivate::initializeGraphics(QGraphicsItem *parent)
{
    Q_Q(QBoxPlotSeries);

    BoxPlotChartItem *boxPlot = new BoxPlotChartItem(q, parent);
    m_item.reset(boxPlot);
    QAbstractSeriesPrivate::initializeGraphics(parent);

    if (m_chart) {
        connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesAdded(QAbstractSeries*)), this, SLOT(handleSeriesChange(QAbstractSeries*)) );
        connect(m_chart->d_ptr->m_dataset, SIGNAL(seriesRemoved(QAbstractSeries*)), this, SLOT(handleSeriesRemove(QAbstractSeries*)) );

        QList<QAbstractSeries *> serieses = m_chart->series();

        // Tries to find this series from the Chart's list of series and deduce the index
        int index = 0;
        foreach (QAbstractSeries *s, serieses) {
            if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
                if (q == static_cast<QBoxPlotSeries *>(s)) {
                    boxPlot->m_seriesIndex = index;
                    m_index = index;
                }
                index++;
            }
        }
        boxPlot->m_seriesCount = index;
    }

    // Make BoxPlotChartItem to instantiate box & whisker items
    boxPlot->handleDataStructureChanged();
}

void QBoxPlotSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
{
    Q_Q(QBoxPlotSeries);

    const QList<QGradient> gradients = theme->seriesGradients();

    if (forced || QChartPrivate::defaultBrush() == m_brush) {
        QColor brushColor = ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.5);
        q->setBrush(brushColor);
    }

    if (forced || QChartPrivate::defaultPen() == m_pen) {
        QPen pen = theme->outlinePen();
        pen.setCosmetic(true);
        q->setPen(pen);
    }
}

void QBoxPlotSeriesPrivate::initializeAnimations(QChart::AnimationOptions options, int duration,
                                                 QEasingCurve &curve)
{
    BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
    Q_ASSERT(item);
    if (item->animation())
        item->animation()->stopAndDestroyLater();

    if (options.testFlag(QChart::SeriesAnimations))
        m_animation = new BoxPlotAnimation(item, duration, curve);
    else
        m_animation = 0;
    item->setAnimation(m_animation);

    QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);

    // Make BoxPlotChartItem to instantiate box & whisker items
    item->handleDataStructureChanged();
}

QList<QLegendMarker*> QBoxPlotSeriesPrivate::createLegendMarkers(QLegend *legend)
{
    Q_Q(QBoxPlotSeries);
    QList<QLegendMarker *> list;
    return list << new QBoxPlotLegendMarker(q, legend);
}

void QBoxPlotSeriesPrivate::handleSeriesRemove(QAbstractSeries *series)
{
    Q_Q(QBoxPlotSeries);

    QBoxPlotSeries *removedSeries = static_cast<QBoxPlotSeries *>(series);

    if (q == removedSeries) {
        if (m_animation)
            m_animation->stopAll();
        QObject::disconnect(m_chart->d_ptr->m_dataset, 0, this, 0);
    }

    // Test if series removed is me, then don't do anything
    if (q != removedSeries) {
        BoxPlotChartItem *item = static_cast<BoxPlotChartItem *>(m_item.data());
        if (item) {
            item->m_seriesCount = item->m_seriesCount - 1;
            if (removedSeries->d_func()->m_index < m_index) {
                m_index--;
                item->m_seriesIndex = m_index;
            }

            item->handleDataStructureChanged();
        }
    }
}

void QBoxPlotSeriesPrivate::handleSeriesChange(QAbstractSeries *series)
{
    Q_UNUSED(series);

    Q_Q(QBoxPlotSeries);

    BoxPlotChartItem *boxPlot = static_cast<BoxPlotChartItem *>(m_item.data());

    if (m_chart) {
        QList<QAbstractSeries *> serieses = m_chart->series();

        // Tries to find this series from the Chart's list of series and deduce the index
        int index = 0;
        foreach (QAbstractSeries *s, serieses) {
            if (s->type() == QAbstractSeries::SeriesTypeBoxPlot) {
                if (q == static_cast<QBoxPlotSeries *>(s)) {
                    boxPlot->m_seriesIndex = index;
                    m_index = index;
                }
                index++;
            }
        }
        boxPlot->m_seriesCount = index;
    }

    boxPlot->handleDataStructureChanged();
}

bool QBoxPlotSeriesPrivate::append(QBoxSet *set)
{
    if (m_boxSets.contains(set) || (set == 0) || set->d_ptr->m_series)
        return false; // Fail if set is already in list or set is null.

    m_boxSets.append(set);
    QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
    QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
    QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
    set->d_ptr->m_series = this;

    emit restructuredBoxes(); // this notifies boxplotchartitem
    return true;
}

bool QBoxPlotSeriesPrivate::remove(QBoxSet *set)
{
    if (!m_boxSets.contains(set))
        return false; // Fail if set is not in list

    set->d_ptr->m_series = 0;
    m_boxSets.removeOne(set);
    QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
    QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
    QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));

    emit restructuredBoxes(); // this notifies boxplotchartitem
    return true;
}

bool QBoxPlotSeriesPrivate::append(QList<QBoxSet *> sets)
{
    foreach (QBoxSet *set, sets) {
        if ((set == 0) || m_boxSets.contains(set) || set->d_ptr->m_series)
            return false; // Fail if any of the sets is null or is already appended.
        if (sets.count(set) != 1)
            return false; // Also fail if same set is more than once in given list.
    }

    foreach (QBoxSet *set, sets) {
        m_boxSets.append(set);
        QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
        QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
        QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
        set->d_ptr->m_series = this;
    }

    emit restructuredBoxes(); // this notifies boxplotchartitem
    return true;
}

bool QBoxPlotSeriesPrivate::remove(QList<QBoxSet *> sets)
{
    if (sets.count() == 0)
        return false;

    foreach (QBoxSet *set, sets) {
        if ((set == 0) || (!m_boxSets.contains(set)))
            return false; // Fail if any of the sets is null or is not in series
        if (sets.count(set) != 1)
            return false; // Also fail if same set is more than once in given list.
    }

    foreach (QBoxSet *set, sets) {
        set->d_ptr->m_series = 0;
        m_boxSets.removeOne(set);
        QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
        QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
        QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));
    }

    emit restructuredBoxes();        // this notifies boxplotchartitem

    return true;
}

bool QBoxPlotSeriesPrivate::insert(int index, QBoxSet *set)
{
    if ((m_boxSets.contains(set)) || (set == 0) || set->d_ptr->m_series)
        return false; // Fail if set is already in list or set is null.

    m_boxSets.insert(index, set);
    set->d_ptr->m_series = this;
    QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
    QObject::connect(set->d_ptr.data(), SIGNAL(updatedBox()), this, SIGNAL(updatedBoxes()));
    QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBox()), this, SIGNAL(restructuredBoxes()));

    emit restructuredBoxes();      // this notifies boxplotchartitem
    return true;
}

QBoxSet *QBoxPlotSeriesPrivate::boxSetAt(int index)
{
    return m_boxSets.at(index);
}

qreal QBoxPlotSeriesPrivate::min()
{
    if (m_boxSets.count() <= 0)
        return 0;

    qreal min = m_boxSets.at(0)->at(0);

    foreach (QBoxSet *set, m_boxSets) {
        for (int i = 0; i < 5; i++) {
            if (set->at(i) < min)
                min = set->at(i);
        }
    }

    return min;
}

qreal QBoxPlotSeriesPrivate::max()
{
    if (m_boxSets.count() <= 0)
        return 0;

    qreal max = m_boxSets.at(0)->at(0);

    foreach (QBoxSet *set, m_boxSets) {
        for (int i = 0; i < 5; i++) {
            if (set->at(i) > max)
                max = set->at(i);
        }
    }

    return max;
}

QT_CHARTS_END_NAMESPACE

#include "moc_qboxplotseries.cpp"
#include "moc_qboxplotseries_p.cpp"
