#ifndef CANDIS_SCREEN_CHART_HPP
#define CANDIS_SCREEN_CHART_HPP
//----------------------------------------------------------------------------
///
/// \brief   CANDis screen showing can messages
///
///          Static table
///
/// \date   20220903
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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

#if 1 // defined(STM32)
   #include <platform_generated.hpp>     // CPlatform
#else
   #include <platform_empty.h>
#endif
#include <ocelli/screen.hpp>
#include <biwak/gdisplay.h>
#include <math.h>


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


class CDiagramm
{
   public:

   #if 0
   struct SValue{
      int value;
      lrtimer_t timeStamp;
   };
   #endif

private:
   int m_minVal;
   int m_maxVal;

   #if 0
      CRing<SValue> m_ring;
   #else
      CRing<int> m_ring;
   #endif

   const TRgb &m_color;
   const char *m_name;
   int m_index;
   static int m_globalIndex;

public:
   CDiagramm(int min, int max, const TRgb &color, const char *name)
      :m_minVal(min)
      ,m_maxVal(max)
      ,m_ring(240)
      ,m_color(color)
      ,m_name(name)
      ,m_index(m_globalIndex++)
   {
      // CRing does not support 'volatile any more'
      m_ring.setVolatile(true);
   }
   void addValue(int value)
   {
      #if 0
      m_ring.putEntry( SValue{ value, lrNow() } );
      #else
      m_ring << value;
      #endif
   }
   void fillDemoData(int offset, int slopes)
   {
      int r=( m_maxVal - m_minVal ) / 2;
      int mid= m_minVal + r;
      int value;
      r-=m_minVal/20;
      for(int i1=0; i1 < m_ring.getMaxEntries(); i1++)
      {
         value = mid + ( sin( ( ( M_PI * slopes ) * ( i1 + offset ) ) / 240 ) * r );
         #if 0
            m_ring.putEntry( SValue{ value, lrNow() } );
         #else
            m_ring << value;
         #endif
      }
   }

   void draw(CGraphicDisplay &display, const ORect &rect)
   {
      int cnt=m_ring.getEntryCount();
      lInfo("Chart: %d entries", cnt);
      int start;
      int value;
      int divider=(m_maxVal-m_minVal)/rect.height();

      display.setFont( getFont6() );
      display.setFg(m_color);
      display.drawText( rect.x1() +16+(m_index*48), rect.y1()-8, m_name);

      if( cnt < rect.width() )
      {
         start=0;
      }
      else
      {
         start=cnt-rect.width();
         cnt=rect.width();
      }

      for(int i1=0; i1 < cnt; i1++)
      {
         display.setFg(m_color);
         #if 0
            value=m_ring.getEntry(start+i1)->value;
         #else
            value=*m_ring.getEntry(start+i1);
         #endif
         int x=rect.x1() + i1;
         int y=rect.y2() - ((value-m_minVal)/divider);
         //display.drawPixel( x, y, color);
         display.drawPixel( x, y, m_color);
         display.drawPixels( &m_color, 1);
      }
      return;
   }
};

int CDiagramm::m_globalIndex=0;

class CScreenChart: public OScreen
{
   private:
      #if 1 // defined(STM32)
      CPlatform *m_pPlatform;
      #endif

      CDiagramm m_temp;
      #if ! defined(STM32)
         CDiagramm m_gas;
         CDiagramm m_hum;
         CDiagramm m_temp2;
      #endif

      static constexpr int BORDER = 4;

   public:
      #if 1
      //defined(STM32)
      CScreenChart( CPlatform *platform )
         #if defined(STM32)
         :m_pPlatform(platform)
         ,m_temp( 1600, 2800, lightRed, "TEMP" )
         #else
         :m_temp( 1600, 2800, lightRed, "TEMP" )
         #endif
         #if ! defined(STM32)
            ,m_gas( 30000, 155000, yellow, "GAS" )
            ,m_hum( 20000, 50000, cyan, "HUM" )
            ,m_temp2( -500, 4000, lightGreen, "TEMP2" )
         #endif
      {
         m_temp.fillDemoData(0,4);
         #if ! defined(STM32)
            m_gas.fillDemoData(64,3);
            m_hum.fillDemoData(128,2);
            m_temp2.fillDemoData(192,1);
         #endif
      }
      #else
      CScreenChart(  )
      {}
      #endif
      int yText(int index)
      {
         return ( BORDER + ( ( 11 + 2 ) * index ) + 3 );
      }
      void drawClimateDiagramm( const ORect &rect )
      {
         CGraphicDisplay &display=OWidget::display();

         display.setFg(lightBlue);
         display.setBg(black);
         display.setFont( getFont8() );

         int FACT=100;
         int ydiff=( ( rect.height() * FACT ) /10);
         int xdiff=( ( rect.width() * FACT ) /20);

         display.drawBar( rect.x1(), rect.y1(), rect.x2(), rect.y2(), darkBlue, black);

         for(int i1=0; i1<10+1; i1++)
         {
            display.drawHLine( rect.x1(), rect.y1() + ( (i1*ydiff) / FACT ), rect.x2(), grey);
         }
         for(int i1=0; i1<20+1; i1++)
         {
            display.drawVLine( rect.x1()+( (i1*xdiff) / FACT ), rect.y1() , rect.y2(), grey);
         }

         m_temp.draw(display, rect );
         #if ! defined(STM32)
            m_gas.draw(display, rect );
            m_hum.draw(display, rect );
            m_temp2.draw(display, rect );
         #endif

         return;
      }

      virtual void draw() override
      {
         OWidget::display().clear(black);
         OScreen::draw();
         // ORect rect(10, 96+8, 240-10, 194+8);
         //ORect rect1(0, 320-64-96, 239, 320-64-16);
         //drawClimateDiagramm(rect1);

         ORect rect2(0, 320-64-96 -96, 239, 320-64-16-96);
         drawClimateDiagramm(rect2);
      }
      void eventLoop()
      {
      }

      void addTemperature(const int id, int temperature)
      {
         if( id == 0x100214 )
         {
            m_temp.addValue(temperature );
         }
         return;
      }

      void showValue(int index, bool dry, bool valid = true, bool gone=false)
      {
      }
};


//---fin----------------------------------------------------------------------
#endif // ? ! CANDIS_SCREEN_CHART_HPP
