/*
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#import "ARDSettingsViewController.h"
#import "ARDSettingsModel.h"
#import "RTCVideoCodecInfo+HumanReadable.h"

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(int, ARDSettingsSections) {
ARDSettingsSectionAudioSettings = 0,
ARDSettingsSectionVideoResolution,
ARDSettingsSectionVideoCodec,
ARDSettingsSectionBitRate,
};

typedef NS_ENUM(int, ARDAudioSettingsOptions) {
ARDAudioSettingsAudioOnly = 0,
ARDAudioSettingsCreateAecDump,
ARDAudioSettingsUseManualAudioConfig,
};

@interface ARDSettingsViewController () <UITextFieldDelegate> {
ARDSettingsModel *_settingsModel;
}

@end

@implementation ARDSettingsViewController

- (instancetype)initWithStyle:(UITableViewStyle)style
settingsModel:(ARDSettingsModel *)settingsModel {
self = [super initWithStyle:style];
if (self) {
_settingsModel = settingsModel;
}
return self;
}

#pragma mark - View lifecycle

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Settings";
[self addDoneBarButton];
}

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}

#pragma mark - Data source

- (NSArray<NSString *> *)videoResolutionArray {
return [_settingsModel availableVideoResolutions];
}

- (NSArray<RTC_OBJC_TYPE(RTCVideoCodecInfo) *> *)videoCodecArray {
return [_settingsModel availableVideoCodecs];
}

#pragma mark -

- (void)addDoneBarButton {
UIBarButtonItem *barItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:@selector(dismissModally:)];
self.navigationItem.leftBarButtonItem = barItem;
}

#pragma mark - Dismissal of view controller

- (void)dismissModally:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 4;
}

- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
switch (section) {
case ARDSettingsSectionAudioSettings:
return 3;
case ARDSettingsSectionVideoResolution:
return self.videoResolutionArray.count;
case ARDSettingsSectionVideoCodec:
return self.videoCodecArray.count;
default:
return 1;
}
}

#pragma mark - Table view delegate helpers

- (void)removeAllAccessories:(UITableView *)tableView inSection:(int)section {
for (int i = 0; i < [tableView numberOfRowsInSection:section]; i++) {
NSIndexPath *rowPath = [NSIndexPath indexPathForRow:i inSection:section];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:rowPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
}

- (void)tableView:(UITableView *)tableView
updateListSelectionAtIndexPath:(NSIndexPath *)indexPath
inSection:(int)section {
[self removeAllAccessories:tableView inSection:section];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

#pragma mark - Table view delegate

- (nullable NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
switch (section) {
case ARDSettingsSectionAudioSettings:
return @"Audio";
case ARDSettingsSectionVideoResolution:
return @"Video resolution";
case ARDSettingsSectionVideoCodec:
return @"Video codec";
case ARDSettingsSectionBitRate:
return @"Maximum bitrate";
default:
return @"";
}
}

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case ARDSettingsSectionAudioSettings:
return [self audioSettingsTableViewCellForTableView:tableView
atIndexPath:indexPath];

case ARDSettingsSectionVideoResolution:
return [self videoResolutionTableViewCellForTableView:tableView
atIndexPath:indexPath];

case ARDSettingsSectionVideoCodec:
return [self videoCodecTableViewCellForTableView:tableView
atIndexPath:indexPath];

case ARDSettingsSectionBitRate:
return [self bitrateTableViewCellForTableView:tableView
atIndexPath:indexPath];

default:
return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"identifier"];
}
}

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case ARDSettingsSectionVideoResolution:
[self tableView:tableView disSelectVideoResolutionAtIndex:indexPath];
break;

case ARDSettingsSectionVideoCodec:
[self tableView:tableView didSelectVideoCodecCellAtIndexPath:indexPath];
break;
}
}

#pragma mark - Table view delegate(Video Resolution)

- (UITableViewCell *)
videoResolutionTableViewCellForTableView:(UITableView *)tableView
atIndexPath:(NSIndexPath *)indexPath {
NSString *dequeueIdentifier = @"ARDSettingsVideoResolutionViewCellIdentifier";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:dequeueIdentifier];
}
NSString *resolution = self.videoResolutionArray[indexPath.row];
cell.textLabel.text = resolution;
if ([resolution
isEqualToString:[_settingsModel
currentVideoResolutionSettingFromStore]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}

return cell;
}

- (void)tableView:(UITableView *)tableView
disSelectVideoResolutionAtIndex:(NSIndexPath *)indexPath {
[self tableView:tableView
updateListSelectionAtIndexPath:indexPath
inSection:ARDSettingsSectionVideoResolution];

NSString *videoResolution = self.videoResolutionArray[indexPath.row];
[_settingsModel storeVideoResolutionSetting:videoResolution];
}

#pragma mark - Table view delegate(Video Codec)

- (UITableViewCell *)
videoCodecTableViewCellForTableView:(UITableView *)tableView
atIndexPath:(NSIndexPath *)indexPath {
NSString *dequeueIdentifier = @"ARDSettingsVideoCodecCellIdentifier";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:dequeueIdentifier];
}
RTC_OBJC_TYPE(RTCVideoCodecInfo) *codec = self.videoCodecArray[indexPath.row];
cell.textLabel.text = [codec humanReadableDescription];
if ([codec isEqualToCodecInfo:[_settingsModel
currentVideoCodecSettingFromStore]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}

return cell;
}

- (void)tableView:(UITableView *)tableView
didSelectVideoCodecCellAtIndexPath:(NSIndexPath *)indexPath {
[self tableView:tableView
updateListSelectionAtIndexPath:indexPath
inSection:ARDSettingsSectionVideoCodec];

RTC_OBJC_TYPE(RTCVideoCodecInfo) *videoCodec =
self.videoCodecArray[indexPath.row];
[_settingsModel storeVideoCodecSetting:videoCodec];
}

#pragma mark - Table view delegate(Bitrate)

- (UITableViewCell *)bitrateTableViewCellForTableView:(UITableView *)tableView
atIndexPath:(NSIndexPath *)indexPath {
NSString *dequeueIdentifier = @"ARDSettingsBitrateCellIdentifier";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:dequeueIdentifier];

UITextField *textField = [[UITextField alloc]
initWithFrame:CGRectMake(10,
0,
cell.bounds.size.width - 20,
cell.bounds.size.height)];
NSString *currentMaxBitrate =
[_settingsModel currentMaxBitrateSettingFromStore].stringValue;
textField.text = currentMaxBitrate;
textField.placeholder = @"Enter max bit rate (kbps)";
textField.keyboardType = UIKeyboardTypeNumberPad;
textField.delegate = self;

// Numerical keyboards have no return button, we need to add one manually.
UIToolbar *numberToolbar = [[UIToolbar alloc]
initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 50)];
numberToolbar.items = @[
[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil],
[[UIBarButtonItem alloc]
initWithTitle:@"Apply"
style:UIBarButtonItemStyleDone
target:self
action:@selector(numberTextFieldDidEndEditing:)]
];
[numberToolbar sizeToFit];

textField.inputAccessoryView = numberToolbar;
[cell addSubview:textField];
}
return cell;
}

- (void)numberTextFieldDidEndEditing:(id)sender {
[self.view endEditing:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
NSNumber *bitrateNumber = nil;

if (textField.text.length != 0) {
bitrateNumber = [NSNumber numberWithInteger:textField.text.intValue];
}

[_settingsModel storeMaxBitrateSetting:bitrateNumber];
}

#pragma mark - Table view delegate(Audio settings)

- (UITableViewCell *)
audioSettingsTableViewCellForTableView:(UITableView *)tableView
atIndexPath:(NSIndexPath *)indexPath {
NSString *dequeueIdentifier = @"ARDSettingsAudioSettingsCellIdentifier";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:dequeueIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:dequeueIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
switchView.tag = indexPath.row;
[switchView addTarget:self
action:@selector(audioSettingSwitchChanged:)
forControlEvents:UIControlEventValueChanged];
cell.accessoryView = switchView;
}

cell.textLabel.text = [self labelForAudioSettingAtIndexPathRow:indexPath.row];
UISwitch *switchView = (UISwitch *)cell.accessoryView;
switchView.on = [self valueForAudioSettingAtIndexPathRow:indexPath.row];

return cell;
}

- (NSString *)labelForAudioSettingAtIndexPathRow:(NSInteger)setting {
switch (setting) {
case ARDAudioSettingsAudioOnly:
return @"Audio only";
case ARDAudioSettingsCreateAecDump:
return @"Create AecDump";
case ARDAudioSettingsUseManualAudioConfig:
return @"Use manual audio config";
default:
return @"";
}
}

- (BOOL)valueForAudioSettingAtIndexPathRow:(NSInteger)setting {
switch (setting) {
case ARDAudioSettingsAudioOnly:
return [_settingsModel currentAudioOnlySettingFromStore];
case ARDAudioSettingsCreateAecDump:
return [_settingsModel currentCreateAecDumpSettingFromStore];
case ARDAudioSettingsUseManualAudioConfig:
return [_settingsModel currentUseManualAudioConfigSettingFromStore];
default:
return NO;
}
}

- (void)audioSettingSwitchChanged:(UISwitch *)sender {
switch (sender.tag) {
case ARDAudioSettingsAudioOnly: {
[_settingsModel storeAudioOnlySetting:sender.isOn];
break;
}
case ARDAudioSettingsCreateAecDump: {
[_settingsModel storeCreateAecDumpSetting:sender.isOn];
break;
}
case ARDAudioSettingsUseManualAudioConfig: {
[_settingsModel storeUseManualAudioConfigSetting:sender.isOn];
break;
}
default:
break;
}
}

@end
NS_ASSUME_NONNULL_END