#pragma once

template <typename MeasurementT>
class AutoStart
{
public:
  AutoStart() : enabled_(false) {}

  void begin(MeasurementT minThreshold, MeasurementT maxThreshold, uint32_t maxNumMeasurementsBetweenPeeks)
  {
    minThreshold_ = minThreshold;
    maxThreshold_ = maxThreshold;
    maxNumMeasurementsBetweenPeeks_ = maxNumMeasurementsBetweenPeeks;
    measurementsSinceLastPeek_ = maxNumMeasurementsBetweenPeeks + 1;
    up_ = false;
    enabled_ = true;
  }

  void enable(bool enable=true) {
    enabled_ = enable;
  }
  bool enabled() const { return enabled_; };

  bool autoStart(MeasurementT measurement)
  {
    if(!enabled_)
      return false;
    measurementsSinceLastPeek_ += 1;
    if (!up_ && measurement > maxThreshold_)
    {
      up_ = true;
      bool doAutoStart = measurementsSinceLastPeek_ < maxNumMeasurementsBetweenPeeks_;
      measurementsSinceLastPeek_ = 0;
      return doAutoStart;
    }
    if (up_ && measurement < minThreshold_)
      up_ = false;

    return false;
  }

private:
  MeasurementT minThreshold_;
  MeasurementT maxThreshold_;
  uint32_t maxNumMeasurementsBetweenPeeks_;

  // time of last peak
  uint32_t measurementsSinceLastPeek_;
  // if measurements have been below min threshold (false) or above max threshold (true)
  bool up_;

  bool enabled_;
};

// ------------------------------------------------------------------------------------------

template <typename MeasurementT>
class AutoStop
{
public:
  AutoStop() : enabled_(false) {}

  void begin(MeasurementT threshold, uint32_t numMeasurementsBelowThreshold)
  {
    threshold_ = threshold;
    numMeasurementsBelowThreshold_ = numMeasurementsBelowThreshold;
    counter_ = 0;
    enabled_ = true;
  }

  void enable(bool enable=true) {
    enabled_ = enable;
  }
  bool enabled() const { return enabled_; };


  bool autoStop(MeasurementT measurement)
  {
    if (measurement > threshold_)
    {
      counter_ = 0;
      return false;
    }
    else
    {
      ++counter_;
      if (counter_ >= numMeasurementsBelowThreshold_)
      {
        counter_ = 0;
        return true;
      }
      return false;
    }
  }

private:
  MeasurementT threshold_;
  uint32_t numMeasurementsBelowThreshold_;
  uint32_t counter_;
  bool enabled_;
};
