/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtSensors module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or 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.GPL2 and 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-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsensorbackend.h"
#include "qsensorbackend_p.h"
#include "qsensor_p.h"
#include <QDebug>

QT_BEGIN_NAMESPACE

/*!
    \class QSensorBackend
    \ingroup sensors_backend
    \inmodule QtSensors
    \since 5.1

    \brief The QSensorBackend class is a sensor implementation.

    Sensors on a device will be represented by sub-classes of
    QSensorBackend.
*/

/*!
    \internal
*/
QSensorBackend::QSensorBackend(QSensor *sensor, QObject *parent)
    : QObject(*new QSensorBackendPrivate(sensor), parent)
{
}

/*!
    \internal
*/
QSensorBackend::~QSensorBackend()
{
}

/*!
   Checks whether a feature is supported by this sensor backend.

   This is the backend side of QSensor::isFeatureSupported(). Reimplement this function if the
   backend supports one of the additional sensor features of QSensor::Feature.

   Returns whether the feature \a feature is supported by this backend. The default implementation returns false.
   \since 5.0
 */
bool QSensorBackend::isFeatureSupported(QSensor::Feature feature) const
{
    Q_UNUSED(feature);
    return false;
}

/*!
    Notify the QSensor class that a new reading is available.
*/
void QSensorBackend::newReadingAvailable()
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();

    // Copy the values from the device reading to the filter reading
    sensorPrivate->filter_reading->copyValuesFrom(sensorPrivate->device_reading);

    for (QFilterList::const_iterator it = sensorPrivate->filters.constBegin(); it != sensorPrivate->filters.constEnd(); ++it) {
        QSensorFilter *filter = (*it);
        if (!filter->filter(sensorPrivate->filter_reading))
            return;
    }

    // Copy the values from the filter reading to the cached reading
    sensorPrivate->cache_reading->copyValuesFrom(sensorPrivate->filter_reading);

    Q_EMIT d->m_sensor->readingChanged();
}

/*!
    \fn QSensorBackend::start()

    Start reporting values.
*/

/*!
    \fn QSensorBackend::stop()

    Stop reporting values.
*/

/*!
    If the backend has lost its reference to the reading
    it can call this method to get the address.

    Note that you will need to down-cast to the appropriate
    type.

    \sa setReading()
*/
QSensorReading *QSensorBackend::reading() const
{
    Q_D(const QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    return sensorPrivate->device_reading;
}

/*!
    Returns the sensor front end associated with this backend.
*/
QSensor *QSensorBackend::sensor() const
{
    Q_D(const QSensorBackend);
    return d->m_sensor;
}

/*!
    \fn template <typename T> T *QSensorBackend::setReading(T *reading)

    This function is called to initialize the \a reading
    classes used for a sensor.

    If your backend has already allocated a reading you
    should pass the address of this to the function.
    Otherwise you should pass 0 and the function will
    return the address of the reading your backend
    should use when it wants to notify the sensor API
    of new readings.

    Note that this is a template function so it should
    be called with the appropriate type.

    \code
    class MyBackend : public QSensorBackend
    {
        QAccelerometerReading m_reading;
    public:
        MyBackend(QSensor *sensor)
            : QSensorBackend(sensor)
        {
            setReading<QAccelerometerReading>(&m_reading);
        }

        ...
    \endcode

    Note that this function must be called or you will
    not be able to send readings to the front end.

    If you do not wish to store the address of the reading
    you may use the reading() method to get it again later.

    \code
    class MyBackend : public QSensorBackend
    {
    public:
        MyBackend(QSensor *sensor)
            : QSensorBackend(sensor)
        {
            setReading<QAccelerometerReading>(0);
        }

        void poll()
        {
            quint64 timestamp;
            qreal x, y, z;
            ...
            QAccelerometerReading *reading = static_cast<QAccelerometerReading*>(reading());
            reading->setTimestamp(timestamp);
            reading->setX(x);
            reading->setY(y);
            reading->setZ(z);
        }

        ...
    \endcode

    \sa reading()
*/

/*!
    \internal
*/
void QSensorBackend::setReadings(QSensorReading *device, QSensorReading *filter, QSensorReading *cache)
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->device_reading = device;
    sensorPrivate->filter_reading = filter;
    sensorPrivate->cache_reading = cache;
}

/*!
    Add a data rate (consisting of \a min and \a max values) for the sensor.

    Note that this function should be called from the constructor so that the information
    is available immediately.

    \sa QSensor::availableDataRates
*/
void QSensorBackend::addDataRate(qreal min, qreal max)
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->availableDataRates << qrange(min, max);
}

/*!
    Set the data rates for the sensor based on \a otherSensor.

    This is designed for sensors that are based on other sensors.

    \code
    setDataRates(otherSensor);
    \endcode

    Note that this function must be called from the constructor.

    \sa QSensor::availableDataRates, addDataRate()
*/
void QSensorBackend::setDataRates(const QSensor *otherSensor)
{
    Q_D(QSensorBackend);
    if (!otherSensor) {
        qWarning() << "ERROR: Cannot call QSensorBackend::setDataRates with 0";
        return;
    }
    if (otherSensor->identifier().isEmpty()) {
        qWarning() << "ERROR: Cannot call QSensorBackend::setDataRates with an invalid sensor";
        return;
    }
    if (d->m_sensor->isConnectedToBackend()) {
        qWarning() << "ERROR: Cannot call QSensorBackend::setDataRates outside of the constructor";
        return;
    }
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->availableDataRates = otherSensor->availableDataRates();
}

/*!
    Add an output range (consisting of \a min, \a max values and \a accuracy) for the sensor.

    Note that this function should be called from the constructor so that the information
    is available immediately.

    \sa QSensor::outputRange, QSensor::outputRanges
*/
void QSensorBackend::addOutputRange(qreal min, qreal max, qreal accuracy)
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();

    qoutputrange details = {min, max, accuracy};

    sensorPrivate->outputRanges << details;
}

/*!
    Set the \a description for the sensor.

    Note that this function should be called from the constructor so that the information
    is available immediately.
*/
void QSensorBackend::setDescription(const QString &description)
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->description = description;
}

/*!
    Inform the front end that the sensor has stopped.
    This can be due to start() failing or for some
    unexpected reason (eg. hardware failure).

    Note that the front end must call QSensor::isActive() to see if
    the sensor has stopped. If the sensor has stopped due to an error
    the sensorError() function should be called to notify the class
    of the error condition.
*/
void QSensorBackend::sensorStopped()
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->active = false;
}

/*!
    Inform the front end that the sensor is busy.
    This implicitly calls sensorStopped() and
    is typically called from start().

    Note that the front end must call QSensor::isBusy() to see if
    the sensor is busy. If the sensor has stopped due to an error
    the sensorError() function should be called to notify the class
    of the error condition.
*/
void QSensorBackend::sensorBusy()
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->active = false;
    sensorPrivate->busy = true;
}

/*!
    Inform the front end that a sensor error occurred.
    Note that this only reports an \a error code. It does
    not stop the sensor.

    \sa sensorStopped()
*/
void QSensorBackend::sensorError(int error)
{
    Q_D(QSensorBackend);
    QSensorPrivate *sensorPrivate = d->m_sensor->d_func();
    sensorPrivate->error = error;
    Q_EMIT d->m_sensor->sensorError(error);
}

QT_END_NAMESPACE

#include "moc_qsensorbackend.cpp"
