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

#pragma once

#include "tray/shared.hpp"
#include <QElapsedTimer>
#include <QLocale>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QVariantMap>
#include <cstdint>

// Forward declaration
class QDBusInterface;
class QDBusServiceWatcher;
class QDBusPendingCallWatcher;

namespace Tray
{

/// @brief Notifier - Sends desktop notifications
///
class Notifier : public QObject
{
  Q_OBJECT

  public:
  // -- Construction

  Notifier ( const Shared & shared_n, QObject * parent_n = nullptr );

  ~Notifier ();

  // -- Message lifetime

  /// @brief Message lifetime in milliseconds
  unsigned int
  message_lifetime () const
  {
    return _call_data.timeout;
  }

  void
  set_message_lifetime ( unsigned int milliseconds_n );

  // -- Notification

  void
  notify_muted ();

  void
  notify_permille ();

  // -- Signals

  Q_SIGNAL
  void
  sig_activated ();

  private:
  // -- Utility

  Q_SLOT
  void
  dbus_service_owner_changed ( const QString & service_name_n,
                               const QString & old_owner_n,
                               const QString & new_owner_n );

  void
  dbus_interface_disconnect ();

  bool
  dbus_interface_connect ();

  void
  notify ( const QString & icon_name_n, const QString & message_n );

  Q_SLOT
  void
  try_submit_notification ();

  Q_SLOT
  void
  call_finished ( QDBusPendingCallWatcher * watcher_n );

  Q_SLOT
  void
  notification_closed ( unsigned int id_n, unsigned int reason_n );

  Q_SLOT
  void
  notification_action ( unsigned int id_n, QString action_key_n );

  private:
  // -- Attributes
  const Shared & _shared;

  QString _dbus_service_name;
  std::unique_ptr< QDBusServiceWatcher > _dbus_service_watcher;
  std::unique_ptr< QDBusInterface > _dbus_interface;
  struct
  {
    QString app_icon;
    QString summary;
    QString body;
  } _last_call;
  bool _call_pending = false;
  bool _body_supported = true;
  struct
  {
    QString method;
    QString app_name;
    std::uint32_t replaces_id = 0;
    QString app_icon;
    QString summary;
    QString body;
    QStringList actions;
    QVariantMap hints;
    std::int32_t timeout = 4000;
  } _call_data;
  QDBusPendingCallWatcher * _call_watcher = nullptr;
  qint64 _call_intervall = 1000 / 60;
  QElapsedTimer _call_elapsed;
  QTimer _call_timer;
  QLocale _locale;
};

} // namespace Tray
