#ifndef MINUTNIK_CORE_H
#define MINUTNIK_CORE_H
//----------------------------------------------------------------------------
///
/// \brief  steif
///
///         Steifomat; Indoor plant watering system
//
/// \date   20190511
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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


#include <biwak/timer.hpp>      // lrtimer_t
#include <list>

/*#include <biwak/timer.h>
#include <biwak/output.h>
#include <biwak/led.h>
*/
#include <ocelli/icon.hpp>

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


class CMinutnikCore
{
   public:
      struct SItem
      {
         int duration;
         const char *description;
         const char *finished;
         const OIconRef* const icon;
      };

      struct SSlot
      {
         const SItem &item;
         lrtimer_t startTimer;
         bool operator ==(const SSlot &other)
         {
            return(startTimer == other.startTimer);
         }
      };

#if 0
      enum EMode
      {
         eModeStart=0,
         eModeEgg=eModeStart,
         eModeCharge,
         eModeBringup,

         #if defined STM32L031xx
            eModeCorona,
         #endif

         eModeCount,
      };
#endif
      enum EState
      {
         Init=0,
         Idle=1,
         Running=2,
         Alarm,
      };

   private:

      std::list<SSlot> m_slots;
      EState   m_state;
      const SSlot *m_shownSlot = nullptr;
      int m_shownSlotIndex = -1;

   public:
      CMinutnikCore();
      ~CMinutnikCore();
      bool isAnyTimerActive();
      void eventLoop();
      void addItem(const SItem& _item)
      {
         SSlot slot{
            .item=_item,
            .startTimer=lrNow()
         };
         m_slots.push_back( slot );
         resortIssues();
      }

      int slotTimeLeft( const SSlot &slot ) const
      {
         int timeLeft= ( slot.item.duration * MSECS_PER_SEC )
                  - lrElapsedMSeconds( slot.startTimer );
         return(timeLeft);
      }

      int slotTimeLeft( )
      {
         if(m_shownSlot)
         {
            int time=slotTimeLeft ( *m_shownSlot );
            if(time<=0)
            {
               m_state=Alarm;
            }
            return( slotTimeLeft ( *m_shownSlot ) );
         }
         return( 0 );
      }
      const char *slotDescription( ) const
      {
         if(m_shownSlot)
         {
            return( m_shownSlot->item.description );
         }
         return( "---" );
      }

      const OIconRef *getIcon( ) const
      {
         if(m_shownSlot)
         {
            return( m_shownSlot->item.icon );
         }
         return( nullptr );
      }

      void resortIssues()
      {
         lrtimer_t minTimeLeft=MSECS_PER_HOUR*6;
         m_shownSlot=nullptr;
         m_shownSlotIndex=-1;
         int index=0;

         // std::list<SSlot>::iterator
         for(const SSlot &slot : m_slots)
         {
            //activeIssueCount++;
            int time;
            if( ( time = slotTimeLeft( slot ) ) < minTimeLeft )
            {
               m_shownSlot=&slot;
               m_shownSlotIndex=index;
               minTimeLeft=time;
            }
            index++;
         }

         if(m_shownSlot!=nullptr)
         {
            m_state=Running;
         }
         else
         {
            m_state=Idle;
         }
         printf("Resort; new state: %d\n", m_state);
      }

      EState getState() const
      {
         return( m_state );
      }
      void setState( EState state )
      {
         m_state=state;
         return;
      }

      const SSlot *currentSlot() const
      {
          return(m_shownSlot);
      }

      const SItem &currentItem() const
      {
          return(m_shownSlot->item);
      }
      void removeItem()
      {
         m_slots.remove( *m_shownSlot );
      }
      int slotCount() const
      {
         return(m_slots.size());
      }
      const std::list<SSlot> &getSlotList() const
      {
         return(m_slots);
      }

};

//---fin----------------------------------------------------------------------
#endif // ? ! MINUTNIK_CORE_H
