#include "misc/Time.h"

#include <chrono>
#include <algorithm>

namespace td {
namespace utils {

void AutoTimer::update() {
    m_InternalTime += getTime() - m_LastTime;
    if (m_InternalTime >= m_Interval) {
        if (m_Function != nullptr)
            m_Function();
        m_InternalTime %= m_Interval;
    }
    m_LastTime = getTime();
}

void AutoTimer::update(std::uint64_t delta) {
    m_InternalTime += delta;
    if (m_InternalTime >= m_Interval) {
        if (m_Function != nullptr)
            m_Function();
        m_InternalTime %= m_Interval;
    }
    m_LastTime = getTime();
}

void AutoTimer::reset() {
    m_InternalTime = 0;
    m_LastTime = getTime();
}

bool Timer::update(std::uint64_t delta) {
    m_InternalTime += delta;
    if (m_InternalTime >= m_Interval) {
        m_InternalTime %= m_Interval;
        return true;
    }
    return false;
}

void Timer::reset() {
    m_InternalTime = 0; // let the timer active once at the beginning
}

bool CooldownTimer::update(std::uint64_t delta) {
    if (m_Cooldown > 0) {
        m_Cooldown = std::max(static_cast<std::int64_t>(0), static_cast<std::int64_t>(m_Cooldown - delta));
    }
    return m_Cooldown == 0;
}

void CooldownTimer::reset() {
    m_Cooldown = 0; // let the timer active once at the beginning
}

void CooldownTimer::applyCooldown() {
    m_Cooldown = m_CooldownTime;
}

std::uint64_t getTime() {
    return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count();
}

} // namespace utils 
} // namespace td
