1 /*
2  *  Copyright (C) 2005-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "ServiceBroker.h"
12 #include "guilib/IMsgTargetCallback.h"
13 #include "messaging/IMessageTarget.h"
14 
15 #include <memory>
16 
17 #define PLAYLIST_NONE    -1
18 #define PLAYLIST_MUSIC   0
19 #define PLAYLIST_VIDEO   1
20 #define PLAYLIST_PICTURE 2
21 
22 class CAction;
23 class CFileItem; typedef std::shared_ptr<CFileItem> CFileItemPtr;
24 class CFileItemList;
25 
26 class CVariant;
27 
28 namespace PLAYLIST
29 {
30 /*!
31  \ingroup windows
32  \brief Manages playlist playing.
33  */
34 enum REPEAT_STATE { REPEAT_NONE = 0, REPEAT_ONE, REPEAT_ALL };
35 
36 class CPlayList;
37 
38 class CPlayListPlayer : public IMsgTargetCallback,
39                         public KODI::MESSAGING::IMessageTarget
40 {
41 
42 public:
43   CPlayListPlayer(void);
44   ~CPlayListPlayer(void) override;
45   bool OnMessage(CGUIMessage &message) override;
46 
47   int GetMessageMask() override;
48   void OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg) override;
49 
50   /*! \brief Play the next (or another) entry in the current playlist
51    \param offset The offset from the current entry (defaults to 1, i.e. the next entry).
52    \param autoPlay Whether we should start playing if not already (defaults to false).
53    */
54   bool PlayNext(int offset = 1, bool autoPlay = false);
55 
56   /*! \brief Play the previous entry in the current playlist
57    \sa PlayNext
58    */
59   bool PlayPrevious();
60   bool PlaySongId(int songId);
61   bool Play();
62 
63   /*! \brief Creates a new playlist for an item and starts playing it
64    \param pItem The item to play.
65    */
66   bool Play(const CFileItemPtr& pItem, const std::string& player);
67 
68   /*! \brief Start playing a particular entry in the current playlist
69    \param index the index of the item to play. This value is modified to ensure it lies within the current playlist.
70    \param replace whether this item should replace the currently playing item. See CApplication::PlayFile (defaults to false).
71    \param playPreviousOnFail whether to go back to the previous item if playback fails (default to false)
72    */
73   bool Play(int index,
74             const std::string& player,
75             bool replace = false,
76             bool playPreviousOnFail = false);
77 
78   /*! \brief Returns the index of the current item in active playlist.
79    \return Current item in the active playlist.
80    \sa SetCurrentSong
81    */
82   int GetCurrentSong() const;
83 
84   /*! \brief Change the current item in the active playlist.
85    \param index item index in playlist. Set only if the index is within the range of the current playlist.
86    \sa GetCurrentSong
87    */
88   void SetCurrentSong(int index);
89 
90   int GetNextSong();
91 
92   /*! \brief Get the index in the playlist that is offset away from the current index in the current playlist.
93    Obeys any repeat settings (eg repeat one will return the current index regardless of offset)
94    \return the index of the entry, or -1 if there is no current playlist. There is no guarantee that the returned index is valid.
95    */
96   int GetNextSong(int offset) const;
97 
98   /*! \brief Set the active playlist
99    \param playList Values can be PLAYLIST_NONE, PLAYLIST_MUSIC or PLAYLIST_VIDEO
100    \sa GetCurrentPlaylist
101    */
102   void SetCurrentPlaylist(int playlist);
103 
104   /*! \brief Get the currently active playlist
105    \return PLAYLIST_NONE, PLAYLIST_MUSIC or PLAYLIST_VIDEO
106    \sa SetCurrentPlaylist, GetPlaylist
107    */
108   int GetCurrentPlaylist() const;
109 
110   /*! \brief Get a particular playlist object
111    \param playList Values can be PLAYLIST_MUSIC or PLAYLIST_VIDEO
112    \return A reference to the CPlayList object.
113    \sa GetCurrentPlaylist
114    */
115   CPlayList& GetPlaylist(int playlist);
116   const CPlayList& GetPlaylist(int iPlaylist) const;
117 
118   /*! \brief Removes any item from all playlists located on a removable share
119    \return Number of items removed from PLAYLIST_MUSIC and PLAYLIST_VIDEO
120    */
121   int RemoveDVDItems();
122 
123   /*! \brief Resets the current song and unplayable counts.
124    Does not alter the active playlist.
125   */
126   void Reset();
127 
128   void ClearPlaylist(int iPlaylist);
129   void Clear();
130 
131   /*! \brief Set shuffle state of a playlist.
132    If the shuffle state changes, the playlist is shuffled or unshuffled.
133    Has no effect if Party Mode is enabled.
134    \param playlist the playlist to (un)shuffle, PLAYLIST_MUSIC or PLAYLIST_VIDEO.
135    \param shuffle set true to shuffle, false to unshuffle.
136    \param notify notify the user with a Toast notification (defaults to false)
137    \sa IsShuffled
138    */
139   void SetShuffle(int playlist, bool shuffle, bool notify = false);
140 
141   /*! \brief Return whether a playlist is shuffled.
142    If partymode is enabled, this always returns false.
143    \param playlist the playlist to query for shuffle state, PLAYLIST_MUSIC or PLAYLIST_VIDEO.
144    \return true if the given playlist is shuffled and party mode isn't enabled, false otherwise.
145    \sa SetShuffle
146    */
147   bool IsShuffled(int iPlaylist) const;
148 
149   /*! \brief Return whether or not something has been played yet from the current playlist.
150    \return true if something has been played, false otherwise.
151    */
152   bool HasPlayedFirstFile() const;
153 
154   /*! \brief Set repeat state of a playlist.
155    If called while in Party Mode, repeat is disabled.
156    \param playlist the playlist to set repeat state for, PLAYLIST_MUSIC or PLAYLIST_VIDEO.
157    \param state set to REPEAT_NONE, REPEAT_ONE or REPEAT_ALL
158    \param notify notify the user with a Toast notification
159    \sa GetRepeat
160    */
161   void SetRepeat(int iPlaylist, REPEAT_STATE state, bool notify = false);
162   REPEAT_STATE GetRepeat(int iPlaylist) const;
163 
164   // add items via the playlist player
165   void Add(int iPlaylist, const CPlayList& playlist);
166   void Add(int iPlaylist, const CFileItemPtr &pItem);
167   void Add(int iPlaylist, const CFileItemList& items);
168   void Insert(int iPlaylist, const CPlayList& playlist, int iIndex);
169   void Insert(int iPlaylist, const CFileItemPtr &pItem, int iIndex);
170   void Insert(int iPlaylist, const CFileItemList& items, int iIndex);
171   void Remove(int iPlaylist, int iPosition);
172   void Swap(int iPlaylist, int indexItem1, int indexItem2);
173 
174   bool IsSingleItemNonRepeatPlaylist() const;
175 
176   bool OnAction(const CAction &action);
177 protected:
178   /*! \brief Returns true if the given is set to repeat all
179    \param playlist Playlist to be query
180    \return true if the given playlist is set to repeat all, false otherwise.
181    */
182   bool Repeated(int playlist) const;
183 
184   /*! \brief Returns true if the given is set to repeat one
185    \param playlist Playlist to be query
186    \return true if the given playlist is set to repeat one, false otherwise.
187    */
188   bool RepeatedOne(int playlist) const;
189 
190   void ReShuffle(int iPlaylist, int iPosition);
191 
192   void AnnouncePropertyChanged(int iPlaylist, const std::string &strProperty, const CVariant &value);
193 
194   bool m_bPlayedFirstFile;
195   bool m_bPlaybackStarted;
196   int m_iFailedSongs;
197   unsigned int m_failedSongsStart;
198   int m_iCurrentSong;
199   int m_iCurrentPlayList;
200   CPlayList* m_PlaylistMusic;
201   CPlayList* m_PlaylistVideo;
202   CPlayList* m_PlaylistEmpty;
203   REPEAT_STATE m_repeatState[2];
204 };
205 
206 }
207