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

#pragma once

#include "qsnd/card_info.hpp"
#include "qsnd/cards_model.hpp"
#include "qsnd/ctl_address.hpp"
#include <QAbstractListModel>

namespace QSnd
{

// Forward declaration
class Cards_Db;

/// @brief Mixers_Model
///
class Mixers_Model : public QAbstractListModel
{
  Q_OBJECT;

  public:
  // -- Types

  enum Entry
  {
    ENTRY_INVALID,
    ENTRY_SEPARATOR,
    ENTRY_DEFAULT,
    ENTRY_CARD,
    ENTRY_USER_DEFINED
  };

  enum Extra_Roles
  {
    ROLE_INDEX = ( Qt::UserRole + 1 ),
    ROLE_ID = ( Qt::UserRole + 2 ),
    ROLE_DRIVER = ( Qt::UserRole + 3 ),
    ROLE_NAME = ( Qt::UserRole + 4 ),
    ROLE_LONG_NAME = ( Qt::UserRole + 5 ),
    ROLE_MIXER_NAME = ( Qt::UserRole + 6 ),
    ROLE_COMPONENTS = ( Qt::UserRole + 7 )
  };

  /// @brief The first entry is the default mixer
  static constexpr int cards_offset = 2;

  // -- Properties

  Q_PROPERTY ( int count READ count NOTIFY countChanged )

  // -- Construction

  Mixers_Model ( QSnd::Cards_Db * cards_db_n, QObject * parent_n = nullptr );

  ~Mixers_Model ();

  // -- Cards model

  Cards_Model *
  cards_model ()
  {
    return &_cards_model;
  }

  const Cards_Model *
  cards_model () const
  {
    return &_cards_model;
  }

  /// @return true if the card id appears more than 1 time in the cards database
  bool
  card_id_is_unique ( const QString & card_id_n ) const;

  // -- Number of rows

  int
  count () const;

  Q_SIGNAL
  void
  countChanged ();

  QModelIndex
  control_index ( const QSnd::Ctl_Address & ctl_addr_n ) const;

  // -- Model index evaluation

  /// @brief Computes the entry type from the given model index
  Entry
  entry ( const QModelIndex & index_n ) const;

  /// @brief Returns the card info for a given model index
  std::shared_ptr< const QSnd::Card_Info >
  card_info ( const QModelIndex & index_n ) const;

  // -- Reload

  Q_SLOT
  void
  reload ();

  // -- Model inteface

  QHash< int, QByteArray >
  roleNames () const override;

  int
  rowCount ( const QModelIndex & parent_n = QModelIndex () ) const override;

  Qt::ItemFlags
  flags ( const QModelIndex & index_n ) const override;

  QVariant
  data ( const QModelIndex & index_n,
         int role_n = Qt::DisplayRole ) const override;

  protected:
  // -- Utility

  Q_SLOT
  void
  reload_begin ();

  Q_SLOT
  void
  reload_finish ();

  Q_SLOT
  void
  cards_insert_begin ( const QModelIndex & parent_n, int start_n, int end_n );

  Q_SLOT
  void
  cards_insert_done ( const QModelIndex & parent_n, int start_n, int end_n );

  Q_SLOT
  void
  cards_remove_begin ( const QModelIndex & parent_n, int start_n, int end_n );

  Q_SLOT
  void
  cards_remove_done ( const QModelIndex & parent_n, int start_n, int end_n );

  private:
  // -- Attributes
  QSnd::Card_Info _default_info;
  QSnd::Card_Info _user_defined_info;
  QSnd::Cards_Model _cards_model;
};

} // namespace QSnd
