//----------------------------------------------------------------------------
///
/// \file   button.hpp
///
/// \brief  class for graphical widget
///
/// \date   20220830
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


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


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


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


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

#include <ocelli/slider.h>
#include <ocelli/ocelli.hpp>
#include <lepto/log.h>
#include <lepto/lepto.h>


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


#if defined USE_BIWAK

struct SStyles
{
   const TRgb topColor;
   const TRgb bottomColor;
   const bool horizontalSeperator;
   const bool indicatorCircle;
   const int rectBorder;
} const styles[]=
{
   [ (int)OSlider::ESliderStyle::bar ]=
      {
         .topColor=lightGrey,
         .bottomColor=black,
         .horizontalSeperator=true,
         .indicatorCircle=false,
         .rectBorder=8

      },
   [ (int)OSlider::ESliderStyle::flat ]=
      {
         .topColor=black,
         .bottomColor=black,
         .horizontalSeperator=false,
         .indicatorCircle=false,
         .rectBorder=6

      }
};

void OSlider::draw() /* override virtual */
{
   int border=styles[(int)m_style].rectBorder;

   if ( styles[(int)m_style].topColor == styles[(int)m_style].bottomColor )
   {
      m_display->setBg( styles[(int)m_style].topColor );
      m_display->setDrawBackground(true);
   }
   else
   {
      m_display->setDrawBackground(false);
   }
   m_display->setFg(white);

   m_display->drawBar( p1().x, p1().y, p2().x, p2().y,
                       styles[(int)m_style].topColor,
                       styles[(int)m_style].bottomColor);

   if ( styles[(int)m_style].topColor == styles[(int)m_style].bottomColor )
   {
      m_display->drawBar( p1().x + border + 1, p1().y + border + 1 , p2().x - border - 1, p2().y - border - 1,
                     darkDarkViolet, darkDarkViolet );
      m_display->setBg( darkDarkViolet );
   }


   #if 0
   if( styles[(int)m_style].horizontalSeperator )
   {
      m_display->drawBar( p1().x, p1().y, p1().x, p2().y , green, black);
   }
   #endif

   #if 1
   const Ocelli::SEvent event{.type=Ocelli::EEventType::init};
   update( event );
#endif
   m_display->setBg( black );
   return;
}

void OSlider::evaluate(const Ocelli::SEvent &event)
{
   int border=styles[(int)m_style].rectBorder;

   int y1=p1().y + ( border * 2 );
   int y2=p2().y - ( border * 2 );
   int yDiff=y2-y1;
   
   m_value= ( m_ledCount - 1 ) - ( ( ( event.y - y1 ) * m_ledCount ) / yDiff );
   m_value= MAX(0, m_value);
   m_value= MIN(m_value, m_ledCount-1);
   
   lInfo("Emit: %d", m_value);
   // Its the index of the bar which is selected; 0...9; -1 is possible when 
   valueChangedSignal.emitSignal(m_value);
}

void OSlider::update(const Ocelli::SEvent &event) /* override virtual */
{
   int border=styles[(int)m_style].rectBorder;
   bool pressed = false;

   if(    ( event.type == Ocelli::EEventType::pressed )
       || ( event.type == Ocelli::EEventType::moved ) )
   {
      evaluate(event);
   }

   if(   (event.type == Ocelli::EEventType::pressed )
      || (event.type == Ocelli::EEventType::moved ) )
   {
      pressed = true;
   }

   if( styles[(int)m_style].indicatorCircle )
   {
      m_display->drawCircle( centerX(), centerY(), (width()/2)- border, false,
                        pressed ? lightGreen : darkDarkGrey );
   }
   else
   {
      m_display->drawRect( p1().x + border, p1().y + border, p2().x - border, p2().y - border,
                        pressed ? lightGreen : darkDarkGrey );
   }

   updateBars();
}

void OSlider::updateBars()
{
   int border=styles[(int)m_style].rectBorder;
   int x1=p1().x + ( border * 2 );
   int x2=p2().x - ( border * 2 );
   int y1=p1().y + ( border * 2 );
   int y2=p2().y - ( border * 2 );
   int barHeight= ( (y2-y1) - ( ( m_ledCount - 1 ) * border ) ) / m_ledCount;

   for(int i1=0; i1 < m_ledCount; i1++)
   {
      int dy=i1*(barHeight+border);
      TRgb color=i1>=( m_ledCount - 1 - m_value) ? lightGreen : darkGreen;
      if(i1==m_ledCount - 1)
      {
         color=grey;
      }
      m_display->drawBar( x1, y1 + dy, x2, y1 + dy + barHeight, color );
   }
}

#else

void OSlider::draw() /* override virtual */
{
}

void OSlider::update(CTouch::EEventType eventType) /* override virtual */
{
}

#endif


void OSlider::setSliderValue(int value, bool emitChange /* =true */ )
{
   m_value=value;
   
   if( OApp::instance()->getCurrentScreen()->containsWidget(this) )
   {
      updateBars();
   }
   
   if(emitChange)
   {
      valueChangedSignal.emitSignal(m_value);
   }
}


void OSlider::setSliderValuePromil(int value, bool emitChange /* =true */)
{
   value++; // needed due to rounding error
   setSliderValue( ( (m_ledCount-1) * value ) / 1000, emitChange );
}


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