/* DBusMPRIS.h */

/* Copyright (C) 2011-2024 Michael Lugmair (Lucio Carreras)
 *
 * This file is part of sayonara player
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DBUS_MPRIS_H
#define DBUS_MPRIS_H

#include "DBusAdaptor.h"

#include "Utils/MetaData/MetaData.h"
#include "Utils/Pimpl.h"

#include <QDBusObjectPath>
#include <QObject>
#include <QPixmap>
#include <QVariant>

class QMainWindow;
class PlayManager;
namespace Playlist
{
	class Accessor;
}

namespace Util
{
	class FileSystem;
}

namespace Dbus::Mpris
{
	class MediaPlayer2 :
		public Adapator
	{
		Q_OBJECT
		PIMPL(MediaPlayer2)

		signals:
			void Seeked(qlonglong position);

		public:
			MediaPlayer2(QMainWindow* player, PlayManager* playManager, Playlist::Accessor* playlistAccessor,
			             const std::shared_ptr<Util::FileSystem>& fileSystem);
			~MediaPlayer2() override;

			Q_PROPERTY(bool CanQuit READ CanQuit CONSTANT)
			[[nodiscard]] bool CanQuit() const;

			Q_PROPERTY(bool CanRaise READ CanRaise CONSTANT)
			[[nodiscard]] bool CanRaise() const;

			Q_PROPERTY(bool HasTrackList READ HasTrackList)
			[[nodiscard]] bool HasTrackList() const;

			Q_PROPERTY(QString Identity READ Identity CONSTANT)
			[[nodiscard]] QString Identity() const;

			Q_PROPERTY(QString DesktopEntry READ DesktopEntry CONSTANT)
			[[nodiscard]] QString DesktopEntry() const;

			Q_PROPERTY(QStringList SupportedUriSchemes READ SupportedUriSchemes CONSTANT)
			[[nodiscard]] QStringList SupportedUriSchemes() const;

			Q_PROPERTY(QStringList SupportedMimeTypes READ SupportedMimeTypes CONSTANT)
			[[nodiscard]] QStringList SupportedMimeTypes() const;

			Q_PROPERTY(bool CanSetFullscreen READ CanSetFullscreen)
			[[nodiscard]] bool CanSetFullscreen() const;

			Q_PROPERTY(bool Fullscreen READ Fullscreen WRITE SetFullscreen)
			[[nodiscard]] bool Fullscreen() const;
			void SetFullscreen(bool b);

			void Raise();
			void Quit();

			Q_PROPERTY(QString PlaybackStatus READ PlaybackStatus)
			[[nodiscard]] QString PlaybackStatus() const;

			Q_PROPERTY(QString LoopStatus READ LoopStatus WRITE SetLoopStatus)
			[[nodiscard]] QString LoopStatus() const;
			void SetLoopStatus(const QString& status);

			Q_PROPERTY(double Rate READ Rate WRITE SetRate)
			[[nodiscard]] double Rate() const;
			void SetRate(double rate);

			Q_PROPERTY(int Rating READ Rating)
			[[nodiscard]] int Rating() const;

			Q_PROPERTY(bool Shuffle READ Shuffle WRITE SetShuffle)
			[[nodiscard]] bool Shuffle() const;
			void SetShuffle(bool shuffle);

			Q_PROPERTY(QVariantMap Metadata READ Metadata)
			[[nodiscard]] QVariantMap Metadata() const;

			Q_PROPERTY(double Volume READ Volume WRITE SetVolume)
			[[nodiscard]] double Volume() const;
			void SetVolume(double volume);
			void IncreaseVolume();
			void DecreaseVolume();

			Q_PROPERTY(qlonglong Position READ Position)
			[[nodiscard]] qlonglong Position() const;
			void SetPosition(const QDBusObjectPath& trackId, qlonglong position);

			Q_PROPERTY(double MinimumRate READ MinimumRate)
			[[nodiscard]] double MinimumRate() const;

			Q_PROPERTY(double MaximumRate READ MaximumRate)
			[[nodiscard]] double MaximumRate() const;

			Q_PROPERTY(bool CanGoNext READ CanGoNext)
			[[nodiscard]] bool CanGoNext() const;

			Q_PROPERTY(bool CanGoPrevious READ CanGoPrevious)
			[[nodiscard]] bool CanGoPrevious() const;

			Q_PROPERTY(bool CanPlay READ CanPlay)
			[[nodiscard]] bool CanPlay() const;

			Q_PROPERTY(bool CanPause READ CanPause)
			[[nodiscard]] bool CanPause() const;

			Q_PROPERTY(bool CanSeek READ CanSeek)
			[[nodiscard]] bool CanSeek() const;

			Q_PROPERTY(bool CanControl READ CanControl CONSTANT)
			[[nodiscard]] bool CanControl() const;

			void Next();
			void Previous();
			void Pause();
			void PlayPause();
			void Stop();
			void Play();
			void Seek(qlonglong offset);
			void OpenUri(const QString& uri);

		public slots: // NOLINT(readability-redundant-access-specifiers)
			void positionChanged(MilliSeconds positionMs);
			void volumeChanged(int volume);
			void trackIndexChanged(int index);
			void trackChanged(const MetaData& track);
			void playstateChanged(PlayState state);

		private slots:
			void coverFound(const QPixmap& pixmap);
			void coverLookupFinished(bool success);

		private: // NOLINT(readability-redundant-access-specifiers)
			void init();
	};
} // end namespace Dbus::MPRIS

#endif // DBUS_MPRIS_H