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

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

@class IoTDeviceController;
@class IoTDevice;
@class IoTDeviceBatteryStatus;
@class IoTDevicePassword;
@class IoTPlayer;
@class IoTPlayerGroup;
@class IoTPlaylist;
@class IoTInputOutputSelector;
@class IoTBluetoothDevice;
@class IoTZigbeeDevice;
@class IoTVoiceUIClient;

NS_ASSUME_NONNULL_BEGIN

/**
 @brief Protocol that defines a series of methods sent by IoTClient to its delegate.
 */
@protocol IoTAppListenerProtocol <NSObject>

@optional

/**
 @brief Notification that a player group has been added.
 @param group the group that has been added.
 */
- (void)playerGroupAdded:(IoTPlayerGroup *)group;

/**
 @brief Notification that a player group has been removed.
 @param group the group that has been removed.
 */
- (void)playerGroupRemoved:(IoTPlayerGroup *)group;

/**
 @brief Notification that a player group has changed play state - for example when a track starts playing.
 @param group the group that has been affected.
 @param state the updated play state.
 */
- (void)playerGroup:(IoTPlayerGroup *)group didChangePlayState:(IoTPlayState)state;

/**
 @brief Notification that the membership of a group has been changed.
 @discussion This method may also be triggered by a change in member availability.
 @param group the group that has been affected.
 */
- (void)playerGroupDidChangePlayerList:(IoTPlayerGroup *)group;

/**
 @brief Notification that the source player of a group has been changed.
 @discussion This method may triggered when changing type of source. For example when going from Spotify streaming to a playlist.
 @param group the group that has been affected.
 */
- (void)playerGroupDidChangeSourcePlayer:(IoTPlayerGroup *)group;

/**
 @brief Notification that the name of a group has been changed.
 @param name the new group name.
 @param group the group that has been affected.
 */
- (void)playerGroup:(IoTPlayerGroup *)group didChangeName:(NSString *)name;

/**
 @brief Notification that the enabled playback controls for a group may have been changed.
 @param group the group that has been affected.
 */
- (void)playerGroupDidChangeEnabledControls:(IoTPlayerGroup *)group;

/**
 @brief Notification that the volume for a group may have been changed.
 @param group the group that has been affected.
 @param volume the new volume.
 */
- (void)playerGroup:(IoTPlayerGroup *)group didChangeVolume:(double)volume;

/**
 @brief Notification that the mute state for a group may have been changed.
 @param group the group that has been affected.
 @param muted the new mute state.
 */
- (void)playerGroup:(IoTPlayerGroup *)group didChangeMuteState:(BOOL)muted;

/**
 @brief Notification that a player group has been changed input source.
 @param group the group that has been affected.
 @param inputSelector the new input source.
 */
- (void)playerGroup:(IoTPlayerGroup *)group didChangeInputSelector:(IoTInputOutputSelector *)inputSelector;

/**
 @brief Notification that a playlist has been changed.
 @param playlist the playlist that has been affected.
 */
- (void)playlistDidChange:(IoTPlaylist *)playlist;

/**
 @brief Notification that a playlist loop mode has been changed.
 @param playlist the playlist that has been affected.
 @param loopMode the new loop mode state.
 */
- (void)playlist:(IoTPlaylist *)playlist didChangeLoopMode:(IoTLoopMode)loopMode;

/**
 @brief Notification that a playlist shuffle mode has been changed.
 @param playlist the playlist that has been affected.
 @param shuffleMode the new loop mode state.
 */
- (void)playlist:(IoTPlaylist *)playlist didChangeShuffleMode:(IoTShuffleMode)shuffleMode;

/**
 @brief Notification that a player name has been changed.
 @param player the player that has been affected.
 @param name the new player name.
 */
- (void)player:(IoTPlayer *)player didChangeDisplayName:(NSString *)name;

/**
 @brief Notification that a player volume has been changed.
 @param player the player that has been affected.
 @param volume the new player volume.
 */
- (void)player:(IoTPlayer *)player didChangeVolume:(double)volume;

/**
 @brief Notification that a player mute state has been changed.
 @param player the player that has been affected.
 @param muted the new player mute state.
 */
- (void)player:(IoTPlayer *)player didChangeMuteState:(BOOL)muted;

/**
 @brief Notification that a player has been changed input source.
 @param player the player that has been affected.
 @param inputSelector the new input source.
 */
- (void)player:(IoTPlayer *)player didChangeInputSelector:(IoTInputOutputSelector *)inputSelector;

/**
 @brief Notification that a player has been changed output sinks.
 @param player the player that has been affected.
 @param outputSelectors array of the output sinks.
 */
- (void)player:(IoTPlayer *)player didChangeOutputSelectors:(NSArray<IoTInputOutputSelector *> *)outputSelectors;

/**
 @brief Notification that a player audio config has changed such as bassboost, eq etc.
 @param player the player that has been affected.
 */
- (void)playerDidChangeAudioConfiguration:(IoTPlayer *)player;

/**
 @brief Notification that a device (IoTSys representation) has been added.
 @param device the device that has been added.
 */
- (void)deviceAdded:(IoTDevice *)device;

/**
 @brief Notification that a device (IoTSys representation) has been removed.
 @param device the device that has been removed.
 */
- (void)deviceRemoved:(IoTDevice *)device;

/*- (void)deviceDidStartUpdate:(IoTDevice *)device;
- (void)device:(IoTDevice *)device didChangeAutoUpdate:(NSString*)autoUpdating;
- (void)deviceUpdateAvailable:(IoTDevice *)device;
- (void)device:(IoTDevice *)device didChangeUpdateStatus:(IoTUpdateStatus)status;
- (void)device:(IoTDevice *)device didChangeUpdateProgress:(double)progress;
- (void)deviceRequiresPhysicalReboot:(IoTDevice *)device;
- (IoTDevicePassword *)devicePasswordRequested:(IoTDevice *)device;
 */

/**
 @brief Notification that a device (IoTSys representation) has changed name.
 @param device the device that has been affected.
 @param name the new name
 */
- (void)device:(IoTDevice *)device didChangeName:(NSString *)name;

/**
 @brief Notification that the Wifi access point info for a device (IoTSys representation) has changed.
 @param device the device that has been affected.
 */
- (void)deviceDidChangeAccessPointState:(IoTDevice *)device;

/**
 @brief Notification that the battery state info for a device (IoTSys representation) has changed.
 @param device the device that has been affected.
 */
- (void)deviceDidChangeBatteryState:(IoTDevice *)device;

/**
 @brief Notification that the ethernet state info for a device (IoTSys representation) has changed.
 @param device the device that has been affected.
 */
- (void)deviceDidChangeEthernetState:(IoTDevice *)device;

/**
 @brief Notification that the wifi state info for a device (IoTSys representation) has changed.
 @param device the device that has been affected.
 */
- (void)deviceDidChangeWiFiState:(IoTDevice *)device;

/**
 @brief Notification that a bluetooth adapter has discovered a new bluetooth device.
 @param device the speaker owning the bluetooth adapter.
 @param btDevice the newly discovered bluetooth device.
 */
- (void)device:(IoTDevice *)device btScanDidDiscoverBtDevice:(IoTBluetoothDevice *)btDevice;

/**
 @brief Notification that a bluetooth adapter has changed scan state.
 @param device the speaker owning the bluetooth adapter.
 @param scanning is the device now scanning.
 */
- (void)device:(IoTDevice *)device btScanStateDidChange:(BOOL)scanning;

/**
 @brief Notification that a bluetooth adapter has changed enabled/disabled/unknown state.
 @param device the speaker owning the bluetooth adapter.
 @param adapterState the new adapter state.
 */
- (void)device:(IoTDevice *)device btAdapterStateDidChange:(IoTBluetoothAdapterState)adapterState;

/**
 @brief Notification that a bluetooth adapter has changed discoverability state.
 @discussion When a bluetooth adapter is discoverable it is visible to other bluetooth devices.
 @param device the speaker owning the bluetooth adapter.
 @param discoverability the new discoverability state.
 */
- (void)device:(IoTDevice *)device btDiscoverabilityDidChange:(IoTDiscoverable)discoverability;

/**
 @brief Notification that a bluetooth adapter has connected a new bluetooth device.
 @param device the speaker owning the bluetooth adapter.
 @param btDevice the newly connected bluetooth device.
 */
- (void)device:(IoTDevice *)device btDidConnectDevice:(IoTBluetoothDevice *)btDevice;

/**
 @brief Notification that a bluetooth adapter has disconnected a bluetooth device.
 @param device the speaker owning the bluetooth adapter.
 @param btDevice the disconnected bluetooth device.
 */
- (void)device:(IoTDevice *)device btDidDisconnectDevice:(IoTBluetoothDevice *)btDevice;

/**
 @brief Notification that the devices paired with a bluetooth adapter has changed.
 @param device the speaker owning the bluetooth adapter.
 @param pairedDevices the updated array of paired bluetooth devices.
 */
- (void)device:(IoTDevice *)device btPairedDevicesDidChange:(NSArray<IoTBluetoothDevice *> *)pairedDevices;

/**
 @brief Notification that a Zigbee adapter has changed enabled/disabled/unknown state.
 @param device the speaker owning the Zigbee adapter.
 @param adapterState the new adapter state.
 */
- (void)device:(IoTDevice *)device zbAdapterStateDidChange:(IoTZigbeeAdapterState)adapterState;

/**
 @brief Notification that a Zigbee adapter has changed coordinator state.
 @param device the speaker owning the Zigbee adapter.
 @param coordinatorState the new coordinator state.
 */
- (void)device:(IoTDevice *)device zbCoordinatorStateDidChange:(IoTCoordinatorState)coordinatorState;

/**
 @brief Notification that the Zigbee devices that have joined the Zigbee network has changed.
 @param device the speaker owning the Zigbee adapter.
 @param joinedDevices the updated array of joined Zigbee devices.
 */
- (void)device:(IoTDevice *)device zbJoinedDevicesDidChange:(NSArray<IoTZigbeeDevice *> *)joinedDevices;

/**
 @brief Notification that the Zigbee adapter has changed joining state.
 @discussion When a Zigbee allows joining, new Zigbee devices are allowed to join the Zigbee network.
 @param device the speaker owning the Zigbee adapter.
 @param joiningAllowed is joining allowed.
 */
- (void)device:(IoTDevice *)device zbJoiningStateDidChange:(BOOL)joiningAllowed;

/**
 @brief Notification that there was a change in the status of the available voice UI clients. This includes chnages such as AVS onboarding being successful.
 @param device the speaker concerned.
 @param voiceUIClients the updated array of voice UI client info.
 */
- (void)device:(IoTDevice *)device voiceUIClientsDidChange:(NSArray<IoTVoiceUIClient *> *)voiceUIClients;

/**
 @brief Notification that there was a change in the global enabled state of Voice UI for the device. This affects all Voice UI clients.
 @param device the speaker concerned.
 @param enabled the new enabled state.
 */
- (void)device:(IoTDevice *)device voiceUIEnabledStateDidChange:(BOOL)enabled;

/**
 @brief Notification that there was a change in the default Voice UI client for the device.
 @discussion The default client is that used when, for example, tapping a button on the speaker to initiate Voice UI without using a specific wake word phrase.
 @param device the speaker concerned.
 @param voiceUIClient the new default Voice UI client.
 */
- (void)device:(IoTDevice *)device voiceUIDefaultClientDidChange:(nullable IoTVoiceUIClient *)voiceUIClient;

/**
 @brief Notification that the AVS onboarding process has started and user approval is expected.
 @discussion The AVS onboarding process requires the user to log in to their Amazon account using a URL provided by the device. The user should then enter an alphanumeric code also provided by the device. The device will then be authorised remotely without any further action by the user.
 @param device the speaker concerned.
 @param code the code the user will be expected to enter to authorize the speaker for AVS.
 @param url the url that should be presented to the user to allow the user to log in to their Amazon account and authorize onboarding.
 */
- (void)device:(IoTDevice *)device voiceUIDidProvideAVSAuthenticationCode:(NSString *)code url:(NSString *)url;

/**
 @brief Notification that the AVS onboarding process has errored.
 @param device the speaker concerned.
 @param didTimeout was the error due to a time out.
 @param reattempt how many times has onboarding been reattempted.
 */
- (void)device:(IoTDevice *)device voiceUIOnboardingDidErrorWithTimeout:(BOOL)didTimeout reattempt:(int)reattempt;

/**
 @brief Notification that the availability of a surround system channel changed.
 @param channel the channel that availability has changed.
 @param player the player (soundbar) that is hosting the surround sound system (NOT the speaker handling the channel).
 */
- (void)homeTheaterChannelAvailabilityChanged:(IoTHomeTheaterChannel)channel player:(IoTPlayer *)player;

/**
 @brief Notification that the volume of a surround system channel changed.
 @param channel the channel that volume has changed on.
 @param player the player (soundbar) that is hosting the surround sound system (NOT the speaker handling the channel).
 */
- (void)homeTheaterChannelVolumeChanged:(IoTHomeTheaterChannel)channel player:(IoTPlayer *)player;

@end

NS_ASSUME_NONNULL_END
