#ifndef __JABYENGINE_FRAME_TIMER_HPP__
#define __JABYENGINE_FRAME_TIMER_HPP__
#include "frame_time_helper.hpp"
#include <stdint.hpp>

namespace JabyEngine {
    class MasterTime {
    __friends:
        static uint32_t value;

    public:
        static uint32_t read() {
            return reinterpret_cast<volatile uint32_t&>(MasterTime::value);
        }

        template<typename T>
        static T read_as() {
            return static_cast<T>(MasterTime::read());
        }
    };

    template<typename T>
    class SimpleTimer {
    protected:
        T value = 0;

    public:
        constexpr SimpleTimer() = default;

        static SimpleTimer create() {
            SimpleTimer timer;

            timer.reset();
            return timer;
        }

        bool is_expired_for(T time) const {
            return static_cast<T>((MasterTime::read_as<T>() - this->value)) >= time;
        }

        void reset() {
            this->value = MasterTime::read_as<T>();
        }
    };

    template<typename T>
    class IntervalTimer : public SimpleTimer<T> {
    private:
        T interval = 0;

    public:
        constexpr IntervalTimer() = default;
        constexpr IntervalTimer(T interval) : SimpleTimer<T>(), interval(interval) {
        }

        static constexpr IntervalTimer create(T interval) {
            IntervalTimer timer;

            static_cast<SimpleTimer<T>&>(timer) = SimpleTimer<T>::create();
            timer.interval = interval;
            return timer;
        }

        void set_interval(T interval) {
            this->interval = interval;
        }

        bool is_expired() const {
            return SimpleTimer<T>::is_expired_for(this->interval);
        }
    };
}

#endif //!__JABYENGINE_FRAME_TIMER_HPP__