#ifndef BIWAK_FADER_H
#define BIWAK_FADER_H
//----------------------------------------------------------------------------
///
/// \brief  Class for handling backlight fading.
///
///         Much more simple than the barrel organ.
///
/// \date   20230313
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


///---General-------------------------


///---Own-----------------------------

#include <biwak/output.hpp>
#include <biwak/timer.hpp>
#include <lepto/lepto.h>    // MIN/MAX


//---Defines------------------------------------------------------------------


//---Declaration--------------------------------------------------------------


//#define FTYPE  int
#define MULTI        5000     // 2000 is minimal off

// Need to be int16_t for miniminutnik
//typedef int16_t   fader_t;
typedef int fader_t;
//typedef int   barrel_t;

class CFader
{
   public:
      //static constexpr fader_t unchanged=-1;
      //static constexpr fader_t finished=-2;

   private:
      lrtimer_t m_startTimer;
      int m_steps_per_sec;
      fader_t m_currentFaderValue;
      fader_t m_targetFaderValue;
      fader_t m_startFaderValue;

   public:
      constexpr CFader( )
         :m_startTimer(0)
         ,m_steps_per_sec(0)
         ,m_currentFaderValue(0)
         ,m_targetFaderValue(0)
         ,m_startFaderValue(0)
      {
      }
      CFader( fader_t min, fader_t max, int timeSec )
         :CFader()
      {
         updateTime( min, max, timeSec );
      }
      void updateTime( fader_t min, fader_t max, int timeSec )
      {
         if(!timeSec)
         {
            m_steps_per_sec = 0;
         }
         else
         {
            m_steps_per_sec = (max - min) / timeSec;
         }
      }
      fader_t eventLoop()
      {
         if( ! isActive() )
            return( m_targetFaderValue );
         
         if (!m_steps_per_sec)
         {
            return( m_currentFaderValue = m_targetFaderValue );
         }
         
         fader_t diff = ( lrElapsedMSeconds(m_startTimer) * m_steps_per_sec )
                        / MSECS_PER_SEC;
         
         if( m_targetFaderValue > m_currentFaderValue )
         {
            m_currentFaderValue = m_startFaderValue + diff;
            m_currentFaderValue = MIN(m_currentFaderValue, m_targetFaderValue);
         }
         else
         {
            m_currentFaderValue = m_startFaderValue - diff;
            m_currentFaderValue = MAX(m_currentFaderValue, m_targetFaderValue);
         }
         
         return( m_currentFaderValue );
      }
      fader_t finish()
      {
         m_currentFaderValue = m_targetFaderValue;
         return( m_targetFaderValue );
      }
      void setTarget(fader_t target)
      {
         m_startFaderValue = eventLoop(); //m_currentFaderValue;
         m_startTimer=lrNow();
         m_targetFaderValue = target;
      }
      fader_t getTarget() const
      {
         return( m_targetFaderValue );
      }
		bool isActive() const
		{
         return( m_currentFaderValue != m_targetFaderValue );
		}
      fader_t current() const
      {
         return( m_currentFaderValue );
      }
};


//---fin-----------------------------------------------------------------------
#endif
