#pragma once
#include "a83/macro.hpp"
#include "a83/error.hpp"
//! счётчик обратного отсчёта
class Counter {
private:
  float COUNT = 0;
  float val = 0;
  bool ready = false;
  void check_count() const {
    #ifdef DEBUG
    if (COUNT < 0)
      a83::error("Counter::check_count: COUNT < 0");
    #endif
  }
public:
  Counter() = default;
  Counter(float _COUNT): COUNT(_COUNT), val(_COUNT) { check_count(); }
  Counter& operator = (CN(Counter)) = default;
  Counter(CN(Counter)) = default;
  ~Counter() = default;
  template <typename T>
  void operator =(T x) { set_count(x); }
  void reset() { ready = false; }
  void reset_all() { ready = false; val = COUNT; }
  CN(float) get_count() const { return COUNT; }
  CN(float) get_val() const { return val; }
  //! оставшееся время в (0..1)
  float get_ratio() const {
    if (val <= 0)
      return 0;
    return val / COUNT;
  }
  void set_count(float _COUNT) {
    ready = false;
    COUNT = _COUNT;
    check_count();
    val = _COUNT;
  }
  bool operator ()() const { return ready; }
  void update(float dt) {
    if (COUNT == 0) {
      ready = true;
      return;
    }
    val -= dt;
    while (1) {
      if (val > 0)
        break;
      val += COUNT;
      ready = true;
    }
  } // update
};