#ifndef UTILITIES_H
#define UTILITIES_H

#include <assert.h>

//!
//! \brief The EventTicker class is a helper class used to determine if a certain event is ready to be executed.
//!
//! The EventTicker class is a helper class used to determine if a certain event is ready to be executed. This class supposed to be used in combination with a Timer provided by the user.
//!
class EventTicker{
public:

    //!
    //! \brief EventTicker Constructor used to build non initilized Object. Call \fn init() befor use.
    //!
    EventTicker() : _isInitialized(false) {
        _isInitialized = false;
    }

    //!
    //! \brief EventTicker Constructor used for initilization. The function \fn must not be called if this constructor is used.
    //! \param timerInterval The timer interval of the timer provided by the user.
    //! \param targetTime The thick intervall (timerInterval <= targetTime), see \fn ready().
    //!
    EventTicker(double timerInterval, double targetTime) {
        _isInitialized = false;
        init(timerInterval, targetTime);
    }

    //!
    //! \brief init Used to init the EventTicker.
    //! \param timerInterval The timer interval of the timer provided by the user.
    //! \param targetTime The thick intervall (timerInterval <= targetTime), see \fn ready().
    //!
    void init(double timerInterval, double targetTime){
        assert(_isInitialized == false);
        assert(timerInterval > 0);
        assert(targetTime >= timerInterval);
        _timerInterval  = timerInterval;
        _targetTime    = targetTime;
        _ticks      = 0;
        _isInitialized  = true;
    }

    //!
    //! \brief ready This function must be called by a user provided timer interrupt handler.
    //! \return True if the event is ready to be executed, false either.
    //!
    //! This function must be called by a user provided timer interrupt handler. A internal counter increases with every call.
    //! If _targetTime <= _timerInterval*_ticks the counter gets reset and the function returns true. If the condition is not
    //! met the function returns false.
    //!
    bool ready(void) {
        assert(_isInitialized == true);
        _ticks++;
        bool ready = _targetTime <= _timerInterval*_ticks;
        if (ready)
            _ticks = 0;
        return ready;
    }

    //!
    //! \brief Resets the tick count.
    void reset(void) {
        _ticks = 0;
    }

private:
    double          _timerInterval;
    double          _targetTime;
    unsigned long   _ticks;
    bool            _isInitialized;
};

#endif // UTILITIES_H