1 #ifndef AFTL_MTP_METADATA_LIBRARY_H
2 #define AFTL_MTP_METADATA_LIBRARY_H
3 
4 #include <mtp/ptp/ObjectId.h>
5 #include <mtp/ptp/ObjectFormat.h>
6 #include <mtp/types.h>
7 #include <functional>
8 #include <memory>
9 #include <string>
10 #include <unordered_map>
11 #include <unordered_set>
12 
13 namespace mtp
14 {
15 	class Session;
16 	DECLARE_PTR(Session);
17 
18 	class Library
19 	{
20 		SessionPtr		_session;
21 		StorageId		_storage;
22 
23 	public:
24 		enum struct State {
25 			Initialising,
26 			QueryingArtists,
27 			LoadingArtists,
28 			QueryingAlbums,
29 			LoadingAlbums,
30 			Loaded
31 		};
32 		using ProgressReporter = std::function<void (State, u64, u64)>;
33 
34 		struct Artist
35 		{
36 			ObjectId 		Id;
37 			ObjectId		MusicFolderId;
38 			std::string 	Name;
39 		};
40 		DECLARE_PTR(Artist);
41 
42 		struct Album
43 		{
44 			ObjectId 		Id;
45 			ObjectId		MusicFolderId;
46 			ArtistPtr		Artist;
47 			std::string 	Name;
48 			time_t	 		Year = 0;
49 			bool			RefsLoaded = false;
50 
51 			void LoadRefs();
52 
53 			std::unordered_set<ObjectId> Refs;
54 			std::unordered_multimap<std::string, int> Tracks;
55 		};
56 		DECLARE_PTR(Album);
57 
58 		struct NewTrackInfo
59 		{
60 			ObjectId		Id;
61 			std::string 	Name;
62 			int				Index;
63 		};
64 
65 	private:
66 		ObjectId _artistsFolder;
67 		ObjectId _albumsFolder;
68 		ObjectId _musicFolder;
69 		bool _artistSupported;
70 		bool _albumDateAuthoredSupported;
71 
72 		using ArtistMap = std::unordered_map<std::string, ArtistPtr>;
73 		ArtistMap _artists;
74 
75 		using AlbumKey = std::pair<ArtistPtr, std::string>;
76 		struct AlbumKeyHash
operatorAlbumKeyHash77 		{ size_t operator() (const AlbumKey & key) const {
78 			return std::hash<ArtistPtr>()(key.first) + std::hash<std::string>()(key.second);
79 		}};
80 
81 		using AlbumMap = std::unordered_map<AlbumKey, AlbumPtr, AlbumKeyHash>;
82 		AlbumMap _albums;
83 
84 		using NameToObjectIdMap = std::unordered_map<std::string, ObjectId>;
85 		NameToObjectIdMap ListAssociations(ObjectId parentId);
86 
87 		ObjectId GetOrCreate(ObjectId parentId, const std::string &name);
88 		void LoadRefs(AlbumPtr album);
89 
90 	public:
91 		Library(const mtp::SessionPtr & session, ProgressReporter && reporter = ProgressReporter());
92 		~Library();
93 
94 		static bool Supported(const mtp::SessionPtr & session);
95 
96 		//search by Metadata?
97 		ArtistPtr GetArtist(std::string name);
98 		ArtistPtr CreateArtist(std::string name);
99 
100 		AlbumPtr GetAlbum(const ArtistPtr & artist, std::string name);
101 		AlbumPtr CreateAlbum(const ArtistPtr & artist, std::string name, int year);
102 		bool HasTrack(const AlbumPtr & album, const std::string &name, int trackIndex);
103 		NewTrackInfo CreateTrack(const ArtistPtr & artist, const AlbumPtr & album, ObjectFormat type, std::string name, const std::string & genre, int trackIndex, const std::string &filename, size_t size);
104 		void AddTrack(AlbumPtr album, const NewTrackInfo &ti);
105 	};
106 	DECLARE_PTR(Library);
107 }
108 
109 #endif
110