/****************************************************************************
**
** 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/QBarCategoryAxis>
#include <private/qbarcategoryaxis_p.h>
#include <private/chartbarcategoryaxisx_p.h>
#include <private/chartbarcategoryaxisy_p.h>
#include <private/abstractdomain_p.h>
#include <QtCharts/QChart>
#include <QtCore/QtMath>

QT_CHARTS_BEGIN_NAMESPACE
/*!
    \class QBarCategoryAxis
    \inmodule QtCharts
    \brief The QBarCategoryAxis class adds categories to a chart's axes.

    QBarCategoryAxis can be set up to show an axis line with tick marks, grid lines, and shades.
    Categories are drawn between the ticks. It can be used also with a line series, as demonstrated
    by the \l {Line and BarChart Example} {Line and BarChart Example}.

    The following code illustrates how to use QBarCategoryAxis:
    \code
    QChartView *chartView = new QChartView;
    QBarSeries *series = new QBarSeries;
    // ...
    chartView->chart()->addSeries(series);
    chartView->chart()->createDefaultAxes();

    QBarCategoryAxis *axisX = new QBarCategoryAxis;
    QStringList categories;
    categories << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun";
    axisX->append(categories);
    axisX->setRange("Feb", "May");
    chartView->chart()->setAxisX(axisX, series);
    \endcode
*/

/*!
    \qmltype BarCategoryAxis
    \instantiates QBarCategoryAxis
    \inqmlmodule QtCharts

    \inherits AbstractAxis

    \brief Adds categories to a chart's axes.

    The BarCategoryAxis type can be set up to show an axis line with tick marks, grid lines, and
    shades. Categories are drawn between the ticks. It can be used also with a line series.

    The following QML snippet illustrates how to use BarCategoryAxis:
    \code
        ChartView {
            BarCategoryAxis {
                id: categoryAxis
                categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun" ]
            }
        // Add a few series...
        }
    \endcode
*/

/*!
  \property QBarCategoryAxis::categories
  \brief The categories of an axis.
*/
/*!
  \qmlproperty QStringList BarCategoryAxis::categories
  The categories of an axis.
*/

/*!
  \property QBarCategoryAxis::min
  \brief The minimum value on the axis.
*/
/*!
  \qmlproperty string BarCategoryAxis::min
  The minimum value on the axis.
*/

/*!
  \property QBarCategoryAxis::max
  \brief The maximum value on the axis.
*/
/*!
  \qmlproperty string BarCategoryAxis::max
  The maximum value on the axis.
*/

/*!
  \property QBarCategoryAxis::count
  \brief The number of categories of an axis.
*/
/*!
  \qmlproperty int BarCategoryAxis::count
  The number of categories of an axis.
*/

/*!
  \fn void QBarCategoryAxis::categoriesChanged()
  This signal is emitted when the categories of the axis change.
*/

/*!
  \fn void QBarCategoryAxis::minChanged(const QString &min)
  This signal is emitted when the \a min value of the axis changes.
*/

/*!
  \fn void QBarCategoryAxis::maxChanged(const QString &max)
  This signal is emitted when the \a max value of the axis changes.
*/

/*!
  \fn void QBarCategoryAxis::countChanged()
  This signal is emitted when the number of categories of an axis changes.
*/

/*!
  \fn void QBarCategoryAxis::rangeChanged(const QString &min, const QString &max)
  This signal is emitted when \a min or \a max value of the axis changes.
*/

/*!
  \qmlsignal BarCategoryAxis::rangeChanged(string min, string max)
  This signal is emitted when \a min or \a max value of the axis changes.

  The corresponding signal handler is \c onRangeChanged.
*/

/*!
  \qmlmethod void BarCategoryAxis::clear()
  Removes all categories. Sets the maximum and minimum values of the axis range to QString::null.
*/

/*!
    Constructs an axis object that is the child of \a parent.
*/
QBarCategoryAxis::QBarCategoryAxis(QObject *parent):
    QAbstractAxis(*new QBarCategoryAxisPrivate(this), parent)
{
}

/*!
    Destroys the axis object.
*/
QBarCategoryAxis::~QBarCategoryAxis()
{
    Q_D(QBarCategoryAxis);
    if (d->m_chart)
        d->m_chart->removeAxis(this);
}

/*!
    \internal
*/
QBarCategoryAxis::QBarCategoryAxis(QBarCategoryAxisPrivate &d, QObject *parent)
    : QAbstractAxis(d, parent)
{

}

/*!
    Appends \a categories to an axis. The maximum value on the axis will be changed
    to match the last category in \a categories. If no categories were previously defined,
    the minimum value on the axis will also be changed to match the first category in
    \a categories.

    A category has to be a valid QString and it cannot be duplicated. Duplicated
    categories will not be appended.
*/
void QBarCategoryAxis::append(const QStringList &categories)
{
    if (categories.isEmpty())
        return;

    Q_D(QBarCategoryAxis);

    int count = d->m_categories.count();

    foreach(QString category, categories) {
        if (!d->m_categories.contains(category) && !category.isNull()) {
            d->m_categories.append(category);
        }
    }

    if (d->m_categories.count() == count)
        return;

    if (count == 0)
        setRange(d->m_categories.first(), d->m_categories.last());
    else
        setRange(d->m_minCategory, d->m_categories.last());

    emit categoriesChanged();
    emit countChanged();
}

/*!
    Appends \a category to an axis. The maximum value on the axis will be changed
    to match the last \a  category. If no categories were previously defined, the minimum
    value on the axis will also be changed to match \a category.

    A category has to be a valid QString and it cannot be duplicated. Duplicated
    categories will not be appended.
*/
void QBarCategoryAxis::append(const QString &category)
{
    Q_D(QBarCategoryAxis);

    int count = d->m_categories.count();

    if (!d->m_categories.contains(category) && !category.isNull())
        d->m_categories.append(category);

    if (d->m_categories.count() == count)
        return;

    if (count == 0)
        setRange(d->m_categories.last(), d->m_categories.last());
    else
        setRange(d->m_minCategory, d->m_categories.last());

    emit categoriesChanged();
    emit countChanged();
}

/*!
    Removes \a category from the axis. Removing a category that currently sets the
    maximum or minimum value on the axis will affect the axis range.
*/
void QBarCategoryAxis::remove(const QString &category)
{
    Q_D(QBarCategoryAxis);

    if (d->m_categories.contains(category)) {
        d->m_categories.removeAt(d->m_categories.indexOf(category));
        if (!d->m_categories.isEmpty()) {
            if (d->m_minCategory == category) {
                setRange(d->m_categories.first(), d->m_maxCategory);
            } else if (d->m_maxCategory == category) {
                setRange(d->m_minCategory, d->m_categories.last());
            } else {
                d->updateCategoryDomain();
            }
        } else {
            setRange(QString(), QString());
        }
        emit categoriesChanged();
        emit countChanged();
    }
}

/*!
    Inserts \a category to the axis at \a index. \a category has to be a valid QString
    and it cannot be duplicated. If \a category is prepended or appended to other
    categories, the minimum and maximum values on the axis are updated accordingly.
*/
void QBarCategoryAxis::insert(int index, const QString &category)
{
    Q_D(QBarCategoryAxis);

    int count = d->m_categories.count();

    if (!d->m_categories.contains(category) && !category.isNull())
        d->m_categories.insert(index, category);

    if (d->m_categories.count() == count)
        return;

    if (count == 0) {
        setRange(d->m_categories.first(), d->m_categories.first());
    } else if (index == 0) {
        setRange(d->m_categories.first(), d->m_maxCategory);
    } else if (index == count) {
        setRange(d->m_minCategory, d->m_categories.last());
    } else {
        d->updateCategoryDomain();
    }

    emit categoriesChanged();
    emit countChanged();
}

/*!
    Replaces \a oldCategory with \a newCategory. If \a oldCategory does not exist on the axis,
    nothing is done. \a newCategory has to be a valid QString and it cannot be duplicated. If
    the minimum or maximum category is replaced, the minimum and maximum values on the axis are
    updated accordingly.
*/
void QBarCategoryAxis::replace(const QString &oldCategory, const QString &newCategory)
{
    Q_D(QBarCategoryAxis);

    int pos = d->m_categories.indexOf(oldCategory);

    if (pos != -1 && !d->m_categories.contains(newCategory) && !newCategory.isNull()) {
        d->m_categories.replace(pos, newCategory);
        if (d->m_minCategory == oldCategory)
            setRange(newCategory, d->m_maxCategory);
        else if (d->m_maxCategory == oldCategory)
            setRange(d->m_minCategory, newCategory);

        emit categoriesChanged();
        emit countChanged();
    }
}

/*!
    Removes all categories. Sets the maximum and minimum values of the axis range to QString::null.
 */
void QBarCategoryAxis::clear()
{
    Q_D(QBarCategoryAxis);
    d->m_categories.clear();
    setRange(QString(), QString());
    emit categoriesChanged();
    emit countChanged();
}

/*!
    Sets \a categories and discards the old ones. The axis range is adjusted to match the
    first and last category in \a categories.

    A category has to be a valid QString and it cannot be duplicated.
*/
void QBarCategoryAxis::setCategories(const QStringList &categories)
{
    Q_D(QBarCategoryAxis);
    d->m_categories.clear();
    d->m_minCategory = QString();
    d->m_maxCategory = QString();
    d->m_min = 0;
    d->m_max = 0;
    d->m_count = 0;
    append(categories);
}

/*!
    Returns categories.
*/
QStringList QBarCategoryAxis::categories()
{
    Q_D(QBarCategoryAxis);
    return d->m_categories;
}

/*!
    Returns the number of categories.
 */
int QBarCategoryAxis::count() const
{
    Q_D(const QBarCategoryAxis);
    return d->m_categories.count();
}

/*!
    Returns the category at \a index. The index must be valid.
*/
QString QBarCategoryAxis::at(int index) const
{
    Q_D(const QBarCategoryAxis);
    return d->m_categories.at(index);
}

/*!
    Sets the minimum category to \a min.
*/
void QBarCategoryAxis::setMin(const QString &min)
{
    Q_D(QBarCategoryAxis);
    d->setRange(min, d->m_maxCategory);
}

/*!
    Returns the minimum category.
*/
QString QBarCategoryAxis::min() const
{
    Q_D(const QBarCategoryAxis);
    return d->m_minCategory;
}

/*!
    Sets the maximum category to \a max.
*/
void QBarCategoryAxis::setMax(const QString &max)
{
    Q_D(QBarCategoryAxis);
    d->setRange(d->m_minCategory, max);
}

/*!
    Returns the maximum category.
*/
QString QBarCategoryAxis::max() const
{
    Q_D(const QBarCategoryAxis);
    return d->m_maxCategory;
}

/*!
    Sets the axis range from \a minCategory to \a maxCategory.
*/
void QBarCategoryAxis::setRange(const QString &minCategory, const QString &maxCategory)
{
    Q_D(QBarCategoryAxis);
    d->setRange(minCategory,maxCategory);
}

/*!
    Returns the type of the axis.
*/
QAbstractAxis::AxisType QBarCategoryAxis::type() const
{
    return AxisTypeBarCategory;
}

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

QBarCategoryAxisPrivate::QBarCategoryAxisPrivate(QBarCategoryAxis *q)
    : QAbstractAxisPrivate(q),
      m_min(0.0),
      m_max(0.0),
      m_count(0)
{

}

QBarCategoryAxisPrivate::~QBarCategoryAxisPrivate()
{

}

void QBarCategoryAxisPrivate::setMin(const QVariant &min)
{
    setRange(min, m_maxCategory);
}

void QBarCategoryAxisPrivate::setMax(const QVariant &max)
{
    setRange(m_minCategory, max);
}

void QBarCategoryAxisPrivate::setRange(const QVariant &min, const QVariant &max)
{
    QString value1 = min.toString();
    QString value2 = max.toString();
    setRange(value1, value2);
}

void QBarCategoryAxisPrivate::setRange(qreal min, qreal max)
{
    Q_Q(QBarCategoryAxis);

    bool categoryChanged = false;
    bool changed = false;

    if (min > max)
        return;

    if (!qFuzzyIsNull(m_min - min)) {
        m_min = min;
        changed = true;

        int imin = m_min + 0.5;
        if (imin >= 0 && imin < m_categories.count()) {
            QString minCategory = m_categories.at(imin);
            if (m_minCategory != minCategory && !minCategory.isEmpty()) {
                m_minCategory = minCategory;
                categoryChanged = true;
                emit q->minChanged(minCategory);
            }
        }

    }

    if (!qFuzzyIsNull(m_max - max)) {
        m_max = max;
        changed = true;

        int imax = m_max - 0.5;
        if (imax >= 0 && imax < m_categories.count()) {
            QString maxCategory = m_categories.at(imax);
            if (m_maxCategory != maxCategory && !maxCategory.isEmpty()) {
                m_maxCategory = maxCategory;
                categoryChanged = true;
                emit q->maxChanged(maxCategory);
            }
        }
    }

    if (categoryChanged){
        emit q->rangeChanged(m_minCategory, m_maxCategory);
    }

    if (changed) {
        emit rangeChanged(m_min,m_max);
    }
}

void  QBarCategoryAxisPrivate::setRange(const QString &minCategory, const QString &maxCategory)
{
	Q_Q(QBarCategoryAxis);
    bool changed = false;

    //special case in case or clearing all categories
    if (minCategory.isNull() && maxCategory.isNull()) {
        m_minCategory = minCategory;
        m_maxCategory = maxCategory;
        m_min = 0;
        m_max = 0;
        m_count = 0;
        emit q->minChanged(minCategory);
        emit q->maxChanged(maxCategory);
        emit q->rangeChanged(m_minCategory, m_maxCategory);
        emit rangeChanged(m_min,m_max);
        return;
    }

    if (m_categories.indexOf(maxCategory) < m_categories.indexOf(minCategory))
        return;

    if (!minCategory.isNull() && (m_minCategory != minCategory || m_minCategory.isNull())
            && m_categories.contains(minCategory)) {
        m_minCategory = minCategory;
        m_min = m_categories.indexOf(m_minCategory) - 0.5;
        changed = true;
        emit q->minChanged(minCategory);
    }

    if (!maxCategory.isNull() && (m_maxCategory != maxCategory || m_maxCategory.isNull())
            && m_categories.contains(maxCategory)) {
        m_maxCategory = maxCategory;
        m_max = m_categories.indexOf(m_maxCategory) + 0.5;
        changed = true;
        emit q->maxChanged(maxCategory);
    }

    if (changed) {
        m_count = m_max - m_min;
        emit q->rangeChanged(m_minCategory, m_maxCategory);
        emit rangeChanged(m_min,m_max);
    }
}

void QBarCategoryAxisPrivate::initializeGraphics(QGraphicsItem* parent)
{
    Q_Q(QBarCategoryAxis);
    ChartAxisElement* axis(0);
    if (orientation() == Qt::Vertical)
        axis = new ChartBarCategoryAxisY(q,parent);
    if (orientation() == Qt::Horizontal)
        axis = new ChartBarCategoryAxisX(q,parent);

    m_item.reset(axis);
    QAbstractAxisPrivate::initializeGraphics(parent);
}

void QBarCategoryAxisPrivate::updateCategoryDomain()
{
    bool changed = false;

    qreal tmpMin = m_categories.indexOf(m_minCategory) - 0.5;
    if (!qFuzzyIsNull(m_min - tmpMin)) {
        m_min = tmpMin;
        changed = true;
    }
    qreal tmpMax = m_categories.indexOf(m_maxCategory) + 0.5;
    if (!qFuzzyIsNull(m_max - tmpMax)) {
        m_max = tmpMax;
        changed = true;
    }
    m_count = m_max - m_min;

    if (changed)
        emit rangeChanged(m_min,m_max);
}


void QBarCategoryAxisPrivate::initializeDomain(AbstractDomain *domain)
{
    Q_Q(QBarCategoryAxis);
    if (m_max == m_min) {
        int min;
        int max;
        if (orientation() == Qt::Vertical) {
            min = domain->minY() + 0.5;
            max = domain->maxY() - 0.5;
        } else {
            min = domain->minX() + 0.5;
            max = domain->maxX() - 0.5;
        }

        if (min > 0 && min < m_categories.count() && max > 0 && max < m_categories.count())
            q->setRange(m_categories.at(min), m_categories.at(max));
    } else {
        if (orientation() == Qt::Vertical)
            domain->setRangeY(m_min, m_max);
        else
            domain->setRangeX(m_min, m_max);
    }
}

QT_CHARTS_END_NAMESPACE

#include "moc_qbarcategoryaxis.cpp"
#include "moc_qbarcategoryaxis_p.cpp"
