//
// © 2018-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "IoTTypes.h"

NS_ASSUME_NONNULL_BEGIN

@class IoTMediaItem;
@class IoTPlayerGroup;

/**
 @brief A representation of a group's playlist.
 @discussion A playlist corresponds to the group's "queued items". It does not corresponding to what is described as a playlist in the application UI which are user created collections of tracks stored locally on the mobile device.

 	 The group itself does not "own" a playlist. It is the playlist owned by the source player within a group when audio is streamed from a playlist.

     There is no public initializer for IoTPlaylist.
*/
@interface IoTPlaylist : NSObject

- (instancetype)init NS_UNAVAILABLE;

/**
 @brief The number of items in the playlist.
*/
@property (nonatomic, readonly) int count;

/**
 @brief A string field that may be set on the playlist.
*/
@property (nonatomic, readonly) NSString *userData;

/**
 @brief The current item of the playlist.
 @discussion When a group is in the playing or paused state, and playing from a playlist, this would most likely be a representation of the currently playing media item. Otherwise it will be an "empty" media item.
 */
@property (nonatomic, readonly) IoTMediaItem *currentItem;

/**
 @brief The index of the currently playing item in the playlist.
 @discussion When a group is in the playing or paused state, and playing from a playlist, this would is the index of the currently playing item. If the source player from the group has a playlist *but is not playing from it* then this value will be -1.
 */
@property (nonatomic, readonly) int indexPlaying;

/**
 @brief Is loop mode available for this playlist (source player).
 */
@property (nonatomic, readonly) BOOL isLoopModeEnabled;

/**
 @brief Is shuffle mode available for this playlist (source player).
 */
@property (nonatomic, readonly) BOOL isShuffleModeEnabled;

/**
 @brief The current loop mode for this playlist (source player).
 */
@property (nonatomic, readonly) IoTLoopMode loopMode;

/**
 @brief The current shuffle mode for this playlist (source player).
 */
@property (nonatomic, readonly) IoTShuffleMode shuffleMode;

/**
 @brief Asynchronously dispatch request to set the loop mode of the playlist.
 @discussion The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param loopMode the requested loopMode.
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)setLoopMode:(IoTLoopMode)loopMode
         completion:(nullable IoTCompletionHandler)completion
    completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to set the shuffle mode of the playlist.
 @discussion The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param shuffleMode the requested shuffle mode.
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)setShuffleMode:(IoTShuffleMode)shuffleMode
            completion:(nullable IoTCompletionHandler)completion
       completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to play a media item from the playlist.
 @discussion This method is preferred over the use of IoTPlayerGroup's playMediaItem: method.
	 The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param index the index of media item to play.
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)playItemAtIndex:(int)index
             completion:(nullable IoTCompletionHandler)completion
        completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to add a media item to the playlist at a given point. Optionally the newly added item may also become the currently playing item.
 @discussion The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param mediaItem the media item to add to the playlist
 @param index the position in the playlist for the new item.
 @param play YES if the newly added item should become the currently playing track (and playback resume if paused or stopped).
 @param userData used to set the userData field on the playlist
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
*/
- (void)addMediaItem:(IoTMediaItem *)mediaItem
             atIndex:(int)index
                play:(BOOL)play
            userData:(NSString *)userData
          completion:(nullable IoTCompletionHandler)completion
     completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to add media items to the playlist starting at a given point. Optionally the first newly added item may also become the currently playing item.
 @discussion The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param mediaItems the media item to add to the playlist
 @param index the position in the playlist for the first new item.
 @param play YES if the first newly added item should become the currently playing track (and playback resume if paused or stopped).
 @param userData used to set the userData field on the playlist
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)addMediaItems:(NSArray<IoTMediaItem *> *)mediaItems
              atIndex:(int)index
                 play:(BOOL)play
             userData:(NSString *)userData
           completion:(nullable IoTCompletionHandler)completion
      completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to remove media items to the playlist.
 @discussion The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param range the index range of the items to remove
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)removeMediaItemsInRange:(NSRange)range
                     completion:(nullable IoTCompletionHandler)completion
                completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to move media items within the playlist.
 @discussion The completion block notes the request as successful if the POST succeeds. It does not ensure that the request was effected.
 @param range the index range of the items to move.
 @param position the starting position for the new items. The move process moves the items before removing them from their old position. For example, when moving an item from index 0 to index 1, the value passed to position should be 2.
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)moveMediaItemsInRange:(NSRange)range
                     position:(int)position
                   completion:(nullable IoTCompletionHandler)completion
              completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to remove all media items from the playlist.
 @param completion block to be called asynchronously upon completion (successful or otherwise).
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)clearWithCompletion:(nullable IoTCompletionHandler)completion
            completionQueue:(nullable dispatch_queue_t)queue;

/**
 @brief Asynchronously dispatch request to fetch the metadata for media items from the playlist in the given range.
 @param range the range of indices for which metadat shoudl be fetched
 @param completion block to be called asynchronously upon completion (successful or otherwise). The metadata is provided in this block if successful.
 @param queue the dispatch queue to use when calling the completion block.
 */
- (void)getItemsInRange:(NSRange)range
             completion:(nullable void(^)(BOOL success, NSArray<IoTMediaItem *> * items, NSError * _Nullable error))completion
        completionQueue:(nullable dispatch_queue_t)queue;

@end

NS_ASSUME_NONNULL_END
