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

#include "cards_db.hpp"
#include "qsnd/alsa.hpp"
#include "qsnd/udev_device_lookout.hpp"
#include <algorithm>
#include <iostream>

namespace QSnd
{

Cards_Db::Cards_Db ( QObject * parent_n )
: QObject ( parent_n )
{
  // Device lookout
  {
    auto * lookout = new QSnd::UDev_Device_Lookout ( this );
    connect ( lookout,
              &QSnd::UDev_Device_Lookout::sig_change,
              this,
              &Cards_Db::reload );
  }

  // Initial reload
  reload ();
}

Cards_Db::~Cards_Db () = default;

void
Cards_Db::reload ()
{
  Cards cards;
  // Reserve some more space
  cards.reserve ( _cards.size () + 8 );

  // -- Load cards
  {
    int card_idx = -1;
    while ( true ) {
      if ( ::snd_card_next ( &card_idx ) != 0 ) {
        break;
      }
      if ( card_idx < 0 ) {
        break;
      }
      cards.emplace_back (
          std::make_shared< const QSnd::Card_Info > ( card_idx ) );
    }
  }

  // -- Remove disappeared cards
  for ( auto it = _cards.cbegin (); it != _cards.cend (); ) {
    auto itf = std::find_if ( cards.cbegin (),
                              cards.cend (),
                              [ &card = *it ] ( const Card_Handle & card_n ) {
                                return *card == *card_n;
                              } );
    if ( itf != cards.cend () ) {
      // Card is still there
      ++it;
    } else {
      // Card has disappeared
      {
        Card_Handle removed_handle = *it;
        it = _cards.erase ( it );
        Q_EMIT sig_card_removed ( removed_handle );
      }
      Q_EMIT countChanged ();
    }
  }

  // -- Insert new cards
  for ( const auto & card : cards ) {
    auto itf = std::find_if (
        _cards.cbegin (),
        _cards.cend (),
        [ &card ] ( const Card_Handle & card_n ) { return *card == *card_n; } );
    if ( itf == _cards.cend () ) {
      // New card
      _cards.push_back ( card );
      Q_EMIT sig_card_new ( card );
      Q_EMIT countChanged ();
    }
  }
}

} // namespace QSnd
