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

#include "card_info.hpp"
#include "qsnd/alsa.hpp"
#include <iostream>

namespace QSnd
{

Card_Info::Card_Info () = default;

Card_Info::Card_Info ( const int card_idx_n )
{
  acquire_info ( card_idx_n );
}

Card_Info::Card_Info ( const QString & dev_str_n )
{
  acquire_info ( dev_str_n );
}

Card_Info::~Card_Info () = default;

void
Card_Info::clear ()
{
  _is_valid = false;
  _index = -1;
  _id.clear ();
  _driver.clear ();
  _name.clear ();
  _long_name.clear ();
  _mixer_name.clear ();
  _components.clear ();
}

bool
Card_Info::acquire_info ( const int card_idx_n )
{
  return acquire_info ( QStringLiteral ( "hw:" ) +
                        QString::number ( card_idx_n ) );
}

bool
Card_Info::acquire_info ( const QString & dev_str_n )
{
  snd_ctl_t * snd_ctl = nullptr;
  {
    // Open control handle
    int oret = ::snd_ctl_open (
        &snd_ctl, dev_str_n.toLocal8Bit ().constData (), SND_CTL_NONBLOCK );
    if ( oret < 0 ) {
      // Control opening failed
      clear ();
    } else {
      // Allocate card info on the stack
      snd_ctl_card_info_t * snd_card_info = nullptr;
      snd_ctl_card_info_alloca ( &snd_card_info );

      // Get card information
      int ciret = ::snd_ctl_card_info ( snd_ctl, snd_card_info );
      if ( ciret < 0 ) {
        // Card info loading failed
        clear ();
      } else {
        // Card info successfully loaded
        _is_valid = true;
        _index = snd_ctl_card_info_get_card ( snd_card_info );
        _id = snd_ctl_card_info_get_id ( snd_card_info );
        _driver = snd_ctl_card_info_get_driver ( snd_card_info );
        _name = snd_ctl_card_info_get_name ( snd_card_info );
        _long_name = snd_ctl_card_info_get_longname ( snd_card_info );
        _mixer_name = snd_ctl_card_info_get_mixername ( snd_card_info );
        _components = snd_ctl_card_info_get_components ( snd_card_info );
      }
    }
  }
  // Close control on demand
  if ( snd_ctl != nullptr ) {
    ::snd_ctl_close ( snd_ctl );
  }
  return is_valid ();
}

bool
Card_Info::operator== ( const QSnd::Card_Info & cinfo_n ) const
{
  if ( _is_valid != cinfo_n._is_valid ) {
    return false;
  }
  if ( !_is_valid && !cinfo_n._is_valid ) {
    return true;
  }
  return ( _index == cinfo_n._index ) && ( _id == cinfo_n._id ) &&
         ( _driver == cinfo_n._driver ) && ( _name == cinfo_n._name ) &&
         ( _long_name == cinfo_n._long_name ) &&
         ( _mixer_name == cinfo_n._mixer_name ) &&
         ( _components == cinfo_n._components );
}

bool
Card_Info::operator!= ( const QSnd::Card_Info & cinfo_n ) const
{
  return !operator== ( cinfo_n );
}

} // namespace QSnd
