/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Mobility Components.
**
** $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 Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsystemalignedtimer.h"
#include "qsysteminfocommon_p.h"

QTM_BEGIN_NAMESPACE

#ifdef QT_SIMULATOR
Q_GLOBAL_STATIC(QSystemAlignedTimerPrivate, alignedTimerPrivate)
QSystemAlignedTimerPrivate *getSystemAlignedTimerPrivate() { return alignedTimerPrivate(); }
#endif // QT_SIMULATOR

/*!
    \class QSystemAlignedTimer
    \ingroup systeminfo
    \inmodule QtSystemInfo
    \brief The QSystemAlignedTimer class provides a service for applications to synchronize their activity.
    \since 1.2

    QSystemAlignedTimer is a fuzzy timer that allows applications that must do periodic activity like
    after being in sleep mode a certain period, to synchronize their activities in the same window of time.

    For example send network "alive" messages at the same time (i.e. turn the wireless radio on at the same time).

    The service is not only for network-aware applications, it is for use by any applications
    that need to periodic wake-ups.

    The recommended use case is when app uses single-shot timer only: set mintime 0 for the first call
    'to jump to the train' and mintime > 0 after 1st wakeup.
*/

/*!
    \fn void QSystemAlignedTimer::timeout()

    This signal is emitted when the timer times out.
*/

/*!
    \fn void QSystemAlignedTimer::error(QSystemAlignedTimer::AlignedTimerError error)

        This signal is emitted when an \a error happens.
*/

/*!
    \enum QSystemAlignedTimer::AlignedTimerError
    This enum describes the last known AlignedTimerError

    \value NoError                        No error.
    \value AlignedTimerNotSupported       The aligned timer is not support on this platform
    \value InvalidArgument                Interval arguments are invalid.
    \value TimerFailed                    General timer failure.
    \value InternalError                  Internal error.
*/

/*!
    Constructs a QSystemAlignedTimer object with the given \a parent.
*/
QSystemAlignedTimer::QSystemAlignedTimer(QObject *parent)
    : QObject(parent)
{
    d = new QSystemAlignedTimerPrivate(this);
    connect(d, SIGNAL(timeout()), this, SIGNAL(timeout()));
    connect(d, SIGNAL(error(QSystemAlignedTimer::AlignedTimerError)), this, SIGNAL(error(QSystemAlignedTimer::AlignedTimerError)));
}

/*!
    Destructs the QSystemAlignedTimer
*/
QSystemAlignedTimer::~QSystemAlignedTimer()
{
}

/*!
    Starts the timer with the minimal interval of \a minimumTime, and maximum interval \a maximumTime in seconds.

    This is not a guaranteed interval, and the timeout signal may be fired at any time,
    depending on other clients attached to this timer.

    In the case of minimalInterval of 0, it means 'wake me up when someone else is woken up'.

    If you need a window of time in which your timer should fire, use QSystemAlignedTimer::setWindow
*/
void QSystemAlignedTimer::start(int minimumTime, int maximumTime)
{
    if (minimumTime > maximumTime || maximumTime <= 0) {
        d->m_lastError = QSystemAlignedTimer::InvalidArgument;
        Q_EMIT error(d->m_lastError);
        return;
    }
    d->start(minimumTime, maximumTime);
}

/*!
    Starts the alignedtimer.
*/
void QSystemAlignedTimer::start()
{
    int minimumTime = minimumInterval();
    int maximumTime = maximumInterval();
    if ((minimumTime > maximumTime) || (maximumTime <= 0)) {
        d->m_lastError = QSystemAlignedTimer::InvalidArgument;
        Q_EMIT error(d->m_lastError);
        return;
    }
    d->start();
}

/*!
    This should be called when the application wakes up via other means than QSystemAlignedTimer timeout.

    Other applications that are in their wakeup window *may* be woken up. Single-shot timer is canceled,
    and reoccuring timer interval will restart.

    Symbian does not support this wokeUp call for reoccuring timers and will simply ignore it.
*/
void QSystemAlignedTimer::wokeUp()
{
    d->wokeUp();
}

/*!
    Stops this timer request.
*/
void QSystemAlignedTimer::stop()
{
    d->stop();
}

/*!
    Set the timeout minimum interval to \a seconds in seconds that must be waited before timeout
    signal is emitted.

    Time in seconds that MUST be waited before timeout.
    Value 0 means 'wake me up when someboy else is woken'.

    mintime value 0 should be used with special care, as it may cause too frequent wakeups.
    It is recommended that the first wait (if possible) uses minimum value of 0 to
    "jump to the train" and minimum value > 0 after 1st wakeup
*/
void QSystemAlignedTimer::setMinimumInterval(int seconds)
{
    d->setMinimumInterval(seconds);
}

/*!
    \property QSystemAlignedTimer::minimumInterval
    \brief The timers's minimumInterval.

    Returns this current timer minimum interval.
*/
int QSystemAlignedTimer::minimumInterval() const
{
    return d->minimumInterval();
}

/*!
    Set the timeout maximum interval to \a seconds the wait must end.

    Time in seconds when the wait MUST end. It is wise to have maxtime-mintime
    quite big so all users of this service get synced.
    For example if you preferred wait is 120 seconds, use minval 110 and maxval 130.

    max interval must be greater than min interval.
*/
void QSystemAlignedTimer::setMaximumInterval(int seconds)
{
    d->setMaximumInterval(seconds);
}

/*!
    \property QSystemAlignedTimer::maximumInterval
    \brief The timer's maximumInterval.

    Returns this current timer maximum interval.
*/
int QSystemAlignedTimer::maximumInterval() const
{
    return d->maximumInterval();
}

/*!
    Sets this timer to be a single shot \a singleShot is true, otherwise false.
*/
void QSystemAlignedTimer::setSingleShot(bool singleShot)
{
    d->setSingleShot(singleShot);
}

/*!
    This static function starts a timer to call a slot after a \a minimumTime
    interval has elapsed, and ensures that it will be called before the
    \a maximumTime has elapsed.

    These values are specified in seconds.

    The receiver is the \a receiver object and the \a member is the slot.
*/
void QSystemAlignedTimer::singleShot(int minimumTime, int maximumTime, QObject *receiver, const char *member)
{
    if (minimumTime > maximumTime || maximumTime <= 0)
        return;
    QSystemAlignedTimerPrivate::singleShot(minimumTime, maximumTime, receiver, member);
}

/*!
    \property QSystemAlignedTimer::singleShot
    Whether the timer is single shot.
*/

/*!
    Returns true if this timer is a single shot, otherwise false.
*/
bool QSystemAlignedTimer::isSingleShot() const
{
    return d->isSingleShot();
}

/*!
    Returns the last AlignedTimerError.
*/
QSystemAlignedTimer::AlignedTimerError QSystemAlignedTimer::lastError() const
{
    return d->lastError();
}

/*!
    \property QSystemAlignedTimer::active
    Returns true if the timer is running; otherwise false.
*/

/*!
    Returns true if the timer is running; otherwise false.
*/
bool QSystemAlignedTimer::isActive () const
{
    return d->isActive();
}

#include "moc_qsystemalignedtimer.cpp"

QTM_END_NAMESPACE
