/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Data Visualization 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 "qabstract3daxis_p.h"

QT_BEGIN_NAMESPACE_DATAVISUALIZATION

/*!
 * \class QAbstract3DAxis
 * \inmodule QtDataVisualization
 * \brief The QAbstract3DAxis class is a base class for the axes of a graph.
 * \since QtDataVisualization 1.0
 *
 * This class specifies the enumerations, properties, and functions shared by
 * graph axes. It should not be used directly, but one of its subclasses should
 * be used instead.
 *
 * \sa QCategory3DAxis, QValue3DAxis
 */

/*!
 * \qmltype AbstractAxis3D
 * \inqmlmodule QtDataVisualization
 * \since QtDataVisualization 1.0
 * \ingroup datavisualization_qml
 * \instantiates QAbstract3DAxis
 * \brief A base type for the axes of a graph.
 *
 * This type is uncreatable, but contains properties that are exposed via subtypes.
 *
 * For AbstractAxis3D enums, see \l QAbstract3DAxis::AxisOrientation and
 * \l{QAbstract3DAxis::AxisType}.
 */

/*!
 * \qmlproperty string AbstractAxis3D::title
 * The title for the axis.
 *
 * \sa titleVisible, titleFixed
 */

/*!
 * \qmlproperty list AbstractAxis3D::labels
 * The labels for the axis.
 * \note Setting this property for ValueAxis3D does nothing, as it generates labels automatically.
 */

/*!
 * \qmlproperty AbstractAxis3D.AxisOrientation AbstractAxis3D::orientation
 * The orientation of the axis.
 */

/*!
 * \qmlproperty AbstractAxis3D.AxisType AbstractAxis3D::type
 * The type of the axis.
 */

/*!
 * \qmlproperty real AbstractAxis3D::min
 *
 * The minimum value on the axis.
 * When setting this property, the maximum value is adjusted if necessary, to
 * ensure that the range remains valid.
 */

/*!
 * \qmlproperty real AbstractAxis3D::max
 *
 * The maximum value on the axis.
 * When setting this property, the minimum value is adjusted if necessary, to
 * ensure that the range remains valid.
 */

/*!
 * \qmlproperty bool AbstractAxis3D::autoAdjustRange
 *
 * Defines whether the axis will automatically adjust the range so that all data fits in it.
 */

/*!
 * \qmlproperty real AbstractAxis3D::labelAutoRotation
 *
 * The maximum angle the labels can autorotate when the camera angle changes.
 * The angle can be between 0 and 90, inclusive. The default value is 0.
 * If the value is 0, axis labels do not automatically rotate.
 * If the value is greater than zero, labels attempt to orient themselves toward the camera, up to
 * the specified angle.
 */

/*!
 * \qmlproperty bool AbstractAxis3D::titleVisible
 *
 * Defines whether the axis title is visible in the primary graph view.
 *
 * The default value is \c{false}.
 *
 * \sa title, titleFixed
 */

/*!
 * \qmlproperty bool AbstractAxis3D::titleFixed
 *
 * The rotation of axis titles.
 *
 * If \c{true}, axis titles in the primary graph view will be rotated towards the camera similarly
 * to the axis labels.
 * If \c{false}, axis titles are only rotated around their axis but are not otherwise oriented
 * towards the camera.
 * This property does not have any effect if the labelAutoRotation property
 * value is zero.
 * Default value is \c{true}.
 *
 * \sa labelAutoRotation, title, titleVisible
 */

/*!
 * \enum QAbstract3DAxis::AxisOrientation
 *
 * The orientation of the axis object.
 *
 * \value AxisOrientationNone
 * \value AxisOrientationX
 * \value AxisOrientationY
 * \value AxisOrientationZ
 */

/*!
 * \enum QAbstract3DAxis::AxisType
 *
 * The type of the axis object.
 *
 * \value AxisTypeNone
 * \value AxisTypeCategory
 * \value AxisTypeValue
 */

/*!
 * \internal
 */
QAbstract3DAxis::QAbstract3DAxis(QAbstract3DAxisPrivate *d, QObject *parent) :
    QObject(parent),
    d_ptr(d)
{
}

/*!
 * Destroys QAbstract3DAxis.
 */
QAbstract3DAxis::~QAbstract3DAxis()
{
}

/*!
 * \property QAbstract3DAxis::orientation
 *
 * \brief The orientation of the axis.
 *
 * The value is one of AxisOrientation values.
 */
QAbstract3DAxis::AxisOrientation QAbstract3DAxis::orientation() const
{
    return d_ptr->m_orientation;
}

/*!
 * \property QAbstract3DAxis::type
 *
 * \brief The type of the axis.
 *
 * The value is one of AxisType values.
 */
QAbstract3DAxis::AxisType QAbstract3DAxis::type() const
{
    return d_ptr->m_type;
}

/*!
 * \property QAbstract3DAxis::title
 *
 * \brief The title for the axis.
 *
 * \sa titleVisible, titleFixed
 */
void QAbstract3DAxis::setTitle(const QString &title)
{
    if (d_ptr->m_title != title) {
        d_ptr->m_title = title;
        emit titleChanged(title);
    }
}

QString QAbstract3DAxis::title() const
{
    return d_ptr->m_title;
}

/*!
 * \property QAbstract3DAxis::labels
 *
 * \brief The labels for the axis.
 * \note Setting this property for QValue3DAxis does nothing, as it generates labels automatically.
 */
void QAbstract3DAxis::setLabels(const QStringList &labels)
{
    Q_UNUSED(labels)
}

QStringList QAbstract3DAxis::labels() const
{
    d_ptr->updateLabels();
    return d_ptr->m_labels;
}

/*!
 * Sets the value range of the axis from \a min to \a max.
 * When setting the range, the maximum value is adjusted if necessary, to ensure
 * that the range remains valid.
 * \note For QCategory3DAxis, specifies the index range of rows or columns to
 * show.
 */
void QAbstract3DAxis::setRange(float min, float max)
{
    d_ptr->setRange(min, max);
    setAutoAdjustRange(false);
}

/*!
 * \property QAbstract3DAxis::labelAutoRotation
 *
 * \brief The maximum angle the labels can autorotate when the camera angle changes.
 *
 * The angle can be between 0 and 90, inclusive. The default value is 0.
 * If the value is 0, axis labels do not automatically rotate.
 * If the value is greater than zero, labels attempt to orient themselves toward the camera, up to
 * the specified angle.
 */
void QAbstract3DAxis::setLabelAutoRotation(float angle)
{
    if (angle < 0.0f)
        angle = 0.0f;
    if (angle > 90.0f)
        angle = 90.0f;
    if (d_ptr->m_labelAutoRotation != angle) {
        d_ptr->m_labelAutoRotation = angle;
        emit labelAutoRotationChanged(angle);
    }
}

float QAbstract3DAxis::labelAutoRotation() const
{
    return d_ptr->m_labelAutoRotation;
}

/*!
 * \property QAbstract3DAxis::titleVisible
 *
 * \brief Whether the axis title is visible in the primary graph view.
 *
 * The default value is \c{false}.
 *
 * \sa title, titleFixed
 */
void QAbstract3DAxis::setTitleVisible(bool visible)
{
    if (d_ptr->m_titleVisible != visible) {
        d_ptr->m_titleVisible = visible;
        emit titleVisibilityChanged(visible);
    }
}

bool QAbstract3DAxis::isTitleVisible() const
{
    return d_ptr->m_titleVisible;
}

/*!
 * \property QAbstract3DAxis::titleFixed
 *
 * \brief The rotation of the axis titles.
 *
 * If \c{true}, axis titles in the primary graph view will be rotated towards the camera similarly
 * to the axis labels.
 * If \c{false}, axis titles are only rotated around their axis but are not otherwise oriented
 * towards the camera.
 * This property does not have any effect if the labelAutoRotation property
 * value is zero.
 * Default value is \c{true}.
 *
 * \sa labelAutoRotation, title, titleVisible
 */
void QAbstract3DAxis::setTitleFixed(bool fixed)
{
    if (d_ptr->m_titleFixed != fixed) {
        d_ptr->m_titleFixed = fixed;
        emit titleFixedChanged(fixed);
    }
}

bool QAbstract3DAxis::isTitleFixed() const
{
    return d_ptr->m_titleFixed;
}

/*!
 * \property QAbstract3DAxis::min
 *
 * \brief The minimum value on the axis.
 *
 * When setting this property, the maximum value is adjusted if necessary, to
 * ensure that the range remains valid.
 * \note For QCategory3DAxis, specifies the index of the first row or column to
 * show.
 */
void QAbstract3DAxis::setMin(float min)
{
    d_ptr->setMin(min);
    setAutoAdjustRange(false);
}

/*!
 * \property QAbstract3DAxis::max
 *
 * \brief The maximum value on the axis.
 *
 * When setting this property, the minimum value is adjusted if necessary, to
 * ensure that the range remains valid.
 * \note For QCategory3DAxis, specifies the index of the last row or column to
 * show.
 */
void QAbstract3DAxis::setMax(float max)
{
    d_ptr->setMax(max);
    setAutoAdjustRange(false);
}

float QAbstract3DAxis::min() const
{
    return d_ptr->m_min;
}

float QAbstract3DAxis::max() const
{
    return d_ptr->m_max;
}

/*!
 * \property QAbstract3DAxis::autoAdjustRange
 *
 * \brief Whether the axis will automatically adjust the range so that all data fits in it.
 *
 * \sa setRange(), setMin(), setMax()
 */
void QAbstract3DAxis::setAutoAdjustRange(bool autoAdjust)
{
    if (d_ptr->m_autoAdjust != autoAdjust) {
        d_ptr->m_autoAdjust = autoAdjust;
        emit autoAdjustRangeChanged(autoAdjust);
    }
}

bool QAbstract3DAxis::isAutoAdjustRange() const
{
    return d_ptr->m_autoAdjust;
}

/*!
 * \fn QAbstract3DAxis::rangeChanged(float min, float max)
 *
 * Emits the minimum and maximum values of the range, \a min and \a max, when
 * the range changes.
 */

// QAbstract3DAxisPrivate
QAbstract3DAxisPrivate::QAbstract3DAxisPrivate(QAbstract3DAxis *q, QAbstract3DAxis::AxisType type)
    : QObject(0),
      q_ptr(q),
      m_orientation(QAbstract3DAxis::AxisOrientationNone),
      m_type(type),
      m_isDefaultAxis(false),
      m_min(0.0f),
      m_max(10.0f),
      m_autoAdjust(true),
      m_labelAutoRotation(0.0f),
      m_titleVisible(false),
      m_titleFixed(true)
{
}

QAbstract3DAxisPrivate::~QAbstract3DAxisPrivate()
{
}

void QAbstract3DAxisPrivate::setOrientation(QAbstract3DAxis::AxisOrientation orientation)
{
    if (m_orientation == QAbstract3DAxis::AxisOrientationNone) {
        m_orientation = orientation;
        emit q_ptr->orientationChanged(orientation);
    } else {
        Q_ASSERT("Attempted to reset axis orientation.");
    }
}

void QAbstract3DAxisPrivate::updateLabels()
{
    // Default implementation does nothing
}

void QAbstract3DAxisPrivate::setRange(float min, float max, bool suppressWarnings)
{
    bool adjusted = false;
    if (!allowNegatives()) {
        if (allowZero()) {
            if (min < 0.0f) {
                min = 0.0f;
                adjusted = true;
            }
            if (max < 0.0f) {
                max = 0.0f;
                adjusted = true;
            }
        } else {
            if (min <= 0.0f) {
                min = 1.0f;
                adjusted = true;
            }
            if (max <= 0.0f) {
                max = 1.0f;
                adjusted = true;
            }
        }
    }
    // If min >= max, we adjust ranges so that
    // m_max becomes (min + 1.0f)
    // as axes need some kind of valid range.
    bool minDirty = false;
    bool maxDirty = false;
    if (m_min != min) {
        m_min = min;
        minDirty = true;
    }
    if (m_max != max || min > max || (!allowMinMaxSame() && min == max)) {
        if (min > max || (!allowMinMaxSame() && min == max)) {
            m_max = min + 1.0f;
            adjusted = true;
        } else {
            m_max = max;
        }
        maxDirty = true;
    }

    if (minDirty || maxDirty) {
        if (adjusted && !suppressWarnings) {
            qWarning() << "Warning: Tried to set invalid range for axis."
                          " Range automatically adjusted to a valid one:"
                       << min << "-" << max << "-->" << m_min << "-" << m_max;
        }
        emit q_ptr->rangeChanged(m_min, m_max);
    }

    if (minDirty)
        emit q_ptr->minChanged(m_min);
    if (maxDirty)
        emit q_ptr->maxChanged(m_max);
}

void QAbstract3DAxisPrivate::setMin(float min)
{
    if (!allowNegatives()) {
        if (allowZero()) {
            if (min < 0.0f) {
                min = 0.0f;
                qWarning() << "Warning: Tried to set negative minimum for an axis that only"
                              "supports positive values and zero:" << min;
            }
        } else {
            if (min <= 0.0f) {
                min = 1.0f;
                qWarning() << "Warning: Tried to set negative or zero minimum for an axis that only"
                              "supports positive values:" << min;
            }
        }
    }

    if (m_min != min) {
        bool maxChanged = false;
        if (min > m_max || (!allowMinMaxSame() && min == m_max)) {
            float oldMax = m_max;
            m_max = min + 1.0f;
            qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for"
                          " value axis. Maximum automatically adjusted to a valid one:"
                       << oldMax <<  "-->" << m_max;
            maxChanged = true;
        }
        m_min = min;

        emit q_ptr->rangeChanged(m_min, m_max);
        emit q_ptr->minChanged(m_min);
        if (maxChanged)
            emit q_ptr->maxChanged(m_max);
    }
}

void QAbstract3DAxisPrivate::setMax(float max)
{
    if (!allowNegatives()) {
        if (allowZero()) {
            if (max < 0.0f) {
                max = 0.0f;
                qWarning() << "Warning: Tried to set negative maximum for an axis that only"
                              "supports positive values and zero:" << max;
            }
        } else {
            if (max <= 0.0f) {
                max = 1.0f;
                qWarning() << "Warning: Tried to set negative or zero maximum for an axis that only"
                              "supports positive values:" << max;
            }
        }
    }

    if (m_max != max) {
        bool minChanged = false;
        if (m_min > max || (!allowMinMaxSame() && m_min == max)) {
            float oldMin = m_min;
            m_min = max - 1.0f;
            if (!allowNegatives() && m_min < 0.0f) {
                if (allowZero())
                    m_min = 0.0f;
                else
                    m_min = max / 2.0f; // Need some positive value smaller than max

                if (!allowMinMaxSame() && max == 0.0f) {
                    m_min = oldMin;
                    qWarning() << "Unable to set maximum value to zero.";
                    return;
                }
            }
            qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for"
                          " value axis. Minimum automatically adjusted to a valid one:"
                       << oldMin <<  "-->" << m_min;
            minChanged = true;
        }
        m_max = max;
        emit q_ptr->rangeChanged(m_min, m_max);
        emit q_ptr->maxChanged(m_max);
        if (minChanged)
            emit q_ptr->minChanged(m_min);
    }
}

QT_END_NAMESPACE_DATAVISUALIZATION
