/*
 *  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
