/* MetaData.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/>.
 */

/*
 * MetaData.h
 *
 *  Created on: Mar 10, 2011
 *      Author: Michael Lugmair (Lucio Carreras)
 */

#ifndef SAYONARA_PLAYER_METADATA_H
#define SAYONARA_PLAYER_METADATA_H

#include "Utils/MetaData/LibraryItem.h"
#include "Utils/MetaData/RadioMode.h"
#include "Utils/MetaData/Genre.h"
#include "Utils/Library/Sortorder.h"
#include "Utils/Pimpl.h"

#include <QMetaType>
#include <QString>

class QDateTime;
class MetaData :
	public LibraryItem
{
	PIMPL(MetaData)

	public:
		struct Bookmark
		{
			QString title;
			Seconds timestamp;

			[[nodiscard]] bool operator==(const Bookmark& b2) const;
		};

		MetaData();
		explicit MetaData(const QString& path);
		MetaData(const MetaData& other);
		MetaData(MetaData&& other) noexcept;
		MetaData& operator=(const MetaData& md);
		MetaData& operator=(MetaData&& md) noexcept;

		~MetaData() override;

		[[nodiscard]] QString title() const;
		void setTitle(const QString& title);

		[[nodiscard]] QString artist() const;
		void setArtist(const QString& artist);
		[[nodiscard]] ArtistId artistId() const;
		void setArtistId(ArtistId id);

		[[nodiscard]] QString album() const;
		void setAlbum(const QString& album);
		[[nodiscard]] AlbumId albumId() const;
		void setAlbumId(AlbumId id);

		[[nodiscard]] const QString& comment() const;
		void setComment(const QString& comment);

		[[nodiscard]] QString filepath() const;
		[[nodiscard]] HashValue filepathHash() const;
		QString setFilepath(const QString& filepath, RadioMode mode = RadioMode::Undefined);

		[[nodiscard]] ArtistId albumArtistId() const;
		[[nodiscard]] QString albumArtist() const;

		void setAlbumArtist(const QString& albumArtist, ArtistId id = -1);
		void setAlbumArtistId(ArtistId id);

		void setRadioStation(const QString& url, const QString& name = QString());
		[[nodiscard]] QString radioStation() const;
		[[nodiscard]] QString radioStationName() const;

		[[nodiscard]] RadioMode radioMode() const;
		void changeRadioMode(RadioMode mode);

		[[nodiscard]] bool isUpdatable() const;
		void setUpdateable(bool b);

		[[nodiscard]] bool isValid() const;

		bool operator==(const MetaData& other) const;
		bool operator!=(const MetaData& other) const;
		[[nodiscard]] bool isEqual(const MetaData& other) const;
		[[nodiscard]] bool isEqualDeep(const MetaData& md) const;

		[[nodiscard]] const Util::Set<GenreID>& genreIds() const;
		[[nodiscard]] Util::Set<Genre> genres() const;
		[[nodiscard]] bool hasGenre(const Genre& genre) const;
		bool removeGenre(const Genre& genre);
		bool addGenre(const Genre& genre);
		void setGenres(const Util::Set<Genre>& genres);
		void setGenres(const QStringList& newGenres);

		void setCreatedDate(uint64_t t);
		[[nodiscard]] uint64_t createdDate() const;
		[[nodiscard]] QDateTime createdDateTime() const;

		void setModifiedDate(uint64_t t);
		[[nodiscard]] uint64_t modifiedDate() const;
		[[nodiscard]] QDateTime modifiedDateTime() const;

		[[nodiscard]] QString genresToString() const;
		[[nodiscard]] QStringList genresToList() const;

		[[nodiscard]] Disc discnumber() const;
		void setDiscnumber(const Disc& value);

		[[nodiscard]] Disc discCount() const;
		void setDiscCount(const Disc& value);

		[[nodiscard]] Bitrate bitrate() const;
		void setBitrate(const Bitrate& value);

		[[nodiscard]] TrackNum trackNumber() const;
		void setTrackNumber(const uint16_t& value);

		[[nodiscard]] Year year() const;
		void setYear(const uint16_t& value);

		[[nodiscard]] Filesize filesize() const;
		void setFilesize(const Filesize& value);

		[[nodiscard]] Rating rating() const;
		void setRating(const Rating& value);

		[[nodiscard]] MilliSeconds durationMs() const;
		void setDurationMs(const MilliSeconds& value);

		[[nodiscard]] bool isDisabled() const;
		void setDisabled(bool value);

		[[nodiscard]] LibraryId libraryId() const;
		void setLibraryid(const LibraryId& value);

		[[nodiscard]] TrackID id() const;
		void setId(const TrackID& value);

		[[nodiscard]] static QString getTitleFromFilepath(const QString& filepath);

		void addBookmark(const Bookmark& bookmark);
		void removeBookmark(const Bookmark& bookmark);
		[[nodiscard]] const QList<Bookmark>& bookmarks() const;
};

#ifndef MetaDataDeclared
Q_DECLARE_METATYPE(MetaData)
#define MetaDataDeclared
#endif

#endif /* SAYONARA_PLAYER_METADATA_H */
