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

#import "IoTPlayer+CategoriesHeader.h"

@implementation IoTPlayer(PlayerGroup)

- (BOOL)isMasterVolumeSupported
{
    RETURN_SUPPORTED(groupVolumeControlAttr)
}

- (double)masterVolume
{
    RETURN_GETTER(double, groupVolumeControlAttr, volume, 0.5)
}

- (double)masterMaxVolume
{
    return 1.0;
}

- (BOOL)isMasterVolumeMuted
{
	RETURN_GETTER(BOOL, groupVolumeControlAttr, mute, NO)
}

- (void)setMasterVolume:(double)volume
             completion:(void(^)(BOOL, NSError *))completion
        completionQueue:(dispatch_queue_t)queue
{
	SETTER(groupVolumeControlAttr,volume,volume,postGroupVolumeControlWith)
}

- (void)setMasterMuted:(BOOL)mute
            completion:(void(^)(BOOL, NSError *))completion
       completionQueue:(dispatch_queue_t)queue
{
    SETTER(groupVolumeControlAttr,mute,mute,postGroupVolumeControlWith)
}

- (IoTPlayState)playState
{
    RETURN_GETTER(IoTPlayState, mediaPlayerAttr, playState.playState, IoTPlayStateStopped)
}

- (void)handlePlayStateUpdate:(BOOL)force
{
    IoTPlayState state = [self playState];
    if ((state == IoTPlayStatePlaying) && (force || (self.timeStartedPlayback < 0))) {
        self.timeStartedPlayback = [[NSDate date] timeIntervalSince1970];
    } else if (state != IoTPlayStatePlaying) {
        self.timeStartedPlayback = -1;
    }
}

- (int)playerPosition
{
    NSTimeInterval diff = 0;
    if (self.timeStartedPlayback >= 0) {
    	diff = [[NSDate date] timeIntervalSince1970] - self.timeStartedPlayback;
    }

    int lastPositionReported = 0;
    if (self.state.mediaPlayerAttr) {
        lastPositionReported = self.state.mediaPlayerAttr.playState.positionMsecs;
    }
    return lastPositionReported + (diff * 1000);
}

- (BOOL)isSeekEnabled
{
    RETURN_GETTER(BOOL, mediaPlayerAttr, enabledControls.seek, NO)
}

- (BOOL)isPreviousEnabled
{
    RETURN_GETTER(BOOL, mediaPlayerAttr, enabledControls.previous, NO)
}

- (BOOL)isNextEnabled
{
    RETURN_GETTER(BOOL, mediaPlayerAttr, enabledControls.next, NO)
}

- (BOOL)isPauseEnabled
{
    RETURN_GETTER(BOOL, mediaPlayerAttr, enabledControls.pause, NO)
}

- (void)setPlayerPosition:(int)position
               completion:(void(^)(BOOL, NSError *))completion
          completionQueue:(dispatch_queue_t)queue
{
    IoTSetPositionInAttr *attr = [[IoTSetPositionInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    attr.positionMsecs = position;
    [self.allPlayController postSetPositionWith:attr
                                    completion: ^(BOOL success) {
                                        if (completion && queue) {
                                            dispatch_async(queue, ^{
                                                completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                            });
                                        }
                                    } completionQueue:self.backgroundQueue];
}

- (void)playWithCompletion:(void(^)(BOOL, NSError *))completion
           completionQueue:(dispatch_queue_t)queue
{
    MEDIA_COMMAND(postPlayWithCompletion)
}

- (void)playMediaItem:(IoTMediaItem *)mediaItem
           completion:(void(^)(BOOL, NSError *))completion
      completionQueue:(dispatch_queue_t)queue
{
    IoTPlayItemInAttr *playItem = [[IoTPlayItemInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    IoTPlayItemAttr *item = [[IoTPlayItemAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    [mediaItem copyToAttr:item];

    playItem.item = item;
    BOOL success = [self.allPlayController postPlayItemWith:playItem
                                                completion:^(BOOL success) {
                                                    if (completion && queue) {
                                                        dispatch_async(queue, ^{
                                                            completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                                        });
                                                    }
                                                } completionQueue:self.backgroundQueue];

    if (!success && completion && queue) {
        dispatch_async(queue, ^{
            completion(NO, [NSError errorWithIoTError:IoTErrorRequest description:nil]);
        });
    }
}

- (void)playItemAtIndex:(int)index
             completion:(void(^)(BOOL, NSError *))completion
        completionQueue:(dispatch_queue_t)queue
{
    IoTPlayIndexInAttr *playAttr = [[IoTPlayIndexInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    playAttr.itemIndex = index;
    playAttr.startPositionMsecs = 0;
    
    BOOL success = [self.allPlayController postPlayIndexWith:playAttr
                                                 completion:^(BOOL success) {
                                                     if (completion && queue) {
                                                         dispatch_async(queue, ^{
                                                             completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                                         });
                                                     }
                                                 } completionQueue:self.backgroundQueue];

    if (!success && completion && queue) {
        dispatch_async(queue, ^{
            completion(NO, [NSError errorWithIoTError:IoTErrorNotSupported description:nil]);
        });
    }
}

- (void)pauseWithCompletion:(void(^)(BOOL, NSError *))completion
            completionQueue:(dispatch_queue_t)queue
{
    MEDIA_COMMAND(postPauseWithCompletion)
}

- (void)stopWithCompletion:(void(^)(BOOL, NSError *))completion
           completionQueue:(dispatch_queue_t)queue
{
    MEDIA_COMMAND(postStopWithCompletion)
}

- (void)nextWithCompletion:(void(^)(BOOL, NSError *))completion
           completionQueue:(dispatch_queue_t)queue
{
    MEDIA_COMMAND(postNextWithCompletion)
}

- (void)previousWithCompletion:(void(^)(BOOL, NSError *))completion
               completionQueue:(dispatch_queue_t)queue
{
    MEDIA_COMMAND(postPreviousWithCompletion)
}

- (void)createPlayerGroupWithName:(NSString *)name
                       completion:(void(^)(BOOL success, NSString * _Nullable groupID, NSError * _Nullable error))completion
                  completionQueue:(dispatch_queue_t)queue
{
    IoTGroupCreateInAttr *attr = [[IoTGroupCreateInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    attr.groupName = name;

    [self.allPlayController postGroupCreateWith:attr
                                    completion:^(IoTGroupCreateOutAttr *outAttr, BOOL success) {
                                        if (completion && queue) {
                                            if (success) {
                                                dispatch_async(queue, ^{
                                                    completion(success, outAttr.groupId, nil);
                                                });
                                            } else {
                                                dispatch_async(queue, ^{
                                                    completion(success, nil, [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                                });
                                            }
                                        }

                                    }
                               completionQueue:self.backgroundQueue];
}

- (void)renamePlayerGroupWithID:(NSString *)groupID
                        newName:(NSString *)newName
                     completion:(nullable IoTCompletionHandler)completion
                completionQueue:(nullable dispatch_queue_t)queue
{
    IoTGroupSetGroupNameInAttr *attr = [[IoTGroupSetGroupNameInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    attr.groupId = groupID;
    attr.groupName = newName;

    [self.allPlayController postGroupSetGroupNameWith:attr
                                          completion:^(BOOL success) {
                                              if (completion && queue) {
                                                  dispatch_async(queue, ^{
                                                      completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                                  });
                                              }
                                          } completionQueue:self.backgroundQueue];
}

- (void)deletePlayerGroupWithID:(NSString *)groupID
                     completion:(void(^)(BOOL, NSError *))completion
                completionQueue:(dispatch_queue_t)queue
{
    IoTGroupDeleteInAttr *attr = [[IoTGroupDeleteInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    attr.groupId = groupID;

    [self.allPlayController postGroupDeleteWith:attr
                                    completion:^(BOOL success) {
                                        if (completion && queue) {
                                            dispatch_async(queue, ^{
                                                completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                            });
                                        }
                                    } completionQueue:self.backgroundQueue];
}

- (void)addToPlayerGroupWithID:(NSString *)groupID
                    completion:(void(^)(BOOL, NSError *))completion
               completionQueue:(dispatch_queue_t)queue
{
    IoTGroupAddToGroupInAttr *attr = [[IoTGroupAddToGroupInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    attr.groupId = groupID;

    [self.allPlayController postGroupAddToGroupWith:attr
                                        completion:^(BOOL success) {
                                            if (completion && queue) {
                                                dispatch_async(queue, ^{
                                                    completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                                });
                                            }
                                        } completionQueue:self.backgroundQueue];
}

- (void)removeFromPlayerGroupWithCompletion:(void(^)(BOOL, NSError *))completion
                            completionQueue:(dispatch_queue_t)queue
{
    IoTGroupRemoveFromGroupInAttr *attr = [[IoTGroupRemoveFromGroupInAttr alloc] initWithStateSyncQueue:self.stateSyncQueue];
    attr.groupId = self.groupID;
    attr.deviceId = self.playerID;
    
    [self.allPlayController postGroupRemoveFromGroupWith:attr
                                             completion:^(BOOL success) {
                                                 if (completion && queue) {
                                                     dispatch_async(queue, ^{
                                                         completion(success, success ? nil : [NSError errorWithIoTError:IoTErrorRequest description:nil]);
                                                     });
                                                 }
                                             } completionQueue:self.backgroundQueue];
}

@end
