/*
 *  Copyright 2015 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 "ARDMainView.h"

#import "UIImage+ARDUtilities.h"

static CGFloat const kRoomTextFieldHeight = 40;
static CGFloat const kRoomTextFieldMargin = 8;
static CGFloat const kCallControlMargin = 8;

// Helper view that contains a text field and a clear button.
@interface ARDRoomTextField : UIView <UITextFieldDelegate>
@property(nonatomic, readonly) NSString *roomText;
@end

@implementation ARDRoomTextField {
  UITextField *_roomText;
}

- (instancetype)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
    _roomText = [[UITextField alloc] initWithFrame:CGRectZero];
    _roomText.borderStyle = UITextBorderStyleNone;
    _roomText.font = [UIFont systemFontOfSize:12];
    _roomText.placeholder = @"Room name";
    _roomText.autocorrectionType = UITextAutocorrectionTypeNo;
    _roomText.autocapitalizationType = UITextAutocapitalizationTypeNone;
    _roomText.clearButtonMode = UITextFieldViewModeAlways;
    _roomText.delegate = self;
    [self addSubview:_roomText];

    // Give rounded corners and a light gray border.
    self.layer.borderWidth = 1;
    self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
    self.layer.cornerRadius = 2;
  }
  return self;
}

- (void)layoutSubviews {
  _roomText.frame =
      CGRectMake(kRoomTextFieldMargin,
                 0,
                 CGRectGetWidth(self.bounds) - kRoomTextFieldMargin,
                 kRoomTextFieldHeight);
}

- (CGSize)sizeThatFits:(CGSize)size {
  size.height = kRoomTextFieldHeight;
  return size;
}

- (NSString *)roomText {
  return _roomText.text;
}

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
  // There is no other control that can take focus, so manually resign focus
  // when return (Join) is pressed to trigger `textFieldDidEndEditing`.
  [textField resignFirstResponder];
  return YES;
}

@end

@implementation ARDMainView {
  ARDRoomTextField *_roomText;
  UIButton *_startRegularCallButton;
  UIButton *_startLoopbackCallButton;
  UIButton *_audioLoopButton;
}

@synthesize delegate = _delegate;
@synthesize isAudioLoopPlaying = _isAudioLoopPlaying;

- (instancetype)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
    _roomText = [[ARDRoomTextField alloc] initWithFrame:CGRectZero];
    [self addSubview:_roomText];

    UIFont *controlFont = [UIFont boldSystemFontOfSize:18.0];
    UIColor *controlFontColor = [UIColor whiteColor];

    _startRegularCallButton = [UIButton buttonWithType:UIButtonTypeSystem];
    _startRegularCallButton.titleLabel.font = controlFont;
    [_startRegularCallButton setTitleColor:controlFontColor
                                  forState:UIControlStateNormal];
    _startRegularCallButton.backgroundColor =
        [UIColor colorWithRed:66.0 / 255.0
                        green:200.0 / 255.0
                         blue:90.0 / 255.0
                        alpha:1.0];
    [_startRegularCallButton setTitle:@"Call room"
                             forState:UIControlStateNormal];
    [_startRegularCallButton addTarget:self
                                action:@selector(onStartRegularCall:)
                      forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:_startRegularCallButton];

    _startLoopbackCallButton = [UIButton buttonWithType:UIButtonTypeSystem];
    _startLoopbackCallButton.titleLabel.font = controlFont;
    [_startLoopbackCallButton setTitleColor:controlFontColor
                                   forState:UIControlStateNormal];
    _startLoopbackCallButton.backgroundColor =
        [UIColor colorWithRed:0.0 green:122.0 / 255.0 blue:1.0 alpha:1.0];
    [_startLoopbackCallButton setTitle:@"Loopback call"
                              forState:UIControlStateNormal];
    [_startLoopbackCallButton addTarget:self
                                 action:@selector(onStartLoopbackCall:)
                       forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:_startLoopbackCallButton];

    // Used to test what happens to sounds when calls are in progress.
    _audioLoopButton = [UIButton buttonWithType:UIButtonTypeSystem];
    _audioLoopButton.titleLabel.font = controlFont;
    [_audioLoopButton setTitleColor:controlFontColor
                           forState:UIControlStateNormal];
    _audioLoopButton.backgroundColor = [UIColor colorWithRed:1.0
                                                       green:149.0 / 255.0
                                                        blue:0.0
                                                       alpha:1.0];
    [self updateAudioLoopButton];
    [_audioLoopButton addTarget:self
                         action:@selector(onToggleAudioLoop:)
               forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:_audioLoopButton];

    self.backgroundColor = [UIColor whiteColor];
  }
  return self;
}

- (void)setIsAudioLoopPlaying:(BOOL)isAudioLoopPlaying {
  if (_isAudioLoopPlaying == isAudioLoopPlaying) {
    return;
  }
  _isAudioLoopPlaying = isAudioLoopPlaying;
  [self updateAudioLoopButton];
}

- (void)layoutSubviews {
  CGRect bounds = self.bounds;
  CGFloat roomTextWidth = bounds.size.width - 2 * kRoomTextFieldMargin;
  CGFloat roomTextHeight = [_roomText sizeThatFits:bounds.size].height;
  _roomText.frame = CGRectMake(kRoomTextFieldMargin,
                               kRoomTextFieldMargin,
                               roomTextWidth,
                               roomTextHeight);

  CGFloat buttonHeight =
      (CGRectGetMaxY(self.bounds) - CGRectGetMaxY(_roomText.frame) -
       kCallControlMargin * 4) /
      3;

  CGFloat regularCallFrameTop =
      CGRectGetMaxY(_roomText.frame) + kCallControlMargin;
  CGRect regularCallFrame =
      CGRectMake(kCallControlMargin,
                 regularCallFrameTop,
                 bounds.size.width - 2 * kCallControlMargin,
                 buttonHeight);

  CGFloat loopbackCallFrameTop =
      CGRectGetMaxY(regularCallFrame) + kCallControlMargin;
  CGRect loopbackCallFrame =
      CGRectMake(kCallControlMargin,
                 loopbackCallFrameTop,
                 bounds.size.width - 2 * kCallControlMargin,
                 buttonHeight);

  CGFloat audioLoopTop = CGRectGetMaxY(loopbackCallFrame) + kCallControlMargin;
  CGRect audioLoopFrame = CGRectMake(kCallControlMargin,
                                     audioLoopTop,
                                     bounds.size.width - 2 * kCallControlMargin,
                                     buttonHeight);

  _startRegularCallButton.frame = regularCallFrame;
  _startLoopbackCallButton.frame = loopbackCallFrame;
  _audioLoopButton.frame = audioLoopFrame;
}

#pragma mark - Private

- (void)updateAudioLoopButton {
  if (_isAudioLoopPlaying) {
    [_audioLoopButton setTitle:@"Stop sound" forState:UIControlStateNormal];
  } else {
    [_audioLoopButton setTitle:@"Play sound" forState:UIControlStateNormal];
  }
}

- (void)onToggleAudioLoop:(id)sender {
  [_delegate mainViewDidToggleAudioLoop:self];
}

- (void)onStartRegularCall:(id)sender {
  [_delegate mainView:self didInputRoom:_roomText.roomText isLoopback:NO];
}

- (void)onStartLoopbackCall:(id)sender {
  [_delegate mainView:self didInputRoom:_roomText.roomText isLoopback:YES];
}

@end
