/// QasTools: Desktop toolset for the Linux sound system ALSA.
/// \copyright See COPYING file.

#pragma once

#include "qsnd/mixer/elem.hpp"
#include "wdg/pad_proxy/slider.hpp"
#include <QString>

namespace MWdg::Mixer::Sliders::Proxy
{

/// @brief Slider
///
class Slider : public Wdg::Pad_Proxy::Slider
{
  Q_OBJECT

  public:
  // -- Construction

  Slider ();

  ~Slider ();

  // -- Mixer simple elem

  QSnd::Mixer::Elem *
  qsnd_mixer_elem () const
  {
    return _qsnd_mixer_elem;
  }

  void
  set_qsnd_mixer_elem ( QSnd::Mixer::Elem * selem_n );

  // -- Snd dir

  unsigned char
  snd_dir () const
  {
    return _snd_dir;
  }

  void
  set_snd_dir ( unsigned char dir_n );

  // -- Channel idx

  unsigned int
  channel_idx () const
  {
    return _channel_idx;
  }

  void
  set_channel_idx ( unsigned int idx_n );

  // -- Is joined flag

  bool
  is_joined () const
  {
    return _is_joined;
  }

  void
  set_is_joined ( bool flag_n );

  // -- Volume

  long
  volume_max () const
  {
    return _volume_max;
  }

  long
  volume_min () const
  {
    return _volume_min;
  }

  long
  volume_value () const
  {
    return _volume_val;
  }

  int
  volume_permille () const;

  // -- Decibel

  bool
  has_dB () const
  {
    if ( qsnd_mixer_elem () == nullptr ) {
      return false;
    }
    return qsnd_mixer_elem ()->has_dB ( snd_dir () );
  }

  long
  ask_dB_vol ( long dB_value_n, int dir_n = -1 )
  {
    return qsnd_mixer_elem ()->ask_dB_vol ( snd_dir (), dB_value_n, dir_n );
  }

  long
  ask_dB_vol_nearest ( long dB_value_n )
  {
    return qsnd_mixer_elem ()->ask_dB_vol_nearest ( snd_dir (), dB_value_n );
  }

  long
  ask_vol_dB ( long volume_n )
  {
    return qsnd_mixer_elem ()->ask_vol_dB ( snd_dir (), volume_n );
  }

  long
  dB_value () const
  {
    return _dB_val;
  }

  void
  set_dB_value ( long dB_val_n );

  Q_SIGNAL
  void
  sig_dB_value_changed ( long dB_value_n );

  long
  dB_max () const
  {
    return qsnd_mixer_elem ()->dB_max ( snd_dir () );
  }

  long
  dB_min () const
  {
    return qsnd_mixer_elem ()->dB_min ( snd_dir () );
  }

  // -- Event processing

  bool
  eventFilter ( QObject * obj_n, QEvent * event_n );

  // -- Public slots

  Q_SLOT
  void
  set_volume_value ( long value_n );

  Q_SLOT
  void
  update_value_from_source ();

  protected:
  // -- Protected methods

  void
  update_limits ();

  void
  dB_value_changed ();

  void
  volume_value_changed ();

  void
  slider_index_changed ();

  private:
  // -- Attributes
  QSnd::Mixer::Elem * _qsnd_mixer_elem;

  long _volume_val;
  long _volume_min;
  long _volume_max;
  long _dB_val;

  unsigned int _channel_idx;
  unsigned char _snd_dir;

  bool _is_joined;
  bool _alsa_updating;
};

} // namespace MWdg::Mixer::Sliders::Proxy
