/* Distributed under the Apache License, Version 2.0.
   See accompanying NOTICE file for details.*/

#pragma once

/**
 * Utility class that looks for a peak in data
 * looking at the data one point at a time.
 *
 * Note: I wrote this for finding peaks on well behaved sinusoidal data. 
 *       I have some Ideas in the comments if the data is not as well behaved.
 */ 
class CDM_DECL DataPeak
{
public:
  
  /**
   * -- Number of Samples - This is how many values the peak is compared too,
   *                        that the current peak must be greater than.
   *                When the this many samples are smaller than the peak,
   *              we have found a peak.
   * -- epsilon - The window (below the peak if trending up, above the peak if trending down)
   *              that a new value must be below/above in order to be considered treding away from the peak
   *              If data is inside the window, we are in a plataue and don't do anything.
   *              If we are going away from the peak (opposite direction) we need #samples away from the window 
   *              to signal a peak.
   *              If we find a point that is a new peak, we move our window and start our counting all over.
   *
   *  By default this class will look for max peak only
   *  By default this class assumes data coming in is trening in the positive/up direction
   */
  DataPeak(unsigned int samples, double epsilon);

  /** Reset Counter info */
  void Reset();

  /** 
   * Get the last top peak value
   */
  double LastTopPeak();

  /** 
   * Get the last bottom peak value
   */
  double LastBottomPeak();

  /** Check to see if we have peaked 
   *  value is the next point of data we will check against.
   */
  bool Peaked(double value);

protected:

  bool         m_PositiveTrend;
  bool         m_FindMax;
  bool         m_FindMin;
  unsigned int m_Samples;
  unsigned int m_PeakCount;
  double       m_Epsilon;
  double       m_SamplePeak;
  double       m_LastTopPeak;
  double       m_LastBottomPeak;
};
