// Copyright 2017-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "MDCTextInputControllerBase.h"
#import "private/MDCTextInputControllerBase+Subclassing.h"

#import "MDCPalettes.h"
#import "MDCMultilineTextField.h"
#import "MDCTextField.h"
#import "MDCTextInput.h"
#import "MDCTextInputBorderView.h"
#import "MDCTextInputCharacterCounter.h"
#import "MDCTextInputController.h"
#import "MDCTextInputControllerFloatingPlaceholder.h"
#import "MDCTextInputUnderlineView.h"

#import "MDCFontTextStyle.h"
#import "UIFont+MaterialSimpleEquality.h"
#import "UIFont+MaterialTypography.h"
#import "MDCMath.h"

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"

#pragma mark - Constants

static const CGFloat MDCTextInputControllerBaseDefaultBorderRadius = 4;
static const CGFloat MDCTextInputControllerBaseDefaultFloatingPlaceholderScaleDefault =
    (CGFloat)0.75;
static const CGFloat MDCTextInputControllerBaseDefaultHintTextOpacity = (CGFloat)0.54;
static const CGFloat MDCTextInputControllerBaseDefaultPadding = 8;

static const NSTimeInterval
    MDCTextInputControllerBaseDefaultFloatingPlaceholderDownAnimationDuration = (CGFloat)0.266666;
static const NSTimeInterval
    MDCTextInputControllerBaseDefaultFloatingPlaceholderUpAnimationDuration = (CGFloat)0.3;
static const NSTimeInterval kDefaultErrorAnnouncementDelay = (CGFloat)0.050;

static inline UIColor *MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault(void) {
  return [UIColor colorWithWhite:0 alpha:MDCTextInputControllerBaseDefaultHintTextOpacity];
}

static inline UIColor *MDCTextInputControllerBaseDefaultActiveColorDefault(void) {
  return [MDCPalette bluePalette].accent700;
}

static inline UIColor *MDCTextInputControllerBaseDefaultNormalUnderlineColorDefault(void) {
  return [UIColor lightGrayColor];
}

static inline UIColor *MDCTextInputControllerBaseDefaultTextErrorColorDefault(void) {
  return [MDCPalette redPalette].accent400;
}

#pragma mark - Class Properties

static BOOL _floatingEnabledDefault = YES;

static CGFloat _floatingPlaceholderScaleDefault =
    MDCTextInputControllerBaseDefaultFloatingPlaceholderScaleDefault;
static CGFloat _underlineHeightActiveDefault = 0;
static CGFloat _underlineHeightNormalDefault = 0;

static UIColor *_activeColorDefault;
static UIColor *_borderFillColorDefault;
static UIColor *_disabledColorDefault;
static UIColor *_errorColorDefault;
static UIColor *_floatingPlaceholderActiveColorDefault;
static UIColor *_floatingPlaceholderNormalColorDefault;
static UIColor *_inlinePlaceholderColorDefault;
static UIColor *_leadingUnderlineLabelTextColorDefault;
static UIColor *_normalColorDefault;
static UIColor *_trailingUnderlineLabelTextColorDefault;

static UIFont *_inlinePlaceholderFontDefault;
static UIFont *_leadingUnderlineLabelFontDefault;
static UIFont *_textInputFontDefault;
static UIColor *_textInputClearButtonTintColorDefault;
static UIFont *_trailingUnderlineLabelFontDefault;

static UIRectCorner _roundedCornersDefault = 0;

static UITextFieldViewMode _underlineViewModeDefault = UITextFieldViewModeWhileEditing;

@interface MDCTextInputControllerBase () {
  BOOL _mdc_adjustsFontForContentSizeCategory;

  MDCTextInputAllCharactersCounter *_characterCounter;

  NSNumber *_floatingPlaceholderScale;

  UIColor *_activeColor;
  UIColor *_borderFillColor;
  UIColor *_borderStrokeColor;
  UIColor *_disabledColor;
  UIColor *_errorColor;
  UIColor *_floatingPlaceholderActiveColor;
  UIColor *_floatingPlaceholderNormalColor;
  UIColor *_floatingPlaceholderErrorActiveColor;
  UIColor *_inlinePlaceholderColor;
  UIColor *_leadingUnderlineLabelTextColor;
  UIColor *_normalColor;
  UIColor *_trailingUnderlineLabelTextColor;

  UIFont *_inlinePlaceholderFont;
  UIFont *_leadingUnderlineLabelFont;
  UIFont *_textInputFont;
  UIColor *_textInputClearButtonTintColor;
  UIFont *_trailingUnderlineLabelFont;

  UIRectCorner _roundedCorners;
}

@property(nonatomic, strong) MDCTextInputAllCharactersCounter *internalCharacterCounter;

@property(nonatomic, copy) NSArray<NSLayoutConstraint *> *placeholderAnimationConstraints;

@property(nonatomic, strong) NSLayoutConstraint *placeholderAnimationConstraintLeading;
@property(nonatomic, strong) NSLayoutConstraint *placeholderAnimationConstraintTop;
@property(nonatomic, strong) NSLayoutConstraint *placeholderAnimationConstraintTrailing;

@property(nonatomic, copy) NSString *errorAccessibilityValue;
@property(nonatomic, copy, readwrite) NSString *errorText;
@property(nonatomic, copy) NSString *helperAccessibilityLabel;
@property(nonatomic, copy) NSString *previousLeadingText;

@end

@implementation MDCTextInputControllerBase

@synthesize characterCountMax = _characterCountMax;
@synthesize characterCountViewMode = _characterCountViewMode;
@synthesize floatingEnabled = _floatingEnabled;
@synthesize roundedCorners = _roundedCorners;
@synthesize textInput = _textInput;
@synthesize underlineHeightActive = _underlineHeightActive;
@synthesize underlineHeightNormal = _underlineHeightNormal;
@synthesize underlineViewMode = _underlineViewMode;

// TODO: (larche): Support in-line auto complete.

- (instancetype)init {
  self = [super init];
  if (self) {
    if ([self isMemberOfClass:[MDCTextInputControllerBase class]]) {
      NSLog(@"NOTE: MDCTextInputControllerBase is a base class meant to be subclassed.\nFor more"
             "information, see the README.md file");
    }
    [self commonMDCTextInputControllerBaseInitialization];
  }

  return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [super init];
  if (self) {
    [self commonMDCTextInputControllerBaseInitialization];

    // This should happen last because it relies on the state of a ton of properties.
    [self setupInput];
  }
  return self;
}

- (instancetype)initWithTextInput:(UIView<MDCTextInput> *)textInput {
  self = [self init];
  if (self) {
    _textInput = textInput;

    // This should happen last because it relies on the state of a ton of properties.
    [self setupInput];
  }

  return self;
}

- (instancetype)copyWithZone:(__unused NSZone *)zone {
  MDCTextInputControllerBase *copy = [[[self class] alloc] init];

  copy.activeColor = self.activeColor;
  copy.borderFillColor = self.borderFillColor;
  copy.borderRadius = self.borderRadius;
  copy.borderStrokeColor = self.borderStrokeColor;
  copy.characterCounter = self.characterCounter;  // Just a pointer value copy
  copy.characterCountViewMode = self.characterCountViewMode;
  copy.characterCountMax = self.characterCountMax;
  copy.roundedCorners = self.roundedCorners;
  copy.disabledColor = self.disabledColor;
  copy.errorAccessibilityValue = [self.errorAccessibilityValue copy];
  copy.errorColor = self.errorColor;
  copy.errorText = [self.errorText copy];
  copy.expandsOnOverflow = self.expandsOnOverflow;
  copy.floatingEnabled = self.isFloatingEnabled;
  copy.floatingPlaceholderActiveColor = self.floatingPlaceholderActiveColor;
  copy.floatingPlaceholderNormalColor = self.floatingPlaceholderNormalColor;
  copy.floatingPlaceholderErrorActiveColor = self.floatingPlaceholderErrorActiveColor;
  copy.floatingPlaceholderScale = self.floatingPlaceholderScale;
  copy.helperText = [self.helperText copy];
  copy.inlinePlaceholderColor = self.inlinePlaceholderColor;
  copy.inlinePlaceholderFont = self.inlinePlaceholderFont;
  copy.leadingUnderlineLabelFont = self.leadingUnderlineLabelFont;
  copy.leadingUnderlineLabelTextColor = self.leadingUnderlineLabelTextColor;
  copy.minimumLines = self.minimumLines;
  copy.normalColor = self.normalColor;
  copy.previousLeadingText = [self.previousLeadingText copy];
  copy.textInput = self.textInput;  // Just a pointer value copy
  copy.trailingUnderlineLabelFont = self.trailingUnderlineLabelFont;
  copy.trailingUnderlineLabelTextColor = self.trailingUnderlineLabelTextColor;
  copy.underlineHeightActive = self.underlineHeightActive;
  copy.underlineHeightNormal = self.underlineHeightNormal;
  copy.underlineViewMode = self.underlineViewMode;

  return copy;
}

- (void)dealloc {
  [self unsubscribeFromNotifications];
}

- (void)commonMDCTextInputControllerBaseInitialization {
  _roundedCorners = [self class].roundedCornersDefault;
  _borderRadius = MDCTextInputControllerBaseDefaultBorderRadius;
  _characterCountViewMode = UITextFieldViewModeAlways;
  _disabledColor = [self class].disabledColorDefault;
  _expandsOnOverflow = YES;
  _floatingEnabled = [self class].isFloatingEnabledDefault;
  _internalCharacterCounter = [[MDCTextInputAllCharactersCounter alloc] init];
  _minimumLines = 1;
  _underlineHeightActive = [self class].underlineHeightActiveDefault;
  _underlineHeightNormal = [self class].underlineHeightNormalDefault;
  _underlineViewMode = [self class].underlineViewModeDefault;
  _textInput.hidesPlaceholderOnInput = NO;

  [self forceUpdatePlaceholderY];
}

- (void)setupInput {
  if (!_textInput) {
    return;
  }

  // This controller will handle Dynamic Type and all fonts for the text input
  _mdc_adjustsFontForContentSizeCategory = _textInput.mdc_adjustsFontForContentSizeCategory || NO;
  _textInput.underline.disabledColor = self.disabledColor;
  _textInput.mdc_adjustsFontForContentSizeCategory = NO;
  _textInput.positioningDelegate = self;
  _textInput.hidesPlaceholderOnInput = !self.isFloatingEnabled;
  _textInput.textInsetsMode = [self textInsetModeDefault];

  if ([_textInput conformsToProtocol:@protocol(MDCMultilineTextInput)] &&
      [_textInput respondsToSelector:@selector(setMinimumLines:)]) {
    ((id<MDCMultilineTextInput>)_textInput).minimumLines = self.minimumLines;
  }

  if ([_textInput conformsToProtocol:@protocol(MDCMultilineTextInput)] &&
      [_textInput respondsToSelector:@selector(setExpandsOnOverflow:)]) {
    ((id<MDCMultilineTextInput>)_textInput).expandsOnOverflow = self.expandsOnOverflow;
  }

  [self subscribeForNotifications];
  _textInput.underline.color = [self class].normalColorDefault;
  _textInput.clearButton.tintColor = self.textInputClearButtonTintColor;
  [self forceUpdatePlaceholderY];
}

- (MDCTextInputTextInsetsMode)textInsetModeDefault {
  return MDCTextInputTextInsetsModeAlways;
}

- (void)subscribeForNotifications {
  if (!_textInput) {
    return;
  }
  NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];

  [defaultCenter addObserver:self
                    selector:@selector(textInputDidToggleEnabled:)
                        name:MDCTextInputDidToggleEnabledNotification
                      object:_textInput];

  if ([_textInput isKindOfClass:[UITextField class]]) {
    [defaultCenter addObserver:self
                      selector:@selector(textInputDidBeginEditing:)
                          name:UITextFieldTextDidBeginEditingNotification
                        object:_textInput];
    [defaultCenter addObserver:self
                      selector:@selector(textInputDidChange:)
                          name:UITextFieldTextDidChangeNotification
                        object:_textInput];
    [defaultCenter addObserver:self
                      selector:@selector(textInputDidEndEditing:)
                          name:UITextFieldTextDidEndEditingNotification
                        object:_textInput];
  }

  if ([_textInput isKindOfClass:[MDCMultilineTextField class]]) {
    MDCMultilineTextField *textField = (MDCMultilineTextField *)_textInput;
    [defaultCenter addObserver:self
                      selector:@selector(textInputDidBeginEditing:)
                          name:UITextViewTextDidBeginEditingNotification
                        object:textField.textView];
    [defaultCenter addObserver:self
                      selector:@selector(textInputDidChange:)
                          name:UITextViewTextDidChangeNotification
                        object:textField.textView];
    [defaultCenter addObserver:self
                      selector:@selector(textInputDidEndEditing:)
                          name:UITextViewTextDidEndEditingNotification
                        object:textField.textView];
  }

  [defaultCenter addObserver:self
                    selector:@selector(textInputDidChange:)
                        name:MDCTextFieldTextDidSetTextNotification
                      object:_textInput];
}

- (void)unsubscribeFromNotifications {
  NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  [defaultCenter removeObserver:self];
}

#pragma mark - Border Customization

- (void)updateBorder {
  self.textInput.borderView.borderFillColor = self.borderFillColor;
  self.textInput.borderView.borderStrokeColor = self.borderStrokeColor;
  self.textInput.borderPath = [self defaultBorderPath];
}

- (UIBezierPath *)defaultBorderPath {
  CGRect borderBound = self.textInput.bounds;
  borderBound.size.height = CGRectGetMaxY(self.textInput.underline.frame);
  return [UIBezierPath bezierPathWithRoundedRect:borderBound
                               byRoundingCorners:self.roundedCorners
                                     cornerRadii:CGSizeMake(self.borderRadius, self.borderRadius)];
}

- (void)setBorderRadius:(CGFloat)borderRadius {
  _borderRadius = borderRadius;
  [self updateLayout];
}

#pragma mark - Character Max Implementation

- (NSUInteger)characterCount {
  return [self.characterCounter characterCountForTextInput:self.textInput];
}

- (id<MDCTextInputCharacterCounter>)characterCounter {
  if (!_characterCounter) {
    _characterCounter = self.internalCharacterCounter;
  }
  return _characterCounter;
}

- (void)setCharacterCounter:(id<MDCTextInputCharacterCounter>)characterCounter {
  if (_characterCounter != characterCounter) {
    _characterCounter = characterCounter;
    [self updateLayout];
  }
}

- (void)setCharacterCountMax:(NSUInteger)characterCountMax {
  if (_characterCountMax != characterCountMax) {
    _characterCountMax = characterCountMax;
    [self updateLayout];
  }
}

#pragma mark - Cursor Customization

- (void)updateCursor {
  self.textInput.cursorColor = (self.isDisplayingErrorText || self.isDisplayingCharacterCountError)
                                   ? self.errorColor
                                   : self.activeColor;
}

#pragma mark - Leading Label Customization

- (void)updateLeadingUnderlineLabel {
  UIFont *font = self.leadingUnderlineLabelFont;
  if (self.mdc_adjustsFontForContentSizeCategory) {
    // TODO: (#4331) This needs to be converted to the new text scheme.
    font = [font mdc_fontSizedForMaterialTextStyle:MDCFontTextStyleCaption
                              scaledForDynamicType:_mdc_adjustsFontForContentSizeCategory];
  }
  self.textInput.leadingUnderlineLabel.font = font;

  self.textInput.leadingUnderlineLabel.textColor =
      (self.isDisplayingErrorText || self.isDisplayingCharacterCountError)
          ? self.errorColor
          : self.leadingUnderlineLabelTextColor;
}

#pragma mark - TextInput Customization

- (void)updateTextInput {
  UIFont *font = self.textInputFont;
  if (self.mdc_adjustsFontForContentSizeCategory) {
    font = [font mdc_fontSizedForMaterialTextStyle:MDCFontTextStyleBody1
                              scaledForDynamicType:_mdc_adjustsFontForContentSizeCategory];
    // TODO: (#4331) This needs to be converted to the new text scheme.
  }
  self.textInput.font = font;
}

#pragma mark - Placeholder Customization

// This updates the placeholder's visual characteristics and not its layout. See the section
// "Placeholder Floating" for methods that update the layout.
- (void)updatePlaceholder {
  UIFont *placeHolderFont = self.inlinePlaceholderFont;
  if (self.mdc_adjustsFontForContentSizeCategory) {
    // TODO: (#4331) This needs to be converted to the new text scheme.
    placeHolderFont =
        [placeHolderFont mdc_fontSizedForMaterialTextStyle:MDCFontTextStyleBody1
                                      scaledForDynamicType:_mdc_adjustsFontForContentSizeCategory];
  }

  // Aside from not wanting to kick off extra work for setting a font that hasn't changed, we use
  // this custom equality check to prevent an edge case that caused a 1 pixel change in width even
  // when the important parts of the new font were the same as the existing font.
  if (![self.textInput.placeholderLabel.font mdc_isSimplyEqual:placeHolderFont]) {
    self.textInput.placeholderLabel.font = placeHolderFont;
  }

  UIColor *placeholderColor;
  if ([self isPlaceholderUp]) {
    UIColor *errorColor = self.textInput.isEditing
                              ? (self.floatingPlaceholderErrorActiveColor ?: self.errorColor)
                              : self.errorColor;
    UIColor *nonErrorColor = self.textInput.isEditing ? self.floatingPlaceholderActiveColor
                                                      : self.floatingPlaceholderNormalColor;
    placeholderColor = (self.isDisplayingCharacterCountError || self.isDisplayingErrorText)
                           ? errorColor
                           : nonErrorColor;
  } else {
    placeholderColor = self.inlinePlaceholderColor;
  }
  if (!self.textInput.isEnabled) {
    placeholderColor = self.disabledColor;
  }
  self.textInput.placeholderLabel.textColor = placeholderColor;
}

#pragma mark - Placeholder Floating

// 'Up' in these methods always means the placeholder is floating; it's .y is smaller and it's not
// 'inline' with the text input. The placeholder also doesn't disappear when you type since it's
// functioning as a title label when 'up'.

- (void)movePlaceholderToUp:(BOOL)isToUp {
  if ([self isPlaceholderUp] == isToUp) {
    return;
  }

  CGFloat scaleFactor = (CGFloat)self.floatingPlaceholderScale.floatValue;
  CGAffineTransform floatingPlaceholderScaleTransform =
      CGAffineTransformMakeScale(scaleFactor, scaleFactor);

  // The animation is accomplished pretty simply. A constraint for vertical and a constraint for
  // horizontal offset, both with a required priority (1000), are acivated on the placeholderLabel.
  // A simple scale transform is also applied. Then it's animated through the UIView animation API
  // (layoutIfNeeded). If in reverse (isToUp == NO), these things are just removed / deactivated.

  CGAffineTransform scaleTransform =
      isToUp ? floatingPlaceholderScaleTransform : CGAffineTransformIdentity;

  // We do this beforehand to flush the layout engine.
  [self.textInput layoutIfNeeded];
  [self updatePlaceholderAnimationConstraints:isToUp];
  [UIView animateWithDuration:[CATransaction animationDuration]
      animations:^{
        self.textInput.placeholderLabel.transform = scaleTransform;
        [self updatePlaceholder];
        [self updateBorder];
        [self.textInput layoutIfNeeded];
      }
      completion:^(__unused BOOL finished) {
        if (!isToUp) {
          [self cleanupPlaceholderAnimationConstraints];
        }
      }];
}

- (BOOL)isPlaceholderUp {
  return self.placeholderAnimationConstraints.count > 0 &&
         !CGAffineTransformEqualToTransform(self.textInput.placeholderLabel.transform,
                                            CGAffineTransformIdentity);
}

// Sometimes we set up the animation constraints for floating up before we have a width for the text
// field. Since there is math that needs to compensate for the transform in relation to the width,
// we update the constants on the constraints.
//
// Note: this method is not called inside updateLayout.
- (void)updatePlaceholderAnimationConstraints:(BOOL)isToUp {
  if (isToUp) {
    UIOffset offset = [self floatingPlaceholderOffset];

    // Remember, the insets are always in LTR. It's automatically flipped when used in RTL.
    // See MDCTextInputController.h.
    UIEdgeInsets insets = self.textInput.textInsets;

    CGFloat leadingConstant = [self floatingPlaceholderAnimationConstraintLeadingConstant:insets
                                                                                   offset:offset];
    if (!self.placeholderAnimationConstraintLeading) {
      self.placeholderAnimationConstraintLeading =
          [NSLayoutConstraint constraintWithItem:self.textInput.placeholderLabel
                                       attribute:NSLayoutAttributeLeading
                                       relatedBy:NSLayoutRelationEqual
                                          toItem:self.textInput
                                       attribute:NSLayoutAttributeLeading
                                      multiplier:1
                                        constant:leadingConstant];
    }
    self.placeholderAnimationConstraintLeading.constant = leadingConstant;

    if (!self.placeholderAnimationConstraintTop) {
      self.placeholderAnimationConstraintTop =
          [NSLayoutConstraint constraintWithItem:self.textInput.placeholderLabel
                                       attribute:NSLayoutAttributeTop
                                       relatedBy:NSLayoutRelationEqual
                                          toItem:self.textInput
                                       attribute:NSLayoutAttributeTop
                                      multiplier:1
                                        constant:offset.vertical];
    }
    self.placeholderAnimationConstraintTop.constant = offset.vertical;

    CGFloat trailingConstant = [self floatingPlaceholderAnimationConstraintTrailingConstant:insets
                                                                                     offset:offset];
    if (!self.placeholderAnimationConstraintTrailing) {
      self.placeholderAnimationConstraintTrailing =
          [NSLayoutConstraint constraintWithItem:self.textInput.placeholderLabel
                                       attribute:NSLayoutAttributeTrailing
                                       relatedBy:NSLayoutRelationEqual
                                          toItem:self.textInput
                                       attribute:NSLayoutAttributeTrailing
                                      multiplier:1
                                        constant:trailingConstant];
      self.placeholderAnimationConstraintTrailing.priority = UILayoutPriorityDefaultHigh - 1;
    }
    self.placeholderAnimationConstraintTrailing.constant = trailingConstant;

    self.placeholderAnimationConstraints = @[
      self.placeholderAnimationConstraintLeading, self.placeholderAnimationConstraintTop,
      self.placeholderAnimationConstraintTrailing
    ];
    [NSLayoutConstraint activateConstraints:self.placeholderAnimationConstraints];
  } else {
    [NSLayoutConstraint deactivateConstraints:self.placeholderAnimationConstraints];
  }
}

// Sometimes we set up the animation constraints for floating up before we have a width for the text
// field. Since there is math that needs to compensate for the transform in relation to the width,
// we check to see if the constraints still have the correct constants.
- (BOOL)needsUpdatePlaceholderAnimationConstraintsToUp {
  if (![self isPlaceholderUp]) {
    return NO;
  }

  // Remember, the insets are always in LTR. It's automatically flipped when used in RTL.
  // See MDCTextInputController.h.
  UIEdgeInsets insets = self.textInput.textInsets;

  UIOffset offset = [self floatingPlaceholderOffset];

  CGFloat leadingConstant = [self floatingPlaceholderAnimationConstraintLeadingConstant:insets
                                                                                 offset:offset];
  CGFloat trailingConstant = [self floatingPlaceholderAnimationConstraintTrailingConstant:insets
                                                                                   offset:offset];

  return self.placeholderAnimationConstraintLeading.constant != leadingConstant &&
         self.placeholderAnimationConstraintTrailing.constant != trailingConstant;
}

// When placeholder is not up, it just uses the layout code that comes for free from the text field
// itself. That means these constraints need go away. So, we can use the existence of them as a
// way to check if the placeholder is floating up. See isplaceholderUp.
- (void)cleanupPlaceholderAnimationConstraints {
  // We need to clear only deactivated constraints and to prevent the clearing of active
  // constraints.
  if (self.placeholderAnimationConstraintLeading.active &&
      self.placeholderAnimationConstraintTop.active &&
      self.placeholderAnimationConstraintTrailing.active) {
    return;
  }
  self.placeholderAnimationConstraints = nil;
  self.placeholderAnimationConstraintLeading = nil;
  self.placeholderAnimationConstraintTop = nil;
  self.placeholderAnimationConstraintTrailing = nil;
}

// Sometimes the text field is not showing the correct layout for its values (like when it's created
// with .text already entered) so we make sure it's in the right place always.
//
// Note that this calls updateLayout inside it so it is not included in updateLayout.
- (void)forceUpdatePlaceholderY {
  BOOL isDirectionToUp = NO;
  if (self.floatingEnabled) {
    isDirectionToUp = self.textInput.hasTextContent || self.textInput.isEditing;
  }

  [CATransaction begin];
  [CATransaction setDisableActions:YES];
  [self movePlaceholderToUp:isDirectionToUp];
  [self updateLayout];

  [CATransaction commit];

  self.textInput.hidesPlaceholderOnInput = !self.floatingEnabled;
  [self.textInput layoutIfNeeded];
}

// The placeholder has a simple scale transform on it. The default is to reduce the size by 25%.
// Unfortunately, auto layout has no concept of compensating for transforms and it keeps the same
// alignmentRect as if it weren't transformed at all. That gives the impression the placeholder,
// when floating up, is too far to the trailing side. This offset is part of a compensation for
// that. It calculates the amount of space between the alignmentRect's sides and the actual shrunken
// placeholder label.
- (UIOffset)floatingPlaceholderOffset {
  CGFloat vertical = MDCTextInputControllerBaseDefaultPadding;

  // Offsets needed due to transform working on normal (0.5,0.5) anchor point.
  // Why no anchor point of (0,0)? Because autolayout doesn't play well with anchor points.
  vertical -= self.textInput.placeholderLabel.font.lineHeight *
              (1 - (CGFloat)self.floatingPlaceholderScale.floatValue) * (CGFloat)0.5;

  // Remember, the insets are always in LTR. It's automatically flipped when used in RTL.
  // See MDCTextInputController.h.
  UIEdgeInsets insets = self.textInput.textInsets;

  CGFloat placeholderMaxWidth =
      CGRectGetWidth(self.textInput.bounds) / self.floatingPlaceholderScale.floatValue -
      insets.left - insets.right;

  CGFloat placeholderWidth =
      [self.textInput.placeholderLabel systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
          .width;
  if (placeholderWidth > placeholderMaxWidth) {
    placeholderWidth = placeholderMaxWidth;
  }

  CGFloat horizontal =
      placeholderWidth * (1 - (CGFloat)self.floatingPlaceholderScale.floatValue) * (CGFloat)0.5;

  return UIOffsetMake(horizontal, vertical);
}

// Remember, the insets are always in LTR. It's automatically flipped when used in RTL.
// See MDCTextInputController.h.
- (CGFloat)floatingPlaceholderAnimationConstraintLeadingConstant:(UIEdgeInsets)textInsets
                                                          offset:(UIOffset)offset {
  CGFloat constant = textInsets.left - offset.horizontal;
  return constant;
}

// Remember, the insets are always in LTR. It's automatically flipped when used in RTL.
// See MDCTextInputController.h.
- (CGFloat)floatingPlaceholderAnimationConstraintTrailingConstant:(UIEdgeInsets)textInsets
                                                           offset:(UIOffset)offset {
  CGFloat constant = offset.horizontal - textInsets.right;
  return constant;
}

#pragma mark - Trailing Label Customization

- (void)updateTrailingUnderlineLabel {
  if (!self.characterCountMax) {
    self.textInput.trailingUnderlineLabel.text = nil;
  } else {
    self.textInput.trailingUnderlineLabel.text = [self characterCountText];
    UIFont *font = self.trailingUnderlineLabelFont;
    if (self.mdc_adjustsFontForContentSizeCategory) {
      // TODO: (#4331) This needs to be converted to the new text scheme.
      font = [font mdc_fontSizedForMaterialTextStyle:MDCFontTextStyleCaption
                                scaledForDynamicType:_mdc_adjustsFontForContentSizeCategory];
    }
    self.textInput.trailingUnderlineLabel.font = font;
  }

  UIColor *textColor = self.trailingUnderlineLabelTextColor;

  if (self.isDisplayingCharacterCountError || self.isDisplayingErrorText) {
    textColor = self.errorColor;
  }

  switch (self.characterCountViewMode) {
    case UITextFieldViewModeAlways:
      break;
    case UITextFieldViewModeWhileEditing:
      textColor = !self.textInput.isEditing ? [UIColor clearColor] : textColor;
      break;
    case UITextFieldViewModeUnlessEditing:
      textColor = self.textInput.isEditing ? [UIColor clearColor] : textColor;
      break;
    case UITextFieldViewModeNever:
      textColor = [UIColor clearColor];
      break;
  }

  self.textInput.trailingUnderlineLabel.textColor = textColor;
}

- (NSString *)characterCountText {
  // TODO: (larche) Localize
  return [NSString stringWithFormat:@"%lu / %lu", (unsigned long)[self characterCount],
                                    (unsigned long)self.characterCountMax];
}

#pragma mark - Underline Customization

- (void)updateUnderline {
  UIColor *underlineColor;
  CGFloat underlineHeight;

  switch (self.underlineViewMode) {
    case UITextFieldViewModeAlways:
      underlineColor = self.activeColor;
      underlineHeight = self.underlineHeightActive;
      break;
    case UITextFieldViewModeWhileEditing:
      underlineColor = self.textInput.isEditing ? self.activeColor : self.normalColor;
      underlineHeight =
          self.textInput.isEditing ? self.underlineHeightActive : self.underlineHeightNormal;
      break;
    case UITextFieldViewModeUnlessEditing:
      underlineColor = !self.textInput.isEditing ? self.activeColor : self.normalColor;
      underlineHeight =
          !self.textInput.isEditing ? self.underlineHeightActive : self.underlineHeightNormal;
      break;
    case UITextFieldViewModeNever:
    default:
      underlineColor = self.normalColor;
      underlineHeight = self.underlineHeightNormal;
      break;
  }
  self.textInput.underline.color =
      (self.isDisplayingCharacterCountError || self.isDisplayingErrorText) ? self.errorColor
                                                                           : underlineColor;
  self.textInput.underline.lineHeight = underlineHeight;

  self.textInput.underline.disabledColor = self.disabledColor;
}

#pragma mark - Underline Labels Fonts

+ (UIFont *)placeholderFont {
  return [UIFont mdc_standardFontForMaterialTextStyle:MDCFontTextStyleBody1];
  // TODO: (#4331) This needs to be converted to the new text scheme.
}

+ (UIFont *)underlineLabelsFont {
  // TODO: (#4331) This needs to be converted to the new text scheme.
  return [UIFont mdc_standardFontForMaterialTextStyle:MDCFontTextStyleCaption];
}

#pragma mark - Properties Implementation

- (UIColor *)activeColor {
  return _activeColor ? _activeColor : [self class].activeColorDefault;
}

- (void)setActiveColor:(UIColor *)activeColor {
  if (![_activeColor isEqual:activeColor]) {
    _activeColor = activeColor;
    [self updateLayout];
  }
}

+ (UIColor *)activeColorDefault {
  if (!_activeColorDefault) {
    _activeColorDefault = MDCTextInputControllerBaseDefaultActiveColorDefault();
  }
  return _activeColorDefault;
}

+ (void)setActiveColorDefault:(UIColor *)activeColorDefault {
  _activeColorDefault = activeColorDefault ? activeColorDefault
                                           : MDCTextInputControllerBaseDefaultActiveColorDefault();
}

- (UIColor *)borderFillColor {
  if (!_borderFillColor) {
    _borderFillColor = [self class].borderFillColorDefault;
  }
  return _borderFillColor;
}

- (void)setBorderFillColor:(UIColor *)borderFillColor {
  if (_borderFillColor != borderFillColor) {
    _borderFillColor = borderFillColor ? borderFillColor : [self class].borderFillColorDefault;
    [self updateBorder];
  }
}

+ (UIColor *)borderFillColorDefault {
  if (!_borderFillColorDefault) {
    _borderFillColorDefault = [UIColor clearColor];
  }
  return _borderFillColorDefault;
}

+ (void)setBorderFillColorDefault:(UIColor *)borderFillColorDefault {
  _borderFillColorDefault = borderFillColorDefault ? borderFillColorDefault : [UIColor clearColor];
}

- (void)setCharacterCountViewMode:(UITextFieldViewMode)characterCountViewMode {
  if (_characterCountViewMode != characterCountViewMode) {
    _characterCountViewMode = characterCountViewMode;

    [self updateLayout];
  }
}

- (UIColor *)borderStrokeColor {
  return _borderStrokeColor;
}

- (void)setBorderStrokeColor:(UIColor *)borderStrokeColor {
  if (_borderStrokeColor != borderStrokeColor) {
    _borderStrokeColor = borderStrokeColor;
    [self updateBorder];
  }
}

- (UIColor *)disabledColor {
  if (!_disabledColor) {
    _disabledColor = [self class].disabledColorDefault;
  }
  return _disabledColor;
}

- (void)setDisabledColor:(UIColor *)disabledColor {
  if (_disabledColor != disabledColor) {
    _disabledColor = disabledColor ? disabledColor : [self class].disabledColorDefault;
    [self updateLayout];
  }
}

+ (UIColor *)disabledColorDefault {
  if (!_disabledColorDefault) {
    _disabledColorDefault = MDCTextInputControllerBaseDefaultNormalUnderlineColorDefault();
  }
  return _disabledColorDefault;
}

+ (void)setDisabledColorDefault:(UIColor *)disabledColorDefault {
  _disabledColorDefault = disabledColorDefault
                              ? disabledColorDefault
                              : MDCTextInputControllerBaseDefaultNormalUnderlineColorDefault();
}

// This is when the character count text is red because the inputted text has more characters than
// the characterCountMax allows.
- (BOOL)isDisplayingCharacterCountError {
  return self.characterCountMax && [self characterCount] > self.characterCountMax;
}

- (BOOL)isDisplayingErrorText {
  return self.errorText != nil;
}

- (void)setErrorAccessibilityValue:(NSString *)errorAccessibilityValue {
  _errorAccessibilityValue = [errorAccessibilityValue copy];
}

- (void)setHelperAccessibilityLabel:(NSString *)helperAccessibilityLabel {
  _helperAccessibilityLabel = [helperAccessibilityLabel copy];
  if ([self.textInput.leadingUnderlineLabel.text isEqualToString:self.helperText]) {
    self.textInput.leadingUnderlineLabel.accessibilityLabel = _helperAccessibilityLabel;
  }
}

- (UIColor *)errorColor {
  if (!_errorColor) {
    _errorColor = [self class].errorColorDefault;
  }
  return _errorColor;
}

- (void)setErrorColor:(UIColor *)errorColor {
  if (![_errorColor isEqual:errorColor]) {
    _errorColor = errorColor ? errorColor : [self class].errorColorDefault;
    if (self.isDisplayingCharacterCountError || self.isDisplayingErrorText) {
      [self updateLeadingUnderlineLabel];
      [self updatePlaceholder];
      [self updateTrailingUnderlineLabel];
      [self updateUnderline];
    }
  }
}

+ (UIColor *)errorColorDefault {
  if (!_errorColorDefault) {
    _errorColorDefault = MDCTextInputControllerBaseDefaultTextErrorColorDefault();
  }
  return _errorColorDefault;
}

+ (void)setErrorColorDefault:(UIColor *)errorColorDefault {
  _errorColorDefault = errorColorDefault ? errorColorDefault
                                         : MDCTextInputControllerBaseDefaultTextErrorColorDefault();
}

- (void)setErrorText:(NSString *)errorText {
  _errorText = [errorText copy];
}

- (void)setExpandsOnOverflow:(BOOL)expandsOnOverflow {
  if (_expandsOnOverflow != expandsOnOverflow) {
    _expandsOnOverflow = expandsOnOverflow;
    if ([_textInput conformsToProtocol:@protocol(MDCMultilineTextInput)] &&
        [_textInput respondsToSelector:@selector(setExpandsOnOverflow:)]) {
      ((id<MDCMultilineTextInput>)_textInput).expandsOnOverflow = expandsOnOverflow;
    }
  }
}
- (UIColor *)floatingPlaceholderActiveColor {
  return _floatingPlaceholderActiveColor ? _floatingPlaceholderActiveColor
                                         : [self class].floatingPlaceholderActiveColorDefault;
}

- (void)setFloatingPlaceholderActiveColor:(UIColor *)floatingPlaceholderActiveColor {
  if (![_floatingPlaceholderActiveColor isEqual:floatingPlaceholderActiveColor]) {
    _floatingPlaceholderActiveColor = floatingPlaceholderActiveColor;
    [self updatePlaceholder];
  }
}

+ (UIColor *)floatingPlaceholderActiveColorDefault {
  if (!_floatingPlaceholderActiveColorDefault) {
    _floatingPlaceholderActiveColorDefault = [self class].activeColorDefault;
  }
  return _floatingPlaceholderActiveColorDefault;
}

+ (void)setFloatingPlaceholderActiveColorDefault:(UIColor *)floatingPlaceholderActiveColorDefault {
  _floatingPlaceholderActiveColorDefault = floatingPlaceholderActiveColorDefault
                                               ? floatingPlaceholderActiveColorDefault
                                               : [self class].activeColorDefault;
}

- (UIColor *)floatingPlaceholderNormalColor {
  return _floatingPlaceholderNormalColor ? _floatingPlaceholderNormalColor
                                         : [self class].floatingPlaceholderNormalColorDefault;
}

- (void)setFloatingPlaceholderNormalColor:(UIColor *)floatingPlaceholderNormalColor {
  if (![_floatingPlaceholderNormalColor isEqual:floatingPlaceholderNormalColor]) {
    _floatingPlaceholderNormalColor = floatingPlaceholderNormalColor;
    [self updatePlaceholder];
  }
}

+ (UIColor *)floatingPlaceholderNormalColorDefault {
  if (!_floatingPlaceholderNormalColorDefault) {
    _floatingPlaceholderNormalColorDefault = [self class].inlinePlaceholderColorDefault;
  }
  return _floatingPlaceholderNormalColorDefault;
}

+ (void)setFloatingPlaceholderNormalColorDefault:(UIColor *)floatingPlaceholderNormalColorDefault {
  _floatingPlaceholderNormalColorDefault = floatingPlaceholderNormalColorDefault
                                               ? floatingPlaceholderNormalColorDefault
                                               : [self class].inlinePlaceholderColorDefault;
}

- (UIColor *)floatingPlaceholderErrorActiveColor {
  return _floatingPlaceholderErrorActiveColor;
}

- (void)setFloatingPlaceholderErrorActiveColor:(UIColor *)floatingPlaceholderErrorActiveColor {
  if (![_floatingPlaceholderErrorActiveColor isEqual:floatingPlaceholderErrorActiveColor]) {
    _floatingPlaceholderErrorActiveColor = floatingPlaceholderErrorActiveColor;
    [self updatePlaceholder];
  }
}

- (void)setFloatingEnabled:(BOOL)floatingEnabled {
  if (_floatingEnabled != floatingEnabled) {
    _floatingEnabled = floatingEnabled;
    [self forceUpdatePlaceholderY];
  }
}

+ (BOOL)isFloatingEnabledDefault {
  return _floatingEnabledDefault;
}

+ (void)setFloatingEnabledDefault:(BOOL)floatingEnabledDefault {
  _floatingEnabledDefault = floatingEnabledDefault;
}

- (NSNumber *)floatingPlaceholderScale {
  if (_floatingPlaceholderScale == nil) {
    _floatingPlaceholderScale =
        [NSNumber numberWithFloat:(float)[self class].floatingPlaceholderScaleDefault];
  }
  return _floatingPlaceholderScale;
}

- (void)setFloatingPlaceholderScale:(NSNumber *)floatingPlaceholderScale {
  if (![_floatingPlaceholderScale isEqualToNumber:floatingPlaceholderScale]) {
    _floatingPlaceholderScale =
        (floatingPlaceholderScale != nil)
            ? floatingPlaceholderScale
            : [NSNumber numberWithFloat:(float)[self class].floatingPlaceholderScaleDefault];

    [self updatePlaceholder];
    [self.textInput setNeedsUpdateConstraints];
  }
}

+ (CGFloat)floatingPlaceholderScaleDefault {
  return _floatingPlaceholderScaleDefault;
}

+ (void)setFloatingPlaceholderScaleDefault:(CGFloat)floatingPlaceholderScaleDefault {
  _floatingPlaceholderScaleDefault = floatingPlaceholderScaleDefault;
  if (floatingPlaceholderScaleDefault <= 0) {
    _floatingPlaceholderScaleDefault =
        MDCTextInputControllerBaseDefaultFloatingPlaceholderScaleDefault;
  }
}

- (void)setHelperText:(NSString *)helperText {
  if (self.isDisplayingErrorText) {
    self.previousLeadingText = helperText;
  } else {
    if (![self.textInput.leadingUnderlineLabel.text isEqualToString:helperText]) {
      self.textInput.leadingUnderlineLabel.text = helperText;
      [self updateLayout];
    }
  }
}

- (NSString *)helperText {
  if (self.isDisplayingErrorText) {
    return self.previousLeadingText;
  } else {
    return self.textInput.leadingUnderlineLabel.text;
  }
}

- (void)setInlinePlaceholderColor:(UIColor *)inlinePlaceholderColor {
  if (![_inlinePlaceholderColor isEqual:inlinePlaceholderColor]) {
    _inlinePlaceholderColor = inlinePlaceholderColor;
    [self updatePlaceholder];
  }
}

- (UIColor *)inlinePlaceholderColor {
  return _inlinePlaceholderColor ? _inlinePlaceholderColor
                                 : [self class].inlinePlaceholderColorDefault;
}

+ (UIColor *)inlinePlaceholderColorDefault {
  if (!_inlinePlaceholderColorDefault) {
    _inlinePlaceholderColorDefault =
        MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault();
  }
  return _inlinePlaceholderColorDefault;
}

+ (void)setInlinePlaceholderColorDefault:(UIColor *)inlinePlaceholderColorDefault {
  _inlinePlaceholderColorDefault =
      inlinePlaceholderColorDefault
          ? inlinePlaceholderColorDefault
          : MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault();
}

- (UIFont *)inlinePlaceholderFont {
  return _inlinePlaceholderFont ?: [self class].inlinePlaceholderFontDefault;
}

- (void)setInlinePlaceholderFont:(UIFont *)inlinePlaceholderFont {
  if (![_inlinePlaceholderFont isEqual:inlinePlaceholderFont]) {
    _inlinePlaceholderFont = inlinePlaceholderFont;
    [self updateLayout];
  }
}

+ (UIFont *)inlinePlaceholderFontDefault {
  return _inlinePlaceholderFontDefault ?: [[self class] placeholderFont];
}

+ (void)setInlinePlaceholderFontDefault:(UIFont *)inlinePlaceholderFontDefault {
  _inlinePlaceholderFontDefault = inlinePlaceholderFontDefault;
}

- (UIFont *)leadingUnderlineLabelFont {
  return _leadingUnderlineLabelFont ?: [self class].leadingUnderlineLabelFontDefault;
}

- (void)setLeadingUnderlineLabelFont:(UIFont *)leadingUnderlineLabelFont {
  if (![_leadingUnderlineLabelFont isEqual:leadingUnderlineLabelFont]) {
    _leadingUnderlineLabelFont = leadingUnderlineLabelFont;
    [self updateLayout];
  }
}

+ (UIFont *)leadingUnderlineLabelFontDefault {
  return _leadingUnderlineLabelFontDefault ?: [[self class] underlineLabelsFont];
}

+ (void)setLeadingUnderlineLabelFontDefault:(UIFont *)leadingUnderlineLabelFontDefault {
  _leadingUnderlineLabelFontDefault = leadingUnderlineLabelFontDefault;
}

- (UIColor *)leadingUnderlineLabelTextColor {
  return _leadingUnderlineLabelTextColor ? _leadingUnderlineLabelTextColor
                                         : [self class].leadingUnderlineLabelTextColorDefault;
}

- (void)setLeadingUnderlineLabelTextColor:(UIColor *)leadingUnderlineLabelTextColor {
  if (_leadingUnderlineLabelTextColor != leadingUnderlineLabelTextColor) {
    _leadingUnderlineLabelTextColor = leadingUnderlineLabelTextColor
                                          ? leadingUnderlineLabelTextColor
                                          : [self class].leadingUnderlineLabelTextColorDefault;

    [self updateLeadingUnderlineLabel];
  }
}

+ (UIColor *)leadingUnderlineLabelTextColorDefault {
  if (!_leadingUnderlineLabelTextColorDefault) {
    _leadingUnderlineLabelTextColorDefault =
        MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault();
  }
  return _leadingUnderlineLabelTextColorDefault;
}

+ (void)setLeadingUnderlineLabelTextColorDefault:(UIColor *)leadingUnderlineLabelTextColorDefault {
  _leadingUnderlineLabelTextColorDefault =
      leadingUnderlineLabelTextColorDefault
          ? leadingUnderlineLabelTextColorDefault
          : MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault();
}

- (void)setMinimumLines:(NSUInteger)minimumLines {
  if (_minimumLines != minimumLines) {
    _minimumLines = minimumLines;
    if ([_textInput conformsToProtocol:@protocol(MDCMultilineTextInput)] &&
        [_textInput respondsToSelector:@selector(setMinimumLines:)]) {
      ((id<MDCMultilineTextInput>)_textInput).minimumLines = minimumLines;
    }
  }
}

- (UIColor *)normalColor {
  return _normalColor ? _normalColor : [self class].normalColorDefault;
}

- (void)setNormalColor:(UIColor *)normalColor {
  if (![_normalColor isEqual:normalColor]) {
    _normalColor = normalColor;
    [self updateLayout];
  }
}

+ (UIColor *)normalColorDefault {
  if (!_normalColorDefault) {
    _normalColorDefault = MDCTextInputControllerBaseDefaultNormalUnderlineColorDefault();
  }
  return _normalColorDefault;
}

+ (void)setNormalColorDefault:(UIColor *)normalColorDefault {
  _normalColorDefault = normalColorDefault
                            ? normalColorDefault
                            : MDCTextInputControllerBaseDefaultNormalUnderlineColorDefault();
}

- (NSString *)placeholderText {
  return _textInput.placeholder;
}

- (void)setPlaceholderText:(NSString *)placeholderText {
  if ([_textInput.placeholder isEqualToString:placeholderText]) {
    return;
  }
  _textInput.placeholder = [placeholderText copy];
  if (self.isFloatingEnabled && _textInput.hasTextContent) {
    [self updatePlaceholderAnimationConstraints:YES];
  }
}

- (void)setPreviousLeadingText:(NSString *)previousLeadingText {
  _previousLeadingText = [previousLeadingText copy];
}

- (void)setRoundedCorners:(UIRectCorner)roundedCorners {
  if (_roundedCorners != roundedCorners) {
    _roundedCorners = roundedCorners;

    [self updateLayout];
  }
}

+ (UIRectCorner)roundedCornersDefault {
  return _roundedCornersDefault;
}

+ (void)setRoundedCornersDefault:(UIRectCorner)roundedCornersDefault {
  _roundedCornersDefault = roundedCornersDefault;
}

- (void)setTextInput:(UIView<MDCTextInput> *)textInput {
  if (_textInput != textInput) {
    [self unsubscribeFromNotifications];

    _textInput = textInput;
    [self setupInput];
  }
}

- (UIFont *)textInputFont {
  if (_textInputFont) {
    return _textInputFont;
  }
  return [self class].textInputFontDefault ?: self.textInput.font;
}

- (void)setTextInputFont:(UIFont *)textInputFont {
  if (![_textInputFont isEqual:textInputFont]) {
    _textInputFont = textInputFont;
    [self updateLayout];
  }
}

+ (UIFont *)textInputFontDefault {
  return _textInputFontDefault;
}

+ (void)setTextInputFontDefault:(UIFont *)textInputFontDefault {
  _textInputFontDefault = textInputFontDefault;
}

- (UIColor *)textInputClearButtonTintColor {
  if (_textInputClearButtonTintColor) {
    return _textInputClearButtonTintColor;
  }
  return [self class].textInputClearButtonTintColorDefault ?: self.textInput.clearButton.tintColor;
}

- (void)setTextInputClearButtonTintColor:(UIColor *)textInputClearButtonTintColor {
  _textInputClearButtonTintColor = textInputClearButtonTintColor;
  _textInput.clearButton.tintColor = _textInputClearButtonTintColor;
}

+ (UIColor *)textInputClearButtonTintColorDefault {
  return _textInputClearButtonTintColorDefault;
}

+ (void)setTextInputClearButtonTintColorDefault:(UIColor *)textInputClearButtonTintColorDefault {
  _textInputClearButtonTintColorDefault = textInputClearButtonTintColorDefault;
}

- (UIFont *)trailingUnderlineLabelFont {
  return _trailingUnderlineLabelFont ?: [self class].trailingUnderlineLabelFontDefault;
}

- (void)setTrailingUnderlineLabelFont:(UIFont *)trailingUnderlineLabelFont {
  if (![_trailingUnderlineLabelFont isEqual:trailingUnderlineLabelFont]) {
    _trailingUnderlineLabelFont = trailingUnderlineLabelFont;
    [self updateLayout];
  }
}

+ (UIFont *)trailingUnderlineLabelFontDefault {
  return _trailingUnderlineLabelFontDefault ?: [[self class] underlineLabelsFont];
}

+ (void)setTrailingUnderlineLabelFontDefault:(UIFont *)trailingUnderlineLabelFontDefault {
  _trailingUnderlineLabelFontDefault = trailingUnderlineLabelFontDefault;
}

- (UIColor *)trailingUnderlineLabelTextColor {
  return _trailingUnderlineLabelTextColor ? _trailingUnderlineLabelTextColor
                                          : [self class].trailingUnderlineLabelTextColorDefault;
}

- (void)setTrailingUnderlineLabelTextColor:(UIColor *)trailingUnderlineLabelTextColor {
  if (_trailingUnderlineLabelTextColor != trailingUnderlineLabelTextColor) {
    _trailingUnderlineLabelTextColor = trailingUnderlineLabelTextColor
                                           ? trailingUnderlineLabelTextColor
                                           : [self class].trailingUnderlineLabelTextColorDefault;

    [self updateTrailingUnderlineLabel];
  }
}

+ (UIColor *)trailingUnderlineLabelTextColorDefault {
  if (!_trailingUnderlineLabelTextColorDefault) {
    _trailingUnderlineLabelTextColorDefault =
        MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault();
  }
  return _trailingUnderlineLabelTextColorDefault;
}

+ (void)setTrailingUnderlineLabelTextColorDefault:
    (UIColor *)trailingUnderlineLabelTextColorDefault {
  _trailingUnderlineLabelTextColorDefault =
      trailingUnderlineLabelTextColorDefault
          ? trailingUnderlineLabelTextColorDefault
          : MDCTextInputControllerBaseDefaultInlinePlaceholderTextColorDefault();
}

- (void)setUnderlineHeightActive:(CGFloat)underlineHeightActive {
  if (_underlineHeightActive != underlineHeightActive) {
    _underlineHeightActive = underlineHeightActive;
    [self updateLayout];
  }
}

+ (CGFloat)underlineHeightActiveDefault {
  return _underlineHeightActiveDefault;
}

+ (void)setUnderlineHeightActiveDefault:(CGFloat)underlineHeightActiveDefault {
  _underlineHeightActiveDefault = underlineHeightActiveDefault;
}

- (void)setUnderlineHeightNormal:(CGFloat)underlineHeightNormal {
  if (_underlineHeightNormal != underlineHeightNormal) {
    _underlineHeightNormal = underlineHeightNormal;
    [self updateLayout];
  }
}

+ (CGFloat)underlineHeightNormalDefault {
  return _underlineHeightNormalDefault;
}

+ (void)setUnderlineHeightNormalDefault:(CGFloat)underlineHeightNormalDefault {
  _underlineHeightNormalDefault = underlineHeightNormalDefault;
}

- (void)setUnderlineViewMode:(UITextFieldViewMode)underlineViewMode {
  if (_underlineViewMode != underlineViewMode) {
    _underlineViewMode = underlineViewMode;
    [self updateLayout];
  }
}

+ (UITextFieldViewMode)underlineViewModeDefault {
  return _underlineViewModeDefault;
}

+ (void)setUnderlineViewModeDefault:(UITextFieldViewMode)underlineViewModeDefault {
  _underlineViewModeDefault = underlineViewModeDefault;
}

#pragma mark - Layout

- (void)updateLayout {
  if (!_textInput) {
    return;
  }

  [self updateCursor];
  [self updatePlaceholder];
  [self updateLeadingUnderlineLabel];
  [self updateTrailingUnderlineLabel];
  [self updateTextInput];
  [self updateUnderline];
  [self updateBorder];
}

#pragma mark - MDCTextFieldPositioningDelegate

// clang-format off
/**
 textInsets: is the source of truth for vertical layout. It's used to figure out the proper
 height and also where to place the placeholder / text field.

 NOTE: It's applied before the textRect is flipped for RTL. So all calculations are done here à la
 LTR.

 The vertical layout is, at most complex, this form:
 MDCTextInputControllerBaseDefaultPadding                             // Top padding
 rint(self.textInput.placeholderLabel.font.lineHeight * scale)     // Placeholder when up
 MDCTextInputControllerBaseDefaultPadding                             // Padding
 ceil(MAX(self.textInput.font.lineHeight,                          // Text field or placeholder
             self.textInput.placeholderLabel.font.lineHeight))
 MDCTextInputControllerBaseDefaultPadding                             // Padding to underline
 --Underline--                                                        // Underline (height not counted)
 underlineLabelsOffset                                                // Depends on text insets mode
 */
// clang-format on
- (UIEdgeInsets)textInsets:(UIEdgeInsets)defaultInsets
    withSizeThatFitsWidthHint:(CGFloat)widthHint {
  // NOTE: UITextFields have a centerY based layout. And you can change EITHER the height or the Y.
  // Not both. Don't know why. So, we have to leave the text rect as big as the bounds and move it
  // to a Y that works. In other words, no bottom inset will make a difference here for UITextFields
  UIEdgeInsets textInsets = defaultInsets;

  if (self.isFloatingEnabled) {
    textInsets.top = MDCTextInputControllerBaseDefaultPadding +
                     rint(self.textInput.placeholderLabel.font.lineHeight *
                          (CGFloat)self.floatingPlaceholderScale.floatValue) +
                     MDCTextInputControllerBaseDefaultPadding;
  }

  CGFloat scale = UIScreen.mainScreen.scale;
  CGFloat leadingOffset =
      ceil(self.textInput.leadingUnderlineLabel.font.lineHeight * scale) / scale;
  CGFloat calculatedNumberOfLinesForLeadingLabel = [MDCTextInputControllerBase
      calculatedNumberOfLinesForLeadingLabel:self.textInput.leadingUnderlineLabel
                          givenTrailingLabel:self.textInput.trailingUnderlineLabel
                                      insets:defaultInsets
                                   widthHint:widthHint];
  leadingOffset = MAX(leadingOffset, calculatedNumberOfLinesForLeadingLabel * leadingOffset);
  CGFloat trailingOffset =
      ceil(self.textInput.trailingUnderlineLabel.font.lineHeight * scale) / scale;

  // The amount of space underneath the underline is variable. It could just be
  // MDCTextInputControllerBaseDefaultPadding or the biggest estimated underlineLabel height +
  // MDCTextInputControllerBaseDefaultPadding. It's also dependent on the .textInsetsMode.
  CGFloat underlineOffset = 0;
  switch (self.textInput.textInsetsMode) {
    case MDCTextInputTextInsetsModeAlways:
      underlineOffset +=
          MAX(leadingOffset, trailingOffset) + MDCTextInputControllerBaseDefaultPadding;
      break;
    case MDCTextInputTextInsetsModeIfContent: {
      // contentConditionalOffset will have the estimated text height for the largest underline
      // label that also has text.
      CGFloat contentConditionalOffset = 0;
      if (self.textInput.leadingUnderlineLabel.text.length) {
        contentConditionalOffset = leadingOffset;
      }
      if (self.textInput.trailingUnderlineLabel.text.length) {
        contentConditionalOffset = MAX(contentConditionalOffset, trailingOffset);
      }

      if (!MDCCGFloatEqual(contentConditionalOffset, 0)) {
        underlineOffset += contentConditionalOffset + MDCTextInputControllerBaseDefaultPadding;
      }
    } break;
    case MDCTextInputTextInsetsModeNever:
      break;
  }

  // .bottom = underlineOffset + MDCTextInputControllerBaseDefaultPadding
  // Legacy default has an additional padding here but this version does not.
  textInsets.bottom = underlineOffset + MDCTextInputControllerBaseDefaultPadding;
  return textInsets;
}

- (UIEdgeInsets)textInsets:(UIEdgeInsets)defaultInsets {
  return [self textInsets:defaultInsets withSizeThatFitsWidthHint:0];
}

// Part of the counting lines logic was sourced from
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html.
+ (NSUInteger)calculatedNumberOfLinesForLeadingLabel:(UILabel *)label
                                  givenTrailingLabel:(UILabel *)trailingLabel
                                              insets:(UIEdgeInsets)insets
                                           widthHint:(CGFloat)widthHint {
  if (!label.text || label.numberOfLines == 1) {
    return 1;
  }
  if (widthHint <= 0 && CGRectGetWidth(label.bounds) <= 0) {
    return 1;
  }

  CGFloat deductedWidthForLeadingLabel = 0;
  // Take into account the width the trailingLabel takes up when calculating the available width.
  if (trailingLabel && trailingLabel.text.length > 0) {
    deductedWidthForLeadingLabel =
        [trailingLabel.text boundingRectWithSize:trailingLabel.frame.size
                                         options:NSStringDrawingUsesLineFragmentOrigin
                                      attributes:@{NSFontAttributeName : trailingLabel.font}
                                         context:nil]
            .size.width;
  }
  // Also take into account the left and right padding of the label when calculating the available
  // width.
  deductedWidthForLeadingLabel += insets.left + insets.right;
  NSTextStorage *textStorage =
      [[NSTextStorage alloc] initWithAttributedString:label.attributedText];
  NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
  [textStorage addLayoutManager:layoutManager];
  CGFloat labelWidth = CGRectGetWidth(label.bounds);
  // Also take int
  CGFloat calculatedWidth = labelWidth > 0 ? labelWidth : widthHint - deductedWidthForLeadingLabel;
  NSTextContainer *textContainer =
      [[NSTextContainer alloc] initWithSize:CGSizeMake(calculatedWidth, CGFLOAT_MAX)];
  textContainer.maximumNumberOfLines = label.numberOfLines;
  textContainer.lineFragmentPadding = 0;
  textContainer.lineBreakMode = label.lineBreakMode;
  [layoutManager addTextContainer:textContainer];
  NSUInteger numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs];
  NSRange lineRange;
  for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++) {
    (void)[layoutManager lineFragmentRectForGlyphAtIndex:index effectiveRange:&lineRange];
    index = NSMaxRange(lineRange);
  }

  return numberOfLines;
}

- (void)textInputDidLayoutSubviews {
  [self updateBorder];

  if ([self needsUpdatePlaceholderAnimationConstraintsToUp]) {
    [self updatePlaceholderAnimationConstraints:YES];
  }
}

- (void)textInputDidUpdateConstraints {
  if (self.isFloatingEnabled && _textInput.hasTextContent > 0) {
    [self updatePlaceholderAnimationConstraints:YES];
  }
}

#pragma mark - UITextField & UITextView Notification Observation

- (void)textInputDidBeginEditing:(__unused NSNotification *)note {
  [CATransaction begin];
  [CATransaction
      setAnimationDuration:MDCTextInputControllerBaseDefaultFloatingPlaceholderUpAnimationDuration];
  [CATransaction
      setAnimationTimingFunction:[CAMediaTimingFunction
                                     functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

  [self updateLayout];

  if (self.isFloatingEnabled && !self.textInput.hasTextContent) {
    [self movePlaceholderToUp:YES];
  }
  [CATransaction commit];

  if (self.characterCountMax > 0) {
    NSString *announcementString;
    if (!announcementString.length) {
      announcementString = [NSString
          stringWithFormat:@"%lu character limit.", (unsigned long)self.characterCountMax];
    }

    // Simply sending a layout change notification does not seem to
    UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, announcementString);
  }
}

- (void)textInputDidToggleEnabled:(NSNotification *)notification {
  if (notification.object != self.textInput) {
    return;
  }
  [self updateLayout];
}

- (void)textInputDidChange:(NSNotification *)note {
  if ([note.name isEqualToString:MDCTextFieldTextDidSetTextNotification]) {
    [CATransaction begin];
    [CATransaction setAnimationDuration:0];
    [self updateLayout];
    [self forceUpdatePlaceholderY];
    [CATransaction commit];
  } else {
    [self updateLayout];
  }

  // Accessibility
  if (self.textInput.isEditing && self.characterCountMax > 0) {
    NSUInteger charactersForTextInput =
        [self.characterCounter characterCountForTextInput:self.textInput];
    NSString *announcementString;
    if (!announcementString.length) {
      announcementString = [NSString stringWithFormat:@"%lu of %lu characters",
                                                      (unsigned long)charactersForTextInput,
                                                      (unsigned long)self.characterCountMax];
    }

    // Simply sending a layout change notification does not seem to
    UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, announcementString);
  }
}

- (void)textInputDidEndEditing:(__unused NSNotification *)note {
  [CATransaction begin];
  [CATransaction setAnimationDuration:
                     MDCTextInputControllerBaseDefaultFloatingPlaceholderDownAnimationDuration];
  [CATransaction
      setAnimationTimingFunction:[CAMediaTimingFunction
                                     functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

  [self updateLayout];

  if (self.isFloatingEnabled && !self.textInput.hasTextContent) {
    [self movePlaceholderToUp:NO];
  }
  [CATransaction commit];
}

#pragma mark - Public API

- (void)setErrorText:(NSString *)errorText
    errorAccessibilityValue:(NSString *)errorAccessibilityValue {
  // Turn on error:
  //
  // Here the 'magic' logic happens for error text.
  // When the user sets error text, we save the current state of their underline, leading text,
  // trailing text, and placeholder text for both content and color.
  if (errorText && !self.isDisplayingErrorText) {
    // If we are not in error, but will be, we need to save the existing state.
    self.previousLeadingText = self.textInput.leadingUnderlineLabel.text
                                   ? self.textInput.leadingUnderlineLabel.text.copy
                                   : @"";

    self.textInput.leadingUnderlineLabel.text = errorText;

    [self updatePlaceholder];
  }

  // Change error:
  if (errorText && self.isDisplayingErrorText) {
    self.textInput.leadingUnderlineLabel.text = errorText;
  }

  // Turn off error:
  //
  // If error text is unset (nil) we reset to previous values.
  if (!errorText) {
    // If there is a saved state, use it.
    if (self.previousLeadingText) {
      self.textInput.leadingUnderlineLabel.text = self.previousLeadingText;
    }

    // Clear out saved state.
    self.previousLeadingText = nil;
  }

  self.errorText = errorText;
  self.errorAccessibilityValue = errorAccessibilityValue;

  [self updateLayout];

  // Accessibility
  // TODO: (larche) Localize
  if (errorText) {
    NSString *announcementString = errorAccessibilityValue;
    if (!announcementString.length) {
      announcementString =
          errorText.length > 0 ? [NSString stringWithFormat:@"Error: %@", errorText] : @"Error.";
    }
    self.textInput.leadingUnderlineLabel.accessibilityLabel = announcementString;

    dispatch_after(
        dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kDefaultErrorAnnouncementDelay * NSEC_PER_SEC)),
        dispatch_get_main_queue(), ^{
          UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification,
                                          announcementString);
        });
  }
  // Restore the helper text accessibilityLabel.
  else {
    if ([self.textInput.leadingUnderlineLabel.text isEqualToString:self.helperText]) {
      self.textInput.leadingUnderlineLabel.accessibilityLabel = self.helperAccessibilityLabel;
    } else {
      self.textInput.leadingUnderlineLabel.accessibilityLabel = nil;
    }
  }
}

- (void)setHelperText:(NSString *)helperText
    helperAccessibilityLabel:(NSString *)helperAccessibilityLabel {
  self.helperText = helperText;
  self.helperAccessibilityLabel = helperAccessibilityLabel;
}

#pragma mark - Accessibility

- (BOOL)mdc_adjustsFontForContentSizeCategory {
  return _mdc_adjustsFontForContentSizeCategory;
}

- (void)mdc_setAdjustsFontForContentSizeCategory:(BOOL)adjusts {
  _mdc_adjustsFontForContentSizeCategory = adjusts;

  [self updateLayout];

  if (_mdc_adjustsFontForContentSizeCategory) {
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(contentSizeCategoryDidChange:)
                                                 name:UIContentSizeCategoryDidChangeNotification
                                               object:nil];
  } else {
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIContentSizeCategoryDidChangeNotification
                                                  object:nil];
  }
}

- (void)contentSizeCategoryDidChange:(__unused NSNotification *)notification {
  [self updateLayout];
}

@end

#pragma clang diagnostic pop
