/*
 * Cantata
 *
 * Copyright (c) 2011-2022 Craig Drummond <craig.p.drummond@gmail.com>
 *
 * ----
 *
 * 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 2 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; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef AUDIOCDDEVICE_H
#define AUDIOCDDEVICE_H

#include "device.h"
#include "gui/covers.h"
#include "http/httpserver.h"
#include "solid-lite/opticaldrive.h"
#include <QImage>

class CddbInterface;
class MusicBrainz;
struct CdAlbum;

class AudioCdDevice : public Device {
	Q_OBJECT

public:
	enum Service {
		SrvNone,
		SrvCddb,
		SrvMusicBrainz
	};

	static const QLatin1String constAnyDev;

	static QString coverUrl(QString id);
	static QString getDevice(const QUrl& url);

	AudioCdDevice(MusicLibraryModel* m, Solid::Device& dev);
	virtual ~AudioCdDevice();

	void dequeue();
	QImage image() const { return cover().img; }
	bool isAudioDevice(const QString& dev) const;
	bool supportsDisconnect() const { return 0 != drive; }
	bool isConnected() const { return !device.isEmpty(); }
	void rescan(bool useCddb);
	bool isRefreshing() const { return lookupInProcess; }
	void toggle();
	void stop();
	QString path() const { return devPath; }
	void addSong(const Song&, bool, bool) {}
	void copySongTo(const Song& s, const QString& musicPath, bool overwrite, bool copyCover);
	void removeSong(const Song&) {}
	void cleanDirs(const QSet<QString>&) {}
	double usedCapacity() { return 1.0; }
	QString capacityString() { return detailsString; }
	qint64 freeSpace() { return 1.0; }
	DevType devType() const { return AudioCd; }
	void saveOptions() {}
	QString subText() { return album; }
	quint32 totalTime();
	bool canPlaySongs() const { return HttpServer::self()->isAlive(); }
	QString albumName() const { return album; }
	QString albumArtist() const { return artist; }
	QString albumComposer() const { return composer; }
	QString albumGenre() const { return genre; }
	int albumDisc() const { return disc; }
	int albumYear() const { return year; }
	const Covers::Image& cover() const { return coverImage; }
	void setCover(const Covers::Image& img);
	const QPixmap& coverPix() const { return scaledCover; }
	void scaleCoverPix(int size) const;
	void autoplay();

Q_SIGNALS:
	void lookup(bool full);
	void matches(const QString& u, const QList<CdAlbum>&);

public Q_SLOTS:
	void percent(int pc);
	void copySongToResult(int status);
	void setDetails(const CdAlbum& a);
	void cdMatches(const QList<CdAlbum>& albums);
	void setCover(const Song& song, const QImage& img, const QString& file);

private:
	void connectService(bool useCddb);
	void playTracks();
	void updateDetails();

private:
	Solid::OpticalDrive* drive;
#ifdef CDDB_FOUND
	CddbInterface* cddb;
#endif
#ifdef MusicBrainz5_FOUND
	MusicBrainz* mb;
#endif
	QString detailsString;
	QString album;
	QString artist;
	QString composer;
	QString genre;
	QString device;
	QString devPath;
	int year;
	int disc;
	quint32 time;
	bool lookupInProcess;
	Covers::Image coverImage;
	mutable QPixmap scaledCover;
	bool autoPlay;
};

#endif
