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

#import "IoTPlayer.h"
#import "IoTPlayer+Private.h"
#import "IoTPlayerState.h"
#import "IoTDevice.h"
#import "IoTMediaItem+Private.h"
#include "IoTProperties.h"
#import "IoTAllPlayController.h"
#import "IoTServiceDiscoveryResult.h"
#import "IoTGlobals.h"
#import "NSError+IoTErrors.h"
#import "IoTWrappedRepresentation.h"

#define RETURN_GETTER(type,attr,property,default) \
type ret = default; \
if (self.state.attr) { \
	ret = self.state.attr.property; \
} \
return ret;

#define SETTER(attr,property,variable,method) \
if (!self.state.attr) { \
	if (completion && queue) { \
		dispatch_async(queue, ^{ \
			completion(NO, [NSError errorWithIoTError:IoTErrorNotSupported description:nil]); \
		}); \
    } \
} else { \
	typeof(self.state.attr) attrCopy = [self.state.attr copy]; \
	attrCopy.property = variable; \
	BOOL success = [self.allPlayController method:attrCopy \
									  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]); \
		}); \
	} \
}

#define MEDIA_COMMAND(method) \
BOOL success = [self.allPlayController method:^(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]); \
	}); \
}


#define RETURN_SUPPORTED(attr) \
return self.state.attr != nil; \

#define RETURN_GETTER_WITH_RANGE(type,attr,property,rangeProperty,default) \
type ret = default; \
if (self.state.attr) { \
	double value = (type)self.state.attr.property; \
	double min = (type)self.state.attr.rangeProperty.min; \
	double max = (type)self.state.attr.rangeProperty.max; \
	double normalizedValue = (value - min) / (max - min); \
	ret = MAX(MIN(normalizedValue, 1.0), 0.0); \
} \
return ret; \

#define SETTER_WITH_RANGE(attr,property,rangeProperty,variable,method) \
double min = self.state.attr.rangeProperty.min; \
double max = self.state.attr.rangeProperty.max; \
double normalizedValue = MAX(MIN(variable, 1.0), 0.0); \
double setterValue = min + (normalizedValue * (max - min)); \
SETTER(attr,property,setterValue,method) \

@interface IoTPlayer (ForwardMethods)

- (BOOL)getPlaylistSizeAndSnapshotIDWithCompletion:(void(^)(BOOL))completion
                                   completionQueue:(dispatch_queue_t)queue;

- (void)handlePlayStateUpdate:(BOOL)force;

@end

@interface IoTPlayer () <IoTAllPlayControllerObserver> {
    __weak id<IoTPlayerUpdates> _updatesDelegate;
}

@property (atomic, assign) BOOL dispatchedAfterInitialFetch;

@property (nonatomic, strong) IoTAllPlayController *allPlayController;
@property (nonatomic, strong) NSString *applicationName;
@property (nonatomic, strong) dispatch_queue_t stateSyncQueue;
@property (nonatomic, strong) dispatch_queue_t backgroundQueue;
@property (nonatomic, strong) IoTPlayerState *state;

@property (nonatomic, assign) NSTimeInterval timeStartedPlayback;

@property (nonatomic, weak) NSTimer *refreshTimer;

@end
