#if ! defined ( LIBOCELLI_OCELLI_HPP)
#define LIBOCELLI_OCELLI_HPP
//----------------------------------------------------------------------------
///
/// \file   ocelli.hpp
///
/// \brief  class for handling ocelli screens
///
///         It takes care that touch events are routed to correct screens.
///         It takes care about backlight reduction in standby.
///
///
/// \date   20220901
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Documentation------------------------------------------------------------


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


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


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

#include <ocelli/screen.hpp>
#include <ocelli/widget.hpp>
#include <biwak/timer.hpp>
#include <biwak/pwm.hpp>
#include <biwak/barrel_organ.h>
#include <biwak/touch_tsc2007.h>


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


class OApp
{
   private:
      static OApp *m_globalOcelliApp;

      OScreen *m_pCurrentScreen=nullptr;
      OScreen *m_pPreviousScreen=nullptr;
      OScreen *m_pNaviScreen=nullptr;
      OScreen *m_pStandbyScreen=nullptr;
      bool m_darkened=false;

      #if defined (STM32)
      lrtimer_t m_touchEventTimer=lrNow();
      CBarrelOrganFade *m_boBacklight;
      CBarrelOrganBeep *m_boBuzzer;
      #endif

      OWidget *m_pressedWidget = nullptr;

      static constexpr int brightnessOn = 600;
      static constexpr int brightnessStandby = 50;

      public:
      // 50is a little bit low
      static const CBarrelOrgan::SSlope fadeIn[];
      static const CBarrelOrgan::SSlope fadeOut[];
      static constexpr CBarrelOrgan::SSlope fadeInDark [] =
                                          {     {   0, brightnessStandby, MSECS_PER_SEC / 2},
                                                { CBarrelOrgan::finished, 0, 0 } };
      static constexpr CBarrelOrgan::SSlope slowFadeDark [] =
                                                // 20 is a little bit too dark
               {     {    brightnessOn, brightnessStandby, MSECS_PER_SEC * 2 },
                     { CBarrelOrgan::finished, 0, 0 } };

      static constexpr const CBarrelOrgan::SSlope beepPressed [] =
               {     { 440 , 440, MSECS_PER_SEC / 32},
                     { CBarrelOrgan::stopped, 0, 0 } };
      static constexpr const CBarrelOrgan::SSlope beepReleased [] =
               {     { 880 , 880, MSECS_PER_SEC / 32},
                     { CBarrelOrgan::stopped, 0, 0 } };


   public:
      enum class EEventType
      {
               // none,
               // init,
         pressed,
         clicked,
         moved,
         released,
               // modified
      };

      struct SEvent{
         int x;
         int y;
         EEventType type;
      };

      OApp(CGraphicDisplay &display, CTouchTsc2007 *touch,
               CBarrelOrganFade *boBacklight,CBarrelOrganBeep *boBuzzer);
      void setNaviScreen(OScreen *screen)
      {
         m_pNaviScreen=screen;
      }
      void setStandbyScreen(OScreen *screen)
      {
         m_pStandbyScreen=screen;
      }
      void setCurrentScreen(OScreen *screen);
      const OScreen *getCurrentScreen() const
      {
         return( m_pCurrentScreen );
      }
      void setPreviousScreen();
      void event( const CTouch::SEvent touchEvent );

      void referEvent(OWidget *widget, Ocelli::SEvent &event);
      void draw();
      void eventLoop();
      static OApp *instance()
      {
         return(m_globalOcelliApp);
      }
      lrtimer_t getTouchTimer() const
      {
        #if defined (STM32)
            return( m_touchEventTimer );
        #else
            return(0);
        #endif
      };
      void _touchEvent()
      {
         #if defined (STM32)
            m_touchEventTimer=lrNow();
            if( m_darkened )
            {
               m_boBacklight->setFadeMode( fadeIn );
               m_darkened = false;
            }
         #endif
      };
};

//---fin.----------------------------------------------------------------------
#endif // ? ! LIBOCELLI_OCELLI_HPP
