//-----------------------------------------------------------------------------
///
/// \brief  Barrel organ
///
///         [...]
///
/// \date   20230806
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//-----------------------------------------------------------------------------


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


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

#include <biwak/pwm.hpp>
#include <biwak/barrel_organ.h>
#include <lepto/log.h>


//---Implementation------------------------------------------------------------


#define  PROMILL 1000
#define  PWM_FADE_FREQUENCY   1000


void CBarrelOrganBeep::eventLoop()
{
   if( getSlopes() == nullptr )
   {
      return;
   }
   
   barrel_t currentFrequency=CBarrelOrgan::eventLoop();
   
   switch(currentFrequency)
   {
      // Important: output has to be permanent low, not high.
      case 0:
      case CBarrelOrgan::finished:
         m_pwmLine->setPwmValue(0);
         m_pwmLine->getTimer().updateFrequency( 0 );
         break;
      case CBarrelOrgan::unchanged:
         break;
      default:
         if( !m_pwmLine->getTimer().getFrequency() )
         {
            m_pwmLine->getTimer().updateFrequency( currentFrequency );
            m_pwmLine->setPwmValue( PROMILL / 2 );
         }
         else
         {
            m_pwmLine->getTimer().rupdateFrequency(currentFrequency);
            m_pwmLine->getTimer().rupdatePulse( PROMILL / 2);
         }
         break;
   }
}


void CBarrelOrganFade::eventLoop()
{
   if( getSlopes() == nullptr )
   {
      return;
   }
   
   barrel_t currentDutyCycle=CBarrelOrgan::eventLoop();
   
   switch(currentDutyCycle)
   {
   case CBarrelOrgan::finished:
      // Don't set pwm value to 0. Stay at last value
      break;
   case CBarrelOrgan::unchanged:
      break;
   default:
      m_pwmLine->setPwmValue(currentDutyCycle);
      break;
   }
   
   return;
}


void CBarrelOrganBeep::setBeepMode( const CBarrelOrgan::SSlope *slopes, bool adapt)
{
   if(slopes==nullptr)
   {
      m_pwmLine->getTimer().updateFrequency(0);
      m_pwmLine->setPwmValue(0);
      stop();
   }
   else
   {
      m_pwmLine->getTimer().updateFrequency(
               startSlopes(slopes, adapt ? m_pwmLine->getTimer().getFrequency() : 0 ) );
      m_pwmLine->setPwmValue( PROMILL / 2 );
   }

   return;
}


void CBarrelOrganBeep::stop()
{
   CBarrelOrgan::stop();
   m_pwmLine->getTimer().updateFrequency( 0 );
}


void CBarrelOrganFade::setFadeMode( const CBarrelOrgan::SSlope *slopes )
{
   if(slopes==nullptr)
   {
      m_pwmLine->getTimer().updateFrequency(0);
      m_pwmLine->setPwmValue(0);
      stop();
   }
   else
   {
      m_pwmLine->getTimer().updateFrequency( PWM_FADE_FREQUENCY );
      m_pwmLine->setPwmValue( startSlopes(slopes) );
   }

   return;
}


//---fin-----------------------------------------------------------------------
