/****************************************************************************
**
** 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 "qsensor.h"
#include "qsensor_p.h"
#include "qsensorbackend.h"
#include "qsensormanager.h"
#include <QDebug>
#include <QMetaProperty>
#include <QTimer>

QT_BEGIN_NAMESPACE

/*!
    \typedef qrange
    \relates QSensor
    \since 5.1

    This type is defined as a QPair.

    \code
    typedef QPair<int,int> qrange;
    \endcode

    \sa QPair, qrangelist, QSensor::availableDataRates
*/

/*!
    \typedef qrangelist
    \relates QSensor
    \since 5.1

    This type is defined as a list of qrange values.

    \code
    typedef QList<qrange> qrangelist;
    \endcode

    \sa QList, qrange, QSensor::availableDataRates
*/

/*!
    \class qoutputrange
    \inmodule QtSensors
    \brief The qoutputrange class holds the specifics of an output range.
    \since 5.1

    The class is defined as a simple struct.

    \code
    struct qoutputrange
    {
        qreal maximum;
        qreal minimum;
        qreal accuracy;
    };
    \endcode

    Each output range specifies a minimum and maximum value as well as an accuracy value.
    The accuracy value represents the resolution of the sensor. It is the smallest change
    the sensor can detect and is expressed using the same units as the minimum and maximum.

    Sensors must often trade off range for accuracy. To allow the user to determine which of
    these are more important the sensor may offer several output ranges. One output
    range may have reduced minimum and maximum values and increased sensitivity. Another output
    range may have higher minimum and maximum values with reduced sensitivity. Note that higher
    sensitivities will be represented by smaller accuracy values.

    An example of this tradeoff can be seen by examining the LIS302DL accelerometer. It has only
    256 possible values to report with. These values are scaled so that they can represent either
    -2G to +2G (with an accuracy value of 0.015G) or -8G to +8G (with an accuracy value of 0.06G).

    \sa qoutputrangelist, QSensor::outputRanges
*/

/*!
    \variable qoutputrange::maximum

    This is the maximum value for this output range.
    The units are defined by the sensor.
*/

/*!
    \variable qoutputrange::minimum

    This is the minimum value for this output range.
    The units are defined by the sensor.
*/

/*!
    \variable qoutputrange::accuracy

    The accuracy value represents the resolution of the sensor. It is the smallest change
    the sensor can detect and is expressed using the same units as the minimum and maximum.
*/

/*!
    \typedef qoutputrangelist
    \relates QSensor
    \since 5.1

    This type is defined as a list of qoutputrange values.

    \code
    typedef QList<qoutputrange> qoutputrangelist;
    \endcode

    \sa QList, qoutputrange, QSensor::outputRanges
*/

static void registerTypes()
{
    qRegisterMetaType<qrange>("qrange");
    qRegisterMetaType<qrangelist>("qrangelist");
    qRegisterMetaType<qoutputrangelist>("qoutputrangelist");
}
Q_CONSTRUCTOR_FUNCTION(registerTypes)

// =====================================================================

void QSensorPrivate::init(const QByteArray &sensorType)
{
    Q_Q(QSensor);
    type = sensorType;
    q->registerInstance(); // so the availableSensorsChanged() signal works
}

/*!
    \class QSensor
    \ingroup sensors_main
    \inmodule QtSensors
    \since 5.1

    \brief The QSensor class represents a single hardware sensor.

    The life cycle of a sensor is typically:

    \list
    \li Create a sub-class of QSensor on the stack or heap.
    \li Setup as required by the application.
    \li Start receiving values.
    \li Sensor data is used by the application.
    \li Stop receiving values.
    \endlist

    The sensor data is delivered via QSensorReading and its sub-classes.

    \section1 Orientation

    Some sensors react to screen orientation changes, such as QAccelerometer, QMagnetometer and
    QRotationSensor. These are so called \e orientable sensors. For orientable sensors,
    QSensor supports changing the reporting of the reading values based on the orientation of the
    screen.

    For orientable sensors, the axesOrientationMode property controls how the orientation affects
    the reading values.

    In the default mode, QSensor::FixedOrientation, the reading values remain
    unaffected by the orientation. In the QSensor::AutomaticOrientation mode, the reading
    values are automatically rotated by taking the current screen orientation into account. And
    finally, in the QSensor::UserOrientation mode, the reading values are rotated
    according to a user-specified orientation.

    The functionality of this is only available if it is supported by the backend and if the sensor
    is orientable, which can be checked by calling QSensor::isFeatureSupported()
    with the QSensor::AxesOrientation flag.

    The orientation values here are always of the screen orientation, not the device orientation.
    The screen orientation is the orientation of the GUI. For example when rotating a device by 90
    degrees counter-clockwise, the screen orientation compensates for that by rotating 90 degrees
    clockwise, to the effect that the GUI is still facing upright after the device has been rotated.
    Note that applications can lock the screen orientation, for example to force portrait or landscape
    mode. For locked orientations, orientable sensors will not react with reading changes if the device
    orientation is changed, as orientable sensors react to screen orientation changes only. This makes
    sense, as the purpose of orientable sensors is to keep the sensor orientation in sync with the screen
    orientation.

    The orientation values range from 0 to 270 degrees. The orientation is applied in clockwise direction,
    e.g. an orientation value of 90 degrees means that the screen has been rotated 90 degress to the right
    from its origin position, to compensate a device rotation of 90 degrees to the left.

    \sa QSensorReading
*/

/*!
    \enum QSensor::Feature
    \brief Lists optional features a backend might support.

    The features common to all sensor types are:

    \value Buffering The backend supports buffering of readings, controlled by the
                     QSensor::bufferSize property.
    \value AlwaysOn The backend supports changing the policy on whether to suspend when idle,
                    controlled by the QSensor::alwaysOn property.
    \value SkipDuplicates The backend supports skipping of same or very similar successive
                          readings. This can be enabled by setting the QSensor::skipDuplicates
                          property to true.

    The features of QMagnetometer are:

    \value GeoValues The backend supports returning geo values, which can be
                     controlled with the QMagnetometer::returnGeoValues property.

    The features of QLightSensor are:

    \value FieldOfView The backend specifies its field of view, which can be
                       read from the QLightSensor::fieldOfView property.

    The features of QAccelerometer are:

    \value AccelerationMode The backend supports switching the acceleration mode
                            of the acceleromter with the QAccelerometer::accelerationMode property.

    The features of QPressureSensor are:

    \value PressureSensorTemperature The backend provides the pressure sensor's die temperature

    The features of all orientable sensors are:

    \value AxesOrientation The backend supports changing the axes orientation from the default of
                           QSensor::FixedOrientation to something else.

    \omitvalue Reserved

    \sa QSensor::isFeatureSupported()
    \since 5.0
*/

/*!
    Construct the \a type sensor as a child of \a parent.

    Do not use this constructor if a derived class exists for the specific sensor type.

    The wrong way is to use the base class constructor:
    \snippet sensors/creating.cpp 3
    The right way is to create an instance of the derived class:
    \snippet sensors/creating.cpp 2

    The derived classes have
    additional properties and data members which are needed for certain features such as
    geo value support in QMagnetometer or acceleration mode support in QAccelerometer.
    These features will only work properly when creating a sensor instance from a QSensor
    subclass.

    Only use this constructor if there is no derived sensor class available. Note that all
    built-in sensors have a derived class, so using this constructor should only be necessary
    when implementing custom sensors, like in the \l {Qt Sensors - Grue Sensor Example}{Grue sensor example}.
*/
QSensor::QSensor(const QByteArray &type, QObject *parent)
    : QObject(*new QSensorPrivate, parent)
{
    Q_D(QSensor);
    d->init(type);
}

/*! \internal
 */
QSensor::QSensor(const QByteArray &type, QSensorPrivate &dd, QObject* parent)
    : QObject(dd, parent)
{
    Q_D(QSensor);
    d->init(type);
}

/*! \internal
 */
QSensorBackend *QSensor::backend() const
{
    Q_D(const QSensor);
    return d->backend;
}

/*!
    Destroy the sensor. Stops the sensor if it has not already been stopped.
*/
QSensor::~QSensor()
{
    Q_D(QSensor);
    stop();
    Q_FOREACH (QSensorFilter *filter, d->filters)
        filter->setSensor(0);
    delete d->backend;
    d->backend = 0;
    // owned by the backend
    d->device_reading = 0;
    d->filter_reading = 0;
    d->cache_reading = 0;
}

/*!
    \property QSensor::connectedToBackend
    \brief a value indicating if the sensor has connected to a backend.

    A sensor that has not been connected to a backend cannot do anything useful.

    Call the connectToBackend() method to force the sensor to connect to a backend
    immediately. This is automatically called if you call start() so you only need
    to do this if you need access to sensor properties (ie. to poll the sensor's
    meta-data before you use it).
*/

bool QSensor::isConnectedToBackend() const
{
    Q_D(const QSensor);
    return (d->backend != 0);
}

/*!
    \property QSensor::identifier
    \brief the backend identifier for the sensor.

    Note that the identifier is filled out automatically
    when the sensor is connected to a backend. If you want
    to connect a specific backend, you should call
    setIdentifier() before connectToBackend().
*/

QByteArray QSensor::identifier() const
{
    Q_D(const QSensor);
    return d->identifier;
}

void QSensor::setIdentifier(const QByteArray &identifier)
{
    Q_D(QSensor);
    if (isConnectedToBackend()) {
        qWarning() << "ERROR: Cannot call QSensor::setIdentifier while connected to a backend!";
        return;
    }
    d->identifier = identifier;
}

/*!
    \property QSensor::type
    \brief the type of the sensor.
*/

QByteArray QSensor::type() const
{
    Q_D(const QSensor);
    return d->type;
}

/*!
    Try to connect to a sensor backend.

    Returns true if a suitable backend could be found, false otherwise.

    The type must be set before calling this method if you are using QSensor directly.

    \sa isConnectedToBackend()
*/
bool QSensor::connectToBackend()
{
    Q_D(QSensor);
    if (isConnectedToBackend())
        return true;

    int dataRate = d->dataRate;
    int outputRange = d->outputRange;

    d->backend = QSensorManager::createBackend(this);

    if (d->backend) {
        // Reset the properties to their default values and re-set them now so
        // that the logic we've put into the setters gets called.
        if (dataRate != 0) {
            d->dataRate = 0;
            setDataRate(dataRate);
        }
        if (outputRange != -1) {
            d->outputRange = -1;
            setOutputRange(outputRange);
        }
    }

    return isConnectedToBackend();
}

/*!
    \property QSensor::busy
    \brief a value to indicate if the sensor is busy.

    Some sensors may be on the system but unavailable for use.
    This function will return true if the sensor is busy. You
    will not be able to start() the sensor.

    Note that this function does not return true if you
    are using the sensor, only if another process is using
    the sensor.

    \sa busyChanged()
*/

bool QSensor::isBusy() const
{
    Q_D(const QSensor);
    return d->busy;
}

/*!
    \fn QSensor::busyChanged()

    This signal is emitted when the sensor is no longer busy.
    This can be used to grab a sensor when it becomes available.

    \code
    sensor.start();
    if (sensor.isBusy()) {
        // need to wait for busyChanged signal and try again
    }
    \endcode
*/

/*!
    \property QSensor::active
    \brief a value to indicate if the sensor is active.

    This is true if the sensor is active (returning values). This is false otherwise.

    Note that setting this value to true will not have an immediate effect. Instead,
    the sensor will be started once the event loop has been reached.
*/
void QSensor::setActive(bool active)
{
    if (active == isActive())
        return;

    if (active)
        QTimer::singleShot(0, this, SLOT(start())); // delay ensures all properties have been set if using QML
    else
        stop();
}

bool QSensor::isActive() const
{
    Q_D(const QSensor);
    return d->active;
}

/*!
    \property QSensor::alwaysOn
    \brief a value to indicate if the sensor should remain running when the screen is off.

    Some platforms have a policy of suspending sensors when the screen turns off.
    Setting this property to true will ensure the sensor continues to run.
*/
/*!
    \fn QSensor::alwaysOnChanged()

    This signal is emitted when the alwaysOn property changes.
*/
void QSensor::setAlwaysOn(bool alwaysOn)
{
    Q_D(QSensor);
    if (d->alwaysOn == alwaysOn) return;
    d->alwaysOn = alwaysOn;
    emit alwaysOnChanged();
}

bool QSensor::isAlwaysOn() const
{
    Q_D(const QSensor);
    return d->alwaysOn;
}

/*!
    \property QSensor::skipDuplicates
    \brief Indicates whether duplicate reading values should be omitted.
    \since 5.1

    When duplicate skipping is enabled, successive readings with the same or very
    similar values are omitted. This helps reducing the amount of processing done, as less sensor
    readings are made available. As a consequence, readings arrive at an irregular interval.

    Duplicate skipping is not just enabled for readings that are exactly the same, but also for
    readings that are quite similar, as each sensor has a bit of jitter even if the device is
    not moved.

    Support for this property depends on the backend. Use isFeatureSupported() to check if it is
    supported on the current platform.

    Duplicate skipping is disabled by default.

    Duplicate skipping takes effect when the sensor is started, changing the property while the
    sensor is active has no immediate effect.
*/
bool QSensor::skipDuplicates() const
{
    Q_D(const QSensor);
    return d->skipDuplicates;
}

/*!
    Sets the duplicate skipping to \a skipDuplicates.

    \since 5.1
*/
void QSensor::setSkipDuplicates(bool skipDuplicates)
{
    Q_D(QSensor);
    if (d->skipDuplicates != skipDuplicates) {
        d->skipDuplicates = skipDuplicates;
        emit skipDuplicatesChanged(skipDuplicates);
    }
}

/*!
    \fn QSensor::skipDuplicatesChanged(bool skipDuplicates)
    \since 5.1

    This signal is emitted when the \a skipDuplicates property changes.
*/

/*!
    \property QSensor::availableDataRates
    \brief the data rates that the sensor supports.

    This is a list of the data rates that the sensor supports.
    Measured in Hertz.

    Entries in the list can represent discrete rates or a
    continuous range of rates.
    A discrete rate is noted by having both values the same.

    See the sensor_explorer example for an example of how to interpret and use
    this information.

    Note that this information is not mandatory as not all sensors have a rate at which
    they run. In such cases, the list will be empty.

    \sa QSensor::dataRate, qrangelist
*/

qrangelist QSensor::availableDataRates() const
{
    Q_D(const QSensor);
    return d->availableDataRates;
}

/*!
    \property QSensor::dataRate
    \brief the data rate that the sensor should be run at.

    Measured in Hertz.

    The data rate is the maximum frequency at which the sensor can detect changes.

    Setting this property is not portable and can cause conflicts with other
    applications. Check with the sensor backend and platform documentation for
    any policy regarding multiple applications requesting a data rate.

    The default value (0) means that the app does not care what the data rate is.
    Applications should consider using a timer-based poll of the current value or
    ensure that the code that processes values can run very quickly as the platform
    may provide updates hundreds of times each second.

    This should be set before calling start() because the sensor may not
    notice changes to this value while it is running.

    Note that there is no mechanism to determine the current data rate in use by the
    platform.

    \sa QSensor::availableDataRates
*/

int QSensor::dataRate() const
{
    Q_D(const QSensor);
    return d->dataRate;
}

void QSensor::setDataRate(int rate)
{
    Q_D(QSensor);
    if (d->dataRate != rate) {
        d->dataRate = rate;
        emit dataRateChanged();
    }
}

/*!
   Checks if a specific feature is supported by the backend.

   QtSensors supports a rich API for controlling and providing information about sensors. Naturally,
   not all of this functionality can be supported by all of the backends.

   To check if the current backend supports the feature \a feature, call this function.

   The backend needs to be connected, otherwise false will be returned. Calling connectToBackend()
   or start() will create a connection to the backend.

   Backends have to implement QSensorBackend::isFeatureSupported() to make this work.

   Returns whether or not the feature is supported if the backend is connected, or false if the backend is not connected.
   \since 5.0
 */
bool QSensor::isFeatureSupported(Feature feature) const
{
    Q_D(const QSensor);
    return d->backend && d->backend->isFeatureSupported(feature);
}

/*!
    Start retrieving values from the sensor.
    Returns true if the sensor was started, false otherwise.

    The sensor may fail to start for several reasons.

    Once an application has started a sensor it must wait until the sensor receives a
    new value before it can query the sensor's values. This is due to how the sensor
    receives values from the system. Sensors do not (in general) poll for new values,
    rather new values are pushed to the sensors as they happen.

    For example, this code will not work as intended.

    \badcode
    sensor->start();
    sensor->reading()->x(); // no data available
    \endcode

    To work correctly, the code that accesses the reading should ensure the
    readingChanged() signal has been emitted.

    \code
        connect(sensor, SIGNAL(readingChanged()), this, SLOT(checkReading()));
        sensor->start();
    }
    void MyClass::checkReading() {
        sensor->reading()->x();
    \endcode

    \sa QSensor::busy
*/
bool QSensor::start()
{
    Q_D(QSensor);
    if (isActive())
        return true;
    if (!connectToBackend())
        return false;
    // Set these flags to their defaults
    d->active = true;
    d->busy = false;
    // Backend will update the flags appropriately
    d->backend->start();
    Q_EMIT activeChanged();
    return isActive();
}

/*!
    Stop retrieving values from the sensor.

    This releases the sensor so that other processes can use it.

    \sa QSensor::busy
*/
void QSensor::stop()
{
    Q_D(QSensor);
    if (!isConnectedToBackend() || !isActive())
        return;
    d->active = false;
    d->backend->stop();
    Q_EMIT activeChanged();
}

/*!
    \property QSensor::reading
    \brief the reading class.

    The reading class provides access to sensor readings. The reading object
    is a volatile cache of the most recent sensor reading that has been received
    so the application should process readings immediately or save the values
    somewhere for later processing.

    Note that this will return 0 until a sensor backend is connected to a backend.

    Also note that readings are not immediately available after start() is called.
    Applications must wait for the readingChanged() signal to be emitted.

    \sa isConnectedToBackend(), start()
*/

QSensorReading *QSensor::reading() const
{
    Q_D(const QSensor);
    return d->cache_reading;
}

/*!
    Add a \a filter to the sensor.

    The sensor does not take ownership of the filter.
    QSensorFilter will inform the sensor if it is destroyed.

    \sa QSensorFilter
*/
void QSensor::addFilter(QSensorFilter *filter)
{
    Q_D(QSensor);
    if (!filter) {
        qWarning() << "addFilter: passed a null filter!";
        return;
    }
    filter->setSensor(this);
    d->filters << filter;
}

/*!
    Remove \a filter from the sensor.

    \sa QSensorFilter
*/
void QSensor::removeFilter(QSensorFilter *filter)
{
    Q_D(QSensor);
    if (!filter) {
        qWarning() << "removeFilter: passed a null filter!";
        return;
    }
    d->filters.removeOne(filter);
    filter->setSensor(0);
}

/*!
    Returns the filters currently attached to the sensor.

    \sa QSensorFilter
*/
QList<QSensorFilter*> QSensor::filters() const
{
    Q_D(const QSensor);
    return d->filters;
}

/*!
    \fn QSensor::readingChanged()

    This signal is emitted when a new sensor reading is received.

    The sensor reading can be found in the QSensor::reading property. Note that the
    reading object is a volatile cache of the most recent sensor reading that has
    been received so the application should process the reading immediately or
    save the values somewhere for later processing.

    Before this signal has been emitted for the first time, the reading object will
    have uninitialized data.

    \sa start()
*/

/*!
    \fn QSensor::activeChanged()

    This signal is emitted when the QSensor::active property has changed.

    \sa QSensor::active
*/

/*!
    \property QSensor::outputRanges
    \brief a list of output ranges the sensor supports.

    A sensor may have more than one output range. Typically this is done
    to give a greater measurement range at the cost of lowering accuracy.

    Note that this information is not mandatory. This information is typically only
    available for sensors that have selectable output ranges (such as typical
    accelerometers).

    \sa QSensor::outputRange, qoutputrangelist
*/

qoutputrangelist QSensor::outputRanges() const
{
    Q_D(const QSensor);
    return d->outputRanges;
}

/*!
    \property QSensor::outputRange
    \brief the output range in use by the sensor.

    This value represents the index in the QSensor::outputRanges list to use.

    Setting this property is not portable and can cause conflicts with other
    applications. Check with the sensor backend and platform documentation for
    any policy regarding multiple applications requesting an output range.

    The default value (-1) means that the app does not care what the output range is.

    Note that there is no mechanism to determine the current output range in use by the
    platform.

    \sa QSensor::outputRanges
*/

int QSensor::outputRange() const
{
    Q_D(const QSensor);
    return d->outputRange;
}

void QSensor::setOutputRange(int index)
{
    Q_D(QSensor);
    if (index == -1 || !isConnectedToBackend()) {
        d->outputRange = index;
        return;
    }
    bool warn = true;
    if (index >= 0 && index < d->outputRanges.count()) {
        warn = false;
        d->outputRange = index;
    }
    if (warn) {
        qWarning() << "setOutputRange:" << index << "is not supported by the sensor.";
    }
}

/*!
    \property QSensor::description
    \brief a descriptive string for the sensor.
*/

QString QSensor::description() const
{
    Q_D(const QSensor);
    return d->description;
}

/*!
    \property QSensor::error
    \brief the last error code set on the sensor.

    Note that error codes are sensor-specific.
*/

int QSensor::error() const
{
    Q_D(const QSensor);
    return d->error;
}

/*!
    \enum QSensor::AxesOrientationMode
    \since 5.1

    Describes how reading values are affected by the screen orientation.

    \value FixedOrientation No automatic rotation is applied to the reading values.

    \value AutomaticOrientation The reading values are automatically rotated based on the screen
                                orientation.

    \value UserOrientation The reading values are rotated based on the angle of the userOrientation property.

    \sa QSensor::axesOrientationMode
*/

/*!
    \property QSensor::axesOrientationMode
    \since 5.1
    \brief The mode that affects how the screen orientation changes reading values.

    When set to FixedOrientation, which is the default mode, no automatic rotation is applied to
    the reading. This is the only mode available for backends that do not support the
    QSensor::AxesOrientation feature.

    When set to AutomaticOrientation, the reading values are automatically rotated when the
    screen orientation changes. In effect, the screen orientation is canceled out.

    As an example, assume the device is rotated by 180 degrees and therefore the screen orientation
    also is rotated by 180 degrees from the native orientation. Without automatic axes orientation,
    the reading values would now be changed: Both the X and the Y values would be negated, forcing
    an application developer to manually cancel out the negation in application code. Automatic
    axes orientation does this automatically, in this mode the X and Y values would be the same as
    with the default screen orientation.

    This automatic rotation of the axes is handy is some usecases, for example in a bubble level
    application that measures how level a surface is by looking at the X axis value of an
    accelerometer. When the device and screen orientation change by 90 degrees, an application
    developer does not need to change anything, he can continue using the X axis value even though
    the device is rotated. Without automatic axes orientation, the application developer would need
    to look at the Y values instead, thereby adding code to the application that reads from a
    different axis depending on the screen orientation.

    The UserOrientation mode is quite similar to AutomaticOrientation, only that the screen orientation
    is manually controlled instead of automatically determined. The angle of the userOrientation
    property is then used for rotating the reading values.

    Since the rotation of the reading values is based on the screen orientation, Z values will never
    change, as the Z axis is perpendicular to the screen.
    As screen orientation changes in 90 degree steps, rotating the reading values is also done in
    steps of 90 degrees.

    This property is only used for orientable sensors.
*/

QSensor::AxesOrientationMode QSensor::axesOrientationMode() const
{
    Q_D(const QSensor);
    return d->axesOrientationMode;
}

void QSensor::setAxesOrientationMode(QSensor::AxesOrientationMode axesOrientationMode)
{
    Q_D(QSensor);
    if (d->axesOrientationMode != axesOrientationMode) {
        d->axesOrientationMode = axesOrientationMode;
        emit axesOrientationModeChanged(axesOrientationMode);
    }
}

/*!
    \property QSensor::currentOrientation
    \since 5.1
    \brief The current orientation that is used for rotating the reading values.

    This might not be the same as the screen orientation. For example, in the FixedOrientation mode,
    the reading values are not rotated, and therefore the property is 0.

    In the UserOrientation mode, the readings are rotated based on the userOrientation property,
    and therefore this property is equal to the userOrientation property.

    In the AutomaticOrientation mode, the readings are rotated based on the screen orientation,
    and therefore this property will be equal to the current screen orientation.

    This property is set by the backend and only valid for orientable sensors.
*/

int QSensor::currentOrientation() const
{
    Q_D(const QSensor);
    return d->currentOrientation;
}

/*!
    \since 5.1
    Sets the current screen orientation to \a currentOrientation. This is to be called from the
    backend whenever the screen orientation or the userOrientation property changes.
*/
void QSensor::setCurrentOrientation(int currentOrientation)
{
    Q_D(QSensor);
    if (d->currentOrientation != currentOrientation) {
        d->currentOrientation = currentOrientation;
        emit currentOrientationChanged(currentOrientation);
    }
}

/*!
    \property QSensor::userOrientation
    \since 5.1
    \brief The angle used for rotating the reading values in the UserOrientation mode.

    When the axesOrientationMode property is set to UserOrientation, the angle for rotating the
    reading values is taken from this property. In other modes, the property has no effect.

    The default is 0. The only valid values are 0, 90, 180 and 270, as those are the only possible
    screen orientations.

    This property is only valid for orientable sensors.
*/

int QSensor::userOrientation() const
{
    Q_D(const QSensor);
    return d->userOrientation;
}

void QSensor::setUserOrientation(int userOrientation)
{
    Q_D(QSensor);
    if (d->userOrientation != userOrientation) {
        d->userOrientation = userOrientation;
        emit userOrientationChanged(userOrientation);
    }
}

/*!
    \fn QSensor::sensorError(int error)

    This signal is emitted when an \a error code is set on the sensor.
    Note that some errors will cause the sensor to stop working.
    You should call isActive() to determine if the sensor is still running.
*/

/*!
    \fn QSensor::availableSensorsChanged()

    This signal is emitted when the list of available sensors has changed.
    The sensors available to a program will not generally change over time
    however some of the available sensors may represent hardware that is not
    permanently connected. For example, a game controller that is connected
    via bluetooth would become available when it was on and would become
    unavailable when it was off.

    \sa QSensor::sensorTypes(), QSensor::sensorsForType()
*/

/*!
    \property QSensor::maxBufferSize

    The property holds the maximum buffer size.

    Note that this may be 1, in which case the sensor does not support any form of buffering.
    In that case, isFeatureSupported(QSensor::Buffering) will also return false.

    \sa QSensor::bufferSize, QSensor::efficientBufferSize
*/

int QSensor::maxBufferSize() const
{
    Q_D(const QSensor);
    return d->maxBufferSize;
}

/*!
    \since 5.1
    Sets the maximum buffer size to \a maxBufferSize. This is to be called from the
    backend.
*/
void QSensor::setMaxBufferSize(int maxBufferSize)
{
    Q_D(QSensor);
    if (d->maxBufferSize != maxBufferSize) {
        d->maxBufferSize = maxBufferSize;
        emit maxBufferSizeChanged(maxBufferSize);
    }
}

/*!
    \property QSensor::efficientBufferSize

    The property holds the most efficient buffer size. Normally this is 1 (which means
    no particular size is most efficient). Some sensor drivers have a FIFO buffer which
    makes it more efficient to deliver the FIFO's size worth of readings at one time.

    \sa QSensor::bufferSize, QSensor::maxBufferSize
*/

int QSensor::efficientBufferSize() const
{
    Q_D(const QSensor);
    return d->efficientBufferSize;
}

/*!
    \since 5.1
    Sets the efficient buffer size to \a efficientBufferSize. This is to be called from the
    backend.
*/
void QSensor::setEfficientBufferSize(int efficientBufferSize)
{
    Q_D(QSensor);
    if (d->efficientBufferSize != efficientBufferSize) {
        d->efficientBufferSize = efficientBufferSize;
        emit efficientBufferSizeChanged(efficientBufferSize);
    }
}

/*!
    \property QSensor::bufferSize

    This property holds the size of the buffer. By default, the buffer size is 1,
    which means no buffering.
    If the maximum buffer size is 1, then buffering is not supported
    by the sensor.

    Setting bufferSize greater than maxBufferSize will cause maxBufferSize to be used.

    Buffering is turned on when bufferSize is greater than 1. The sensor will collect
    the requested number of samples and deliver them all to the application at one time.
    They will be delivered to the application as a burst of changed readings so it is
    particularly important that the application processes each reading immediately or
    saves the values somewhere else.

    If stop() is called when buffering is on-going, the partial buffer is not delivered.

    When the sensor is started with buffering option, values are collected from that
    moment onwards. There is no pre-existing buffer that can be utilized.

    Some backends only support enabling or disabling the buffer and do not give
    control over the size. In this case, the maxBufferSize and efficientBufferSize properties
    might not be set at all, even though buffering is supported. Setting the bufferSize property
    to any value greater than 1 will enable buffering. After the sensor has been started,
    the bufferSize property will be set to the actual value by the backend.

    \sa QSensor::maxBufferSize, QSensor::efficientBufferSize
*/

int QSensor::bufferSize() const
{
    Q_D(const QSensor);
    return d->bufferSize;
}

void QSensor::setBufferSize(int bufferSize)
{
    Q_D(QSensor);
    if (d->bufferSize != bufferSize) {
        d->bufferSize = bufferSize;
        emit bufferSizeChanged(bufferSize);
    }
}

// =====================================================================

/*!
    \class QSensorFilter
    \ingroup sensors_main
    \inmodule QtSensors

    \brief The QSensorFilter class provides an efficient
           callback facility for asynchronous notifications of
           sensor changes.

    Some sensors (eg. the accelerometer) are often accessed very frequently.
    This may be slowed down by the use of signals and slots.
    The QSensorFilter interface provides a more efficient way for the
    sensor to notify your class that the sensor has changed.

    Additionally, multiple filters can be added to a sensor. They are called
    in order and each filter has the option to modify the values in the reading
    or to suppress the reading altogether.

    Note that the values in the class returned by QSensor::reading() will
    not be updated until after the filters have been run.

    \sa filter()
*/

/*!
    \internal
*/
QSensorFilter::QSensorFilter()
    : m_sensor(0)
{
}

/*!
    Notifies the attached sensor (if any) that the filter is being destroyed.
*/
QSensorFilter::~QSensorFilter()
{
    if (m_sensor)
        m_sensor->removeFilter(this);
}

/*!
    \fn QSensorFilter::filter(QSensorReading *reading)

    This function is called when the sensor \a reading changes.

    The filter can modify the reading.

    Returns true to allow the next filter to receive the value.
    If this is the last filter, returning true causes the signal
    to be emitted and the value is stored in the sensor.

    Returns false to drop the reading.
*/

/*!
    \internal
*/
void QSensorFilter::setSensor(QSensor *sensor)
{
    m_sensor = sensor;
}

// =====================================================================

/*!
    \class QSensorReading
    \ingroup sensors_main
    \inmodule QtSensors

    \brief The QSensorReading class holds the readings from the sensor.

    Note that QSensorReading is not particularly useful by itself. The interesting
    data for each sensor is defined in a sub-class of QSensorReading.
*/

/*!
    \internal
*/
QSensorReading::QSensorReading(QObject *parent, QSensorReadingPrivate *_d)
    : QObject(parent)
    , d(_d?_d:new QSensorReadingPrivate)
{
}

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

/*!
    \property QSensorReading::timestamp
    \brief the timestamp of the reading.

    Timestamps values are microseconds since a fixed point.
    You can use timestamps to see how far apart two sensor readings are.

    Note that sensor timestamps from different sensors may not be directly
    comparable (as they may choose different fixed points for their reference).

    \b{Note that some platforms do not deliver timestamps correctly}.
    Applications should be prepared for occasional issues that cause timestamps to jump
    backwards.
*/

/*!
    Returns the timestamp of the reading.
*/
quint64 QSensorReading::timestamp() const
{
    return d->timestamp;
}

/*!
    Sets the \a timestamp of the reading.
*/
void QSensorReading::setTimestamp(quint64 timestamp)
{
    d->timestamp = timestamp;
}

/*!
    Returns the number of extra properties that the reading has.

    Note that this does not count properties declared in QSensorReading.

    As an example, this returns 3 for QAccelerometerReading because
    there are 3 properties defined in that class.
*/
int QSensorReading::valueCount() const
{
    const QMetaObject *mo = metaObject();
    return mo->propertyCount() - mo->propertyOffset();
}

/*!
    Returns the value of the property at \a index.

    Note that this function is slower than calling the data function directly.

    Here is an example of getting a property via the different mechanisms available.

    Accessing directly provides the best performance but requires compile-time knowledge
    of the data you are accessing.

    \code
    QAccelerometerReading *reading = ...;
    qreal x = reading->x();
    \endcode

    You can also access a property by name. To do this you must call QObject::property().

    \code
    qreal x = reading->property("x").value<qreal>();
    \endcode

    Finally, you can access values via numeric index.

    \code
    qreal x = reading->value(0).value<qreal>();
    \endcode

    Note that value() can only access properties declared with Q_PROPERTY() in sub-classes
    of QSensorReading.

    \sa valueCount(), QObject::property()
*/
QVariant QSensorReading::value(int index) const
{
    // get them meta-object
    const QMetaObject *mo = metaObject();

    // determine the index of the property we want
    index += mo->propertyOffset();

    // get the meta-property
    QMetaProperty property = mo->property(index);

    // read the property
    return property.read(this);
}

/*!
    \fn QSensorReading::copyValuesFrom(QSensorReading *other)
    \internal

    Copy values from other into this reading. Implemented by sub-classes
    using the DECLARE_READING() and IMPLEMENT_READING() macros.

    Note that this method should only be called by QSensorBackend.
*/
void QSensorReading::copyValuesFrom(QSensorReading *other)
{
    QSensorReadingPrivate *my_ptr = d.data();
    QSensorReadingPrivate *other_ptr = other->d.data();
    /* Do a direct copy of the private class */
    *(my_ptr) = *(other_ptr);
}

/*!
    \fn QSensorReading::d_ptr()
    \internal
    No longer used. Exists to keep the winscw build happy.
*/

/*!
    \macro DECLARE_READING(classname)
    \relates QSensorReading
    \brief The DECLARE_READING macro adds some required methods to a reading class.

    This macro should be used for all reading classes. Pass the \a classname of your reading class.

    \code
    class MyReading : public QSensorReading
    {
        Q_OBJECT
        Q_PROPERTY(qreal myprop READ myprop)
        DECLARE_READING(MyReading)
    public:
        qreal myprop() const;
        vod setMyprop(qreal myprop);
    };
    \endcode

    \sa IMPLEMENT_READING()
*/

/*!
    \macro IMPLEMENT_READING(classname)
    \relates QSensorReading
    \brief The IMPLEMENT_READING macro implements the required methods for a reading class.

    This macro should be used for all reading classes. It should be placed into a single compilation
    unit (source file), not into a header file. Pass the \a classname of your reading class.

    \code
    IMPLEMENT_READING(MyReading)
    \endcode

    \sa DECLARE_READING()
*/

QT_END_NAMESPACE

#include "moc_qsensor.cpp"

