// 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 <CoreGraphics/CoreGraphics.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import "MDCAvailability.h"
#import "MDCBottomNavigationBar.h"
#import "UIView+MaterialElevationResponding.h"

#import "private/MDCBottomNavigationBar+Private.h"
#import "private/MDCBottomNavigationItemView.h"
#import "MDCBadgeAppearance.h"
#import "MDCBottomNavigationBarDelegate.h"
#import "MDCBottomNavigationBarItem.h"
#import "MDCBottomNavigationBar+ItemView.h"
#import "MDCPalettes.h"
#import "MDCRippleTouchController.h"
#import "MDCRippleTouchControllerDelegate.h"
#import "MDCRippleView.h"
#import "MDCShadow.h"
#import "MDCShadowsCollection.h"
#import "MDCShadowElevations.h"
#import "MDCShadowLayer.h"
#import "MDCFontTextStyle.h"
#import "UIFont+MaterialTypography.h"
#import "MDCMath.h"

NS_ASSUME_NONNULL_BEGIN

// KVO context
static char *const kKVOContextMDCBottomNavigationBar = "kKVOContextMDCBottomNavigationBar";
static char *const kKVOContextMDCBottomNavigationBarItem = "kKVOContextMDCBottomNavigationBarItem";

static const CGFloat kMinItemWidth = 80;
static const CGFloat kPreferredItemWidth = 120;
static const CGFloat kMaxItemWidth = 350;
// The default amount of internal padding on the leading/trailing edges of each bar item.
static const CGFloat kDefaultItemHorizontalPadding = 0;
static const CGFloat kBarHeightStackedTitle = 56;
static const CGFloat kBarHeightAdjacentTitle = 40;
static const CGFloat kItemsHorizontalMargin = 12;
static const CGFloat kBadgeFontSize = 8;
// Active indicator
static const CGFloat kDefaultActiveIndicatorHeight = 30;
static const CGFloat kDefaultActiveIndicatorWidth = 60;

// Vertical layout
static const CGFloat kDefaultVerticalLayoutWidth = 80;
static const CGFloat kDefaultVerticalPadding = 45;
static const CGFloat kDefaultItemSpacingInVerticalLayoutOniPad = 15;
static const CGFloat kDefaultItemSpacingInVerticalLayout = 8;

@interface MDCBottomNavigationBar () <MDCRippleTouchControllerDelegate>

@property(nonatomic, strong) NSMutableArray<MDCBottomNavigationItemView *> *itemViews;
@property(nonatomic, readonly) UIEdgeInsets mdc_safeAreaInsets;
@property(nonatomic, strong) UIView *barView;
@property(nonatomic, strong) UIVisualEffectView *blurEffectView;
@property(nonatomic, strong) UIStackView *itemsLayoutView;
@property(nonatomic, strong) UILayoutGuide *barItemsLayoutGuide NS_AVAILABLE_IOS(9_0);
@property(nonatomic, strong) NSLayoutConstraint *itemsLayoutViewAlignmentConstraint;
@property(nonatomic, strong) NSLayoutConstraint *itemsLayoutViewHeightConstraint;
@property(nonatomic, strong) NSLayoutConstraint *itemsLayoutViewBottomAnchorConstraint;
@property(nonatomic, strong) NSMutableArray<NSLayoutConstraint *> *itemViewHeightConstraints;
@property(nonatomic, strong) NSMutableArray<NSLayoutConstraint *> *itemViewWidthConstraints;
@property(nonatomic, strong)
    NSMutableArray<NSLayoutConstraint *> *itemsLayoutViewHorizontalConstraints;
@property(nonatomic, strong)
    NSMutableArray<NSLayoutConstraint *> *itemsLayoutViewVerticalConstraints;

#if MDC_AVAILABLE_SDK_IOS(13_0)
/**
 The last large content viewer item displayed by the content viewer while the interaction is
 running. When the interaction ends this property is nil.
 */
@property(nonatomic, nullable) id<UILargeContentViewerItem> lastLargeContentViewerItem
    NS_AVAILABLE_IOS(13_0);
@property(nonatomic, assign) BOOL isLargeContentLongPressInProgress;
#endif  // MDC_AVAILABLE_SDK_IOS(13_0)

@end

@implementation MDCBottomNavigationBar

static BOOL gEnablePerformantShadow = NO;

@synthesize mdc_overrideBaseElevation = _mdc_overrideBaseElevation;
@synthesize mdc_elevationDidChangeBlock = _mdc_elevationDidChangeBlock;
@synthesize shadowsCollection = _shadowsCollection;
@synthesize elevation = _elevation;

- (instancetype)initWithFrame:(CGRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
    self.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth);
    self.isAccessibilityElement = NO;
    [self commonMDCBottomNavigationBarInit];
  }
  return self;
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [super initWithCoder:aDecoder];
  if (self) {
    [self commonMDCBottomNavigationBarInit];
  }
  return self;
}

- (void)commonMDCBottomNavigationBarInit {
  _itemsContentHorizontalMargin = kItemsHorizontalMargin;
  _selectedItemTintColor = UIColor.blackColor;
  _unselectedItemTintColor = UIColor.grayColor;
  _selectedItemTitleColor = _selectedItemTintColor;
  _titleVisibility = MDCBottomNavigationBarTitleVisibilitySelected;
  _alignment = MDCBottomNavigationBarAlignmentJustified;
  _barTintColor = UIColor.whiteColor;
  _truncatesLongTitles = YES;
  _titlesNumberOfLines = 1;
  _mdc_overrideBaseElevation = -1;
  _rippleEnabled = YES;
  _itemsAlignmentInVerticalMode = MDCNavigationBarItemsVerticalAlignmentCenter;
  _itemBadgeAppearance = [[MDCBadgeAppearance alloc] init];
  _itemBadgeAppearance.textColor = UIColor.whiteColor;
  _itemBadgeAppearance.font = [UIFont systemFontOfSize:kBadgeFontSize];
  _itemBadgeAppearance.backgroundColor = MDCPalette.redPalette.tint700;

  _itemsHorizontalPadding = kDefaultItemHorizontalPadding;
  _showsSelectionIndicator = NO;
  _selectionIndicatorColor = [UIColor colorWithRed:195.f / 255.f
                                             green:217.f / 255.f
                                              blue:242.f / 255.f
                                             alpha:1];
  _selectionIndicatorSize = CGSizeMake(kDefaultActiveIndicatorWidth, kDefaultActiveIndicatorHeight);

  // Remove any unarchived subviews and reconfigure the view hierarchy
  if (self.subviews.count) {
    NSArray *subviews = self.subviews;
    for (UIView *view in subviews) {
      [view removeFromSuperview];
    }
  }

  _barView = [[UIView alloc] init];
  _barView.clipsToBounds = YES;
  _barView.backgroundColor = _barTintColor;
  [self addSubview:_barView];

  _itemsLayoutView = [[UIStackView alloc] initWithFrame:CGRectZero];
  _itemsLayoutView.layoutMarginsRelativeArrangement = YES;
  _itemsLayoutView.spacing = kDefaultItemHorizontalPadding;
  _itemsLayoutView.alignment = UIStackViewAlignmentCenter;
  _itemsLayoutView.distribution = UIStackViewDistributionFillEqually;
  _itemsLayoutView.translatesAutoresizingMaskIntoConstraints = NO;
  _itemsLayoutView.clipsToBounds = NO;
  [_barView addSubview:_itemsLayoutView];

  _itemsLayoutView.accessibilityTraits = UIAccessibilityTraitTabBar;
  self.elevation = MDCShadowElevationBottomNavigationBar;
  self.shadowColor = gEnablePerformantShadow ? MDCShadowColor() : UIColor.blackColor;
  _itemViews = [NSMutableArray array];
  _itemViewHeightConstraints = [NSMutableArray array];
  _itemViewWidthConstraints = [NSMutableArray array];
  _itemsLayoutViewHorizontalConstraints = [NSMutableArray array];
  _itemsLayoutViewVerticalConstraints = [NSMutableArray array];
  _itemTitleFont = [UIFont mdc_standardFontForMaterialTextStyle:MDCFontTextStyleCaption];

  // Horizontal layout constraints.
  [_itemsLayoutViewHorizontalConstraints
      addObject:[_itemsLayoutView.leadingAnchor constraintEqualToAnchor:_barView.leadingAnchor]];
  [_itemsLayoutViewHorizontalConstraints
      addObject:[_itemsLayoutView.trailingAnchor constraintEqualToAnchor:_barView.trailingAnchor]];
  [_itemsLayoutViewHorizontalConstraints
      addObject:[_itemsLayoutView.topAnchor constraintEqualToAnchor:_barView.topAnchor]];
  _itemsLayoutViewHeightConstraint =
      [_itemsLayoutView.heightAnchor constraintEqualToConstant:[self calculateBarHeight]];
  [_itemsLayoutViewHorizontalConstraints addObject:_itemsLayoutViewHeightConstraint];

  // Vertical layout constraints.
  [_itemsLayoutViewVerticalConstraints
      addObject:[_itemsLayoutView.widthAnchor
                    constraintEqualToConstant:kDefaultVerticalLayoutWidth]];
  [_itemsLayoutViewVerticalConstraints
      addObject:[_itemsLayoutView.leadingAnchor
                    constraintEqualToAnchor:_barView.safeAreaLayoutGuide.leadingAnchor]];
  _itemsLayoutViewAlignmentConstraint =
      [_itemsLayoutView.centerYAnchor constraintEqualToAnchor:_barView.centerYAnchor];

  // Layout guide to control items stack view's bottom anchor.
  _barItemsLayoutGuide = [[UILayoutGuide alloc] init];
  _barItemsLayoutGuide.identifier = @"MDCBottomNavigationBarItemsLayoutGuide";
  [_itemsLayoutView addLayoutGuide:_barItemsLayoutGuide];
  _itemsLayoutViewBottomAnchorConstraint =
      [_barItemsLayoutGuide.bottomAnchor constraintEqualToAnchor:_itemsLayoutView.bottomAnchor];

  _enableVerticalLayout = NO;
  _displayItemTitlesInVerticalLayout = NO;
  [self loadConstraints];
}

- (CGFloat)barWidthForVerticalLayout {
  return kDefaultVerticalLayoutWidth;
}

- (void)layoutSubviews {
  [super layoutSubviews];

  CGRect standardBounds = CGRectStandardize(self.bounds);
  if (self.blurEffectView) {
    self.blurEffectView.frame = standardBounds;
  }

  self.barView.frame = standardBounds;

  self.layer.shadowColor = self.shadowColor.CGColor;

  for (NSUInteger i = 0; i < self.itemViews.count; i++) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    [self configureTitleStateForItemView:itemView];
  }

  UIUserInterfaceLayoutDirection layoutDirection = self.effectiveUserInterfaceLayoutDirection;
  if (layoutDirection == UIUserInterfaceLayoutDirectionLeftToRight) {
    _itemsLayoutView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
  } else {
    _itemsLayoutView.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
  }

  if (gEnablePerformantShadow) {
    [self updateShadow];
  }
}

- (void)safeAreaInsetsDidChange {
  [super safeAreaInsetsDidChange];
  [self setNeedsLayout];
}

- (NSUInteger)itemCount {
  return self.barItems.count > 0 ? self.barItems.count : self.items.count;
}

- (CGSize)intrinsicContentSize {
  if (self.enableVerticalLayout) {
    return CGSizeMake([self barWidthForVerticalLayout], UIViewNoIntrinsicMetric);
  } else {
    CGFloat height = [self calculateBarHeight];
    CGFloat itemWidth = [self widthForItemsWhenCenteredWithAvailableWidth:CGFLOAT_MAX
                                                                   height:height];

    return CGSizeMake(itemWidth * [self itemCount], height);
  }
}

- (CGFloat)widthForItemsWhenCenteredWithAvailableWidth:(CGFloat)availableWidth
                                                height:(CGFloat)barHeight {
  CGFloat maxItemWidth = kPreferredItemWidth;
  for (UIView *itemView in self.itemViews) {
    maxItemWidth =
        MAX(maxItemWidth, [itemView sizeThatFits:CGSizeMake(availableWidth, barHeight)].width +
                              self.itemsHorizontalPadding * 2);
  }
  maxItemWidth = MIN(kMaxItemWidth, maxItemWidth);
  NSUInteger itemCount = [self itemCount];
  CGFloat totalWidth = maxItemWidth * itemCount;
  if (totalWidth > availableWidth) {
    maxItemWidth = availableWidth / itemCount;
  }
  if (maxItemWidth < kMinItemWidth) {
    maxItemWidth = kMinItemWidth;
  }
  return maxItemWidth;
}

- (NSLayoutYAxisAnchor *)barItemsBottomAnchor {
  return self.barItemsLayoutGuide.bottomAnchor;
}

- (CGSize)sizeThatFits:(CGSize)size {
  CGFloat height;
  CGFloat width = size.width;
  if ([self shouldUseAnchoredLayout]) {
    height = [self calculateBarHeight];
  } else {
    height = self.barHeight;

    if (height <= 0) {
      height = kBarHeightStackedTitle;
      if (self.alignment == MDCBottomNavigationBarAlignmentJustifiedAdjacentTitles &&
          self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular) {
        height = kBarHeightAdjacentTitle;
      }
    }
  }

  if (self.enableVerticalLayout) {
    width = kDefaultVerticalLayoutWidth;
  }

  return CGSizeMake(width, height);
}

+ (Class)layerClass {
  if (gEnablePerformantShadow) {
    return [super layerClass];
  } else {
    return [MDCShadowLayer class];
  }
}

- (void)setElevation:(MDCShadowElevation)elevation {
  if (MDCCGFloatEqual(_elevation, elevation)) {
    return;
  }
  _elevation = elevation;
  if (gEnablePerformantShadow) {
    [self updateShadow];
  } else {
    MDCShadowLayer *shadowLayer = (MDCShadowLayer *)self.layer;
    shadowLayer.elevation = elevation;
  }
  [self mdc_elevationDidChange];
}

- (void)updateShadow {
  MDCShadow *shadow = [self.shadowsCollection shadowForElevation:self.mdc_currentElevation];
  shadow = [[MDCShadowBuilder builderWithColor:self.shadowColor
                                       opacity:shadow.opacity
                                        radius:shadow.radius
                                        offset:shadow.offset
                                        spread:shadow.spread] build];
  MDCConfigureShadowForView(self, shadow);
}

- (void)setShadowColor:(UIColor *)shadowColor {
  UIColor *shadowColorCopy = [shadowColor copy];
  _shadowColor = shadowColorCopy;
  self.layer.shadowColor = shadowColorCopy.CGColor;
}

- (BOOL)isTitleBelowIcon {
  switch (self.alignment) {
    case MDCBottomNavigationBarAlignmentCentered:
    case MDCBottomNavigationBarAlignmentJustified:
      return YES;
      break;
    case MDCBottomNavigationBarAlignmentJustifiedAdjacentTitles:
      return self.traitCollection.horizontalSizeClass != UIUserInterfaceSizeClassRegular;
      break;
  }
}

- (void)setBarHeight:(CGFloat)barHeight {
  _barHeight = barHeight;
  _itemsLayoutViewHeightConstraint.constant = [self calculateBarHeight];
}

- (void)setBarHeightWithoutTitles:(CGFloat)barHeightWithoutTitles {
  _barHeightWithoutTitles = barHeightWithoutTitles;
  _itemsLayoutViewHeightConstraint.constant = [self calculateBarHeight];
}

- (CGFloat)calculateBarHeight {
  if ([self shouldUseAnchoredLayout]) {
    if ([self itemViewsShouldAlwaysHideTitles] ||
        [self barHeightShouldShrinkBasedOnTraitCollection:self.traitCollection]) {
      // Return _barHeightWithoutTitles if it has been set to a positive value.
      // If _barHeightWithoutTitles is 0 (default value) or negative, return _barHeight instead.
      return _barHeightWithoutTitles > 0 ? _barHeightWithoutTitles : _barHeight;
    } else {
      return _barHeight;
    }
  }

  CGFloat height = self.isTitleBelowIcon ? kBarHeightStackedTitle : kBarHeightAdjacentTitle;
  if (self.barHeight > 0) {
    height = self.barHeight;
  }
  return height;
}

- (void)recalculateBarHeightAndUpdateLayout {
  _itemsLayoutViewHeightConstraint.constant = [self calculateBarHeight];
  [self invalidateIntrinsicContentSize];
}

- (void)setEnableVerticalLayout:(BOOL)enableVerticalLayout {
  if (_enableVerticalLayout == enableVerticalLayout) {
    return;
  }
  _enableVerticalLayout = enableVerticalLayout;
  for (MDCBottomNavigationItemView *item in self.itemViews) {
    item.enableVerticalLayout = enableVerticalLayout;
  }
  [self loadConstraints];
  [self invalidateIntrinsicContentSize];
}

- (void)setDisplayItemTitlesInVerticalLayout:(BOOL)displayItemTitlesInVerticalLayout {
  if (_displayItemTitlesInVerticalLayout == displayItemTitlesInVerticalLayout) {
    return;
  }
  _displayItemTitlesInVerticalLayout = displayItemTitlesInVerticalLayout;
  for (MDCBottomNavigationItemView *item in self.itemViews) {
    item.displayTitleInVerticalLayout = _displayItemTitlesInVerticalLayout;
  }
}

- (void)setItemsAlignmentInVerticalMode:
    (MDCNavigationBarItemsVerticalAlignment)itemsAlignmentInVerticalMode {
  _itemsAlignmentInVerticalMode = itemsAlignmentInVerticalMode;
  _itemsLayoutViewAlignmentConstraint.active = NO;
  switch (_itemsAlignmentInVerticalMode) {
    case MDCNavigationBarItemsVerticalAlignmentCenter:
      _itemsLayoutViewAlignmentConstraint =
          [_itemsLayoutView.centerYAnchor constraintEqualToAnchor:_barView.centerYAnchor];
      break;
    case MDCNavigationBarItemsVerticalAlignmentTop:
      _itemsLayoutViewAlignmentConstraint =
          [_itemsLayoutView.topAnchor constraintEqualToAnchor:_barView.topAnchor
                                                     constant:kDefaultVerticalPadding];
      break;
    case MDCNavigationBarItemsVerticalAlignmentBottom:
      _itemsLayoutViewAlignmentConstraint =
          [_itemsLayoutView.bottomAnchor constraintEqualToAnchor:_barView.bottomAnchor
                                                        constant:-kDefaultVerticalPadding];
      break;
  }
  [self loadConstraints];
}

- (void)loadConstraints {
  if (self.enableVerticalLayout) {
    [self activateVerticalLayoutConstraints];
  } else {
    [self activateHorizontalLayoutConstraints];
  }
}
- (void)activateVerticalLayoutConstraints {
  _itemsLayoutViewBottomAnchorConstraint.active = NO;
  [NSLayoutConstraint deactivateConstraints:self.itemsLayoutViewHorizontalConstraints];
  for (NSLayoutConstraint *constraint in self.itemViewHeightConstraints) {
    constraint.constant = kBarHeightStackedTitle;
  }
  _itemsLayoutViewAlignmentConstraint.active = YES;
  self.itemsLayoutView.axis = UILayoutConstraintAxisVertical;

  if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
    self.itemsLayoutView.spacing = kDefaultItemSpacingInVerticalLayoutOniPad;
  } else if (self.displayItemTitlesInVerticalLayout) {
    self.itemsLayoutView.spacing = kDefaultItemSpacingInVerticalLayout;
  }
  [NSLayoutConstraint activateConstraints:self.itemViewWidthConstraints];
  [NSLayoutConstraint activateConstraints:self.itemsLayoutViewVerticalConstraints];
}

- (void)activateHorizontalLayoutConstraints {
  _itemsLayoutViewAlignmentConstraint.active = NO;
  [NSLayoutConstraint deactivateConstraints:self.itemViewWidthConstraints];
  [NSLayoutConstraint deactivateConstraints:self.itemsLayoutViewVerticalConstraints];
  CGFloat barHeight = [self calculateBarHeight];
  _itemsLayoutViewHeightConstraint.constant = barHeight;
  self.itemsLayoutView.axis = UILayoutConstraintAxisHorizontal;
  self.itemsLayoutView.spacing = kDefaultItemHorizontalPadding;
  _itemsLayoutViewBottomAnchorConstraint.active = YES;
  for (NSLayoutConstraint *constraint in self.itemViewHeightConstraints) {
    constraint.constant = barHeight;
  }
  [NSLayoutConstraint activateConstraints:self.itemsLayoutViewHorizontalConstraints];
}

- (void)dealloc {
  [self removeObserversFromTabBarItems];
  [self removeObserversFromBarItems];
}

- (NSArray<NSString *> *)barItemKVOKeyPaths {
  static NSArray<NSString *> *keyPaths;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    keyPaths = @[
      NSStringFromSelector(@selector(item)),
    ];
  });
  return keyPaths;
}

- (NSArray<NSString *> *)kvoKeyPaths {
  static NSArray<NSString *> *keyPaths;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    keyPaths = @[
      NSStringFromSelector(@selector(badgeColor)),
      NSStringFromSelector(@selector(badgeValue)),
      NSStringFromSelector(@selector(title)),
      NSStringFromSelector(@selector(image)),
      NSStringFromSelector(@selector(selectedImage)),
      NSStringFromSelector(@selector(accessibilityValue)),
      NSStringFromSelector(@selector(accessibilityLabel)),
      NSStringFromSelector(@selector(accessibilityHint)),
      NSStringFromSelector(@selector(accessibilityIdentifier)),
      NSStringFromSelector(@selector(isAccessibilityElement)),
      NSStringFromSelector(@selector(titlePositionAdjustment)),
      NSStringFromSelector(@selector(largeContentSizeImage)),
      NSStringFromSelector(@selector(largeContentSizeImageInsets)),
      NSStringFromSelector(@selector(tag)),
    ];
  });
  return keyPaths;
}

- (void)addObserversToTabBarItemsForBarItems {
  NSArray<NSString *> *keyPaths = [self kvoKeyPaths];
  NSArray<NSString *> *barItemKeyPaths = [self barItemKVOKeyPaths];
  for (MDCBottomNavigationBarItem *barItem in self.barItems) {
    for (NSString *keyPath in keyPaths) {
      [barItem.item addObserver:self
                     forKeyPath:keyPath
                        options:NSKeyValueObservingOptionNew
                        context:kKVOContextMDCBottomNavigationBar];
    }
    for (NSString *keyPath in barItemKeyPaths) {
      [barItem addObserver:self
                forKeyPath:keyPath
                   options:NSKeyValueObservingOptionNew
                   context:kKVOContextMDCBottomNavigationBarItem];
    }
  }
}

- (void)removeObserversFromBarItems {
  NSArray<NSString *> *keyPaths = [self kvoKeyPaths];
  NSArray<NSString *> *barItemKeyPaths = [self barItemKVOKeyPaths];
  for (MDCBottomNavigationBarItem *barItem in self.barItems) {
    for (NSString *keyPath in keyPaths) {
      @try {
        [barItem.item removeObserver:self
                          forKeyPath:keyPath
                             context:kKVOContextMDCBottomNavigationBar];
      } @catch (NSException *exception) {
        if (exception) {
          // No need to do anything if there are no observers.
        }
      }
    }
    for (NSString *keyPath in barItemKeyPaths) {
      @try {
        [barItem removeObserver:self
                     forKeyPath:keyPath
                        context:kKVOContextMDCBottomNavigationBarItem];
      } @catch (NSException *exception) {
        if (exception) {
          // No need to do anything if there are no observers.
        }
      }
    }
  }
}

// TODO(b/378528228): Remove this function and associated logic when clients are fully migrated to
// setBarItems.
- (void)addObserversToTabBarItems {
  NSArray<NSString *> *keyPaths = [self kvoKeyPaths];
  for (UITabBarItem *item in self.items) {
    for (NSString *keyPath in keyPaths) {
      [item addObserver:self
             forKeyPath:keyPath
                options:NSKeyValueObservingOptionNew
                context:kKVOContextMDCBottomNavigationBar];
    }
  }
}

// TODO(b/378528228): Remove this function and associated logic when clients are fully migrated to
// setBarItems.
- (void)removeObserversFromTabBarItems {
  NSArray<NSString *> *keyPaths = [self kvoKeyPaths];
  for (UITabBarItem *item in self.items) {
    for (NSString *keyPath in keyPaths) {
      @try {
        [item removeObserver:self forKeyPath:keyPath context:kKVOContextMDCBottomNavigationBar];
      } @catch (NSException *exception) {
        if (exception) {
          // No need to do anything if there are no observers.
        }
      }
    }
  }
}

- (void)observeValueForKeyPath:(nullable NSString *)keyPath
                      ofObject:(nullable id)object
                        change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change
                       context:(nullable void *)context {
  if (context == kKVOContextMDCBottomNavigationBar) {
    if (!object) {
      return;
    }
    NSUInteger itemIndex = [self.items indexOfObject:object];
    // Since the object returned is of type UITabBarItem, we need to create an array from the
    // barItems array and get the index of the UITabBarItem.
    if (self.barItems.count > 0) {
      itemIndex = NSNotFound;
      for (NSUInteger i = 0; i < self.barItems.count; i++) {
        if ([self.barItems[i].item isEqual:object]) {
          itemIndex = i;
          break;
        }
      }
    }

    if (itemIndex == NSNotFound || itemIndex >= _itemViews.count) {
      return;
    }
    id newValue = [object valueForKey:keyPath];
    if (newValue == [NSNull null]) {
      newValue = nil;
    }

    MDCBottomNavigationItemView *itemView = _itemViews[itemIndex];
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(badgeColor))]) {
      itemView.badgeColor = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(accessibilityValue))]) {
      itemView.accessibilityValue = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(badgeValue))]) {
      itemView.badgeText = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(image))]) {
      itemView.image = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(selectedImage))]) {
      itemView.selectedImage = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(title))]) {
      itemView.title = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(accessibilityIdentifier))]) {
      itemView.accessibilityElementIdentifier = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(accessibilityLabel))]) {
      itemView.accessibilityLabel = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(accessibilityHint))]) {
      itemView.accessibilityHint = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(isAccessibilityElement))]) {
      itemView.isAccessibilityElement = [newValue boolValue];
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(titlePositionAdjustment))]) {
      itemView.titlePositionAdjustment = [newValue UIOffsetValue];
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(largeContentSizeImage))]) {
      itemView.largeContentImage = newValue;
    } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tag))]) {
      itemView.tag = [newValue integerValue];
    } else if ([keyPath
                   isEqualToString:NSStringFromSelector(@selector(largeContentSizeImageInsets))]) {
      itemView.largeContentImageInsets = [newValue UIEdgeInsetsValue];
    }
  } else if (context == kKVOContextMDCBottomNavigationBarItem) {
    if (!object) {
      return;
    }
    NSUInteger itemIndex = [self.barItems indexOfObject:object];

    if (itemIndex == NSNotFound || itemIndex >= _itemViews.count) {
      return;
    }
    id newValue = [object valueForKey:keyPath];
    if (newValue == [NSNull null]) {
      newValue = nil;
    }

    if ([keyPath isEqualToString:NSStringFromSelector(@selector(item))]) {
      // Remove all existing item views and repopulate them with the new bar items.
      [self removeItemViews];
      [self updateBarItems];
    }
  } else {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  }
  [self layoutIfNeeded];
}

- (UIEdgeInsets)mdc_safeAreaInsets {
  return self.safeAreaInsets;
}

- (nullable UIView *)viewForItem:(UITabBarItem *)item {
  NSUInteger itemIndex = [_items indexOfObject:item];
  if (itemIndex == NSNotFound) {
    return nil;
  }
  if (itemIndex >= _itemViews.count) {
    NSAssert(NO, @"Item index should not be out of item view bounds");
    return nil;
  }
  return _itemViews[itemIndex];
}

- (nullable UITabBarItem *)tabBarItemForPoint:(CGPoint)point {
  for (NSUInteger i = 0; (i < self.itemViews.count) && (i < [self itemCount]); i++) {
    UIView *itemView = self.itemViews[i];
    BOOL isPointInView = CGRectContainsPoint(itemView.frame, point);
    if (isPointInView) {
      return self.items[i];
    }
  }

  return nil;
}

/** Returns the item view at the given point. Nil if there is no view at the given point. */
- (MDCBottomNavigationItemView *_Nullable)itemViewForPoint:(CGPoint)point {
  for (NSUInteger i = 0; i < self.itemViews.count; i++) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    CGRect rect = [itemView convertRect:itemView.bounds toView:self];
    if (CGRectContainsPoint(rect, point)) {
      return itemView;
    }
  }

  return nil;
}

- (void)traitCollectionDidChange:(nullable UITraitCollection *)previousTraitCollection {
  [super traitCollectionDidChange:previousTraitCollection];

  if (self.traitCollectionDidChangeBlock) {
    self.traitCollectionDidChangeBlock(self, previousTraitCollection);
  }

  if (self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass ||
      self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass) {
    [self recalculateBarHeightAndUpdateLayout];
  }
}

#pragma mark - Touch handlers

- (void)didTouchUpInsidebarItemButton:(UIButton *)button {
  for (NSUInteger i = 0; i < self.barItems.count; i++) {
    MDCBottomNavigationBarItem *barItem = self.barItems[i];
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    if (itemView.button == button) {
      BOOL shouldSelect = YES;
      if ([self.delegate respondsToSelector:@selector(bottomNavigationBar:shouldSelectItem:)]) {
        shouldSelect = [self.delegate bottomNavigationBar:self shouldSelectItem:barItem.item];
      }
      if (shouldSelect) {
        [self setSelectedBarItem:barItem animated:YES];
        if ([self.delegate respondsToSelector:@selector(bottomNavigationBar:didSelectItem:)]) {
          [self.delegate bottomNavigationBar:self didSelectItem:barItem.item];
        }
      }
    }
  }
}

// TODO(b/378528228): Remove this function and associated logic when clients are fully migrated to
// setBarItems.
- (void)didTouchUpInsideButton:(UIButton *)button {
  for (NSUInteger i = 0; i < self.items.count; i++) {
    UITabBarItem *item = self.items[i];
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    if (itemView.button == button) {
      BOOL shouldSelect = YES;
      if ([self.delegate respondsToSelector:@selector(bottomNavigationBar:shouldSelectItem:)]) {
        shouldSelect = [self.delegate bottomNavigationBar:self shouldSelectItem:item];
      }
      if (shouldSelect) {
        [self setSelectedItem:item animated:YES];
        if ([self.delegate respondsToSelector:@selector(bottomNavigationBar:didSelectItem:)]) {
          [self.delegate bottomNavigationBar:self didSelectItem:item];
        }
      }
    }
  }
}

#pragma mark - Setters

- (void)setBarItems:(NSArray<MDCBottomNavigationBarItem *> *)barItems {
  if ([_barItems isEqual:barItems] || _barItems == barItems) {
    return;
  }
  // If clients report conflicting gesture recognizers please see proposed solution in the
  // internal document: go/mdc-ios-bottomnavigation-largecontentvieweritem
  [self addInteraction:[[UILargeContentViewerInteraction alloc] initWithDelegate:self]];

  [self removeItemViews];
  _barItems = [barItems copy];
  [self updateBarItems];
}

- (void)removeItemViews {
  // Remove existing item views from the bottom navigation so it can be repopulated with new items.
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    [itemView removeFromSuperview];
  }
  if (self.itemViews.count > 0) {
    [self.itemViews removeAllObjects];
    [self.itemViewHeightConstraints removeAllObjects];
    [self.itemViewWidthConstraints removeAllObjects];
    [self removeObserversFromBarItems];
  }
}

- (void)updateBarItems {
  CGFloat barHeight = [self calculateBarHeight];

  for (NSUInteger i = 0; i < self.barItems.count; i++) {
    MDCBottomNavigationItemView *itemView =
        [[MDCBottomNavigationItemView alloc] initWithFrame:CGRectZero];

    itemView.rippleTouchController.delegate = self;
    itemView.selected = NO;
    itemView.displayTitleInVerticalLayout = self.displayItemTitlesInVerticalLayout;
    itemView.enableVerticalLayout = self.enableVerticalLayout;

    itemView.selectionIndicatorColor = self.selectionIndicatorColor;
    itemView.selectionIndicatorSize = self.selectionIndicatorSize;
    [self configureTitleStateForItemView:itemView];

    // If a given badge appearance has a `nil` for its textColor and font, then the values from the
    // itemBadgeAppearance are used.
    if (!self.barItems[i].badgeAppearance.textColor) {
      self.barItems[i].badgeAppearance.textColor = _itemBadgeAppearance.textColor;
    }
    if (!self.barItems[i].badgeAppearance.font) {
      self.barItems[i].badgeAppearance.font = _itemBadgeAppearance.font;
    }

    [self configureItemView:itemView
                   withItem:self.barItems[i].item
                 appearance:self.barItems[i].badgeAppearance];

    [itemView.button addTarget:self
                        action:@selector(didTouchUpInsidebarItemButton:)
              forControlEvents:UIControlEventTouchUpInside];

    [self.itemViews addObject:itemView];
    [self.itemsLayoutView addArrangedSubview:itemView];
    itemView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *itemViewHeightConstraint =
        [itemView.heightAnchor constraintEqualToConstant:barHeight];
    // This priority is set to low to avoid conflict of constraints due to the itemView's height
    // being the same as the bar.
    itemViewHeightConstraint.priority = UILayoutPriorityDefaultLow;
    [self.itemViewHeightConstraints addObject:itemViewHeightConstraint];
    NSLayoutConstraint *itemViewWidthConstraint =
        [itemView.widthAnchor constraintEqualToConstant:kDefaultVerticalLayoutWidth];
    // This priority is set to low to avoid conflict of constraints due to the itemView's width
    // being the same as the bar.
    itemViewWidthConstraint.priority = UILayoutPriorityDefaultLow;
    [self.itemViewWidthConstraints addObject:itemViewWidthConstraint];
  }

  self.selectedBarItem = nil;
  [NSLayoutConstraint activateConstraints:self.itemViewHeightConstraints];
  [self loadConstraints];
  [self addObserversToTabBarItemsForBarItems];
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

- (void)setSelectedBarItem:(nullable MDCBottomNavigationBarItem *)selectedBarItem {
  [self setSelectedBarItem:selectedBarItem animated:NO];
}

- (void)setSelectedBarItem:(nullable MDCBottomNavigationBarItem *)selectedBarItem
                  animated:(BOOL)animated {
  if (_selectedBarItem == selectedBarItem) {
    return;
  }
  _selectedBarItem = selectedBarItem;
  for (NSUInteger i = 0; i < self.barItems.count; i++) {
    MDCBottomNavigationBarItem *barItem = self.barItems[i];
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    if (selectedBarItem == barItem) {
      [itemView setSelected:YES animated:animated];
    } else {
      [itemView setSelected:NO animated:animated];
    }
  }
}

// TODO(b/378528228): Remove this function and associated logic when clients are fully migrated to
// setBarItems.
- (void)setItems:(NSArray<UITabBarItem *> *)items {
  if ([_items isEqual:items] || _items == items || _barItems.count > 0) {
    return;
  }
  // If clients report conflicting gesture recognizers please see proposed solution in the
  // internal document: go/mdc-ios-bottomnavigation-largecontentvieweritem
  [self addInteraction:[[UILargeContentViewerInteraction alloc] initWithDelegate:self]];

  // Remove existing item views from the bottom navigation so it can be repopulated with new items.
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    [itemView removeFromSuperview];
  }
  [self.itemViews removeAllObjects];
  [self.itemViewHeightConstraints removeAllObjects];
  [self.itemViewWidthConstraints removeAllObjects];
  [self removeObserversFromTabBarItems];
  _items = [items copy];

  CGFloat barHeight = [self calculateBarHeight];

  for (NSUInteger i = 0; i < items.count; i++) {
    MDCBottomNavigationItemView *itemView =
        [[MDCBottomNavigationItemView alloc] initWithFrame:CGRectZero];
    itemView.rippleTouchController.delegate = self;
    itemView.selected = NO;
    itemView.displayTitleInVerticalLayout = self.displayItemTitlesInVerticalLayout;
    itemView.enableVerticalLayout = self.enableVerticalLayout;

    [self configureTitleStateForItemView:itemView];
    [self configureItemView:itemView withItem:items[i] appearance:self.itemBadgeAppearance];

    [itemView.button addTarget:self
                        action:@selector(didTouchUpInsideButton:)
              forControlEvents:UIControlEventTouchUpInside];

    [self.itemViews addObject:itemView];
    [self.itemsLayoutView addArrangedSubview:itemView];
    itemView.translatesAutoresizingMaskIntoConstraints = NO;
    NSLayoutConstraint *itemViewHeightConstraint =
        [itemView.heightAnchor constraintEqualToConstant:barHeight];
    // This priority is set to low to avoid conflict of constraints due to the itemView's height
    // being the same as the bar.
    itemViewHeightConstraint.priority = UILayoutPriorityDefaultLow;
    [self.itemViewHeightConstraints addObject:itemViewHeightConstraint];
    NSLayoutConstraint *itemViewWidthConstraint =
        [itemView.widthAnchor constraintEqualToConstant:kDefaultVerticalLayoutWidth];
    // This priority is set to low to avoid conflict of constraints due to the itemView's width
    // being the same as the bar.
    itemViewWidthConstraint.priority = UILayoutPriorityDefaultLow;
    [self.itemViewWidthConstraints addObject:itemViewWidthConstraint];
  }

  self.selectedItem = nil;
  [NSLayoutConstraint activateConstraints:self.itemViewHeightConstraints];
  [self loadConstraints];
  [self addObserversToTabBarItems];
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

// TODO(b/378528228): Remove this function and associated logic when clients are fully migrated to
// setBarItems.
- (void)setSelectedItem:(nullable UITabBarItem *)selectedItem {
  [self setSelectedItem:selectedItem animated:NO];
}

// TODO(b/378528228): Remove this function and associated logic when clients are fully migrated to
// setBarItems.
- (void)setSelectedItem:(UITabBarItem *)selectedItem animated:(BOOL)animated {
  if (_selectedItem == selectedItem) {
    return;
  }
  _selectedItem = selectedItem;
  for (NSUInteger i = 0; i < self.items.count; i++) {
    UITabBarItem *item = self.items[i];
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    if (selectedItem == item) {
      [itemView setSelected:YES animated:animated];
    } else {
      [itemView setSelected:NO animated:animated];
    }
  }
}

- (void)setItemsContentVerticalMargin:(CGFloat)itemsContentsVerticalMargin {
  if (MDCCGFloatEqual(_itemsContentVerticalMargin, itemsContentsVerticalMargin)) {
    return;
  }
  _itemsContentVerticalMargin = itemsContentsVerticalMargin;
  for (NSUInteger i = 0; i < [self itemCount]; i++) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    itemView.contentVerticalMargin = itemsContentsVerticalMargin;
  }
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

- (void)setItemsContentHorizontalMargin:(CGFloat)itemsContentHorizontalMargin {
  if (MDCCGFloatEqual(_itemsContentHorizontalMargin, itemsContentHorizontalMargin)) {
    return;
  }
  _itemsContentHorizontalMargin = itemsContentHorizontalMargin;
  for (NSUInteger i = 0; i < [self itemCount]; i++) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    itemView.contentHorizontalMargin = itemsContentHorizontalMargin;
  }
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

- (void)setItemsHorizontalPadding:(CGFloat)itemsHorizontalPadding {
  if (MDCCGFloatEqual(_itemsHorizontalPadding, itemsHorizontalPadding)) {
    return;
  }
  _itemsHorizontalPadding = itemsHorizontalPadding;
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

- (void)setTruncatesLongTitles:(BOOL)truncatesLongTitles {
  _truncatesLongTitles = truncatesLongTitles;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.truncatesTitle = truncatesLongTitles;
    [itemView setNeedsLayout];
  }
  [self setNeedsLayout];
}

- (void)setSelectedItemTintColor:(UIColor *)selectedItemTintColor {
  _selectedItemTintColor = selectedItemTintColor;
  _selectedItemTitleColor = selectedItemTintColor;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.selectedItemTintColor = selectedItemTintColor;
  }
}

- (void)setUnselectedItemTintColor:(UIColor *)unselectedItemTintColor {
  _unselectedItemTintColor = unselectedItemTintColor;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.unselectedItemTintColor = unselectedItemTintColor;
  }
}

- (void)setSelectedItemTitleColor:(UIColor *)selectedItemTitleColor {
  _selectedItemTitleColor = selectedItemTitleColor;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.selectedItemTitleColor = selectedItemTitleColor;
  }
}

- (void)setTitleVisibility:(MDCBottomNavigationBarTitleVisibility)titleVisibility {
  _titleVisibility = titleVisibility;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.titleVisibility = titleVisibility;
  }
}

- (void)setItemTitleFont:(UIFont *)itemTitleFont {
  _itemTitleFont = itemTitleFont;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.itemTitleFont = itemTitleFont;
  }
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

- (void)setTitlesNumberOfLines:(NSInteger)titlesNumberOfLines {
  _titlesNumberOfLines = titlesNumberOfLines;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.titleNumberOfLines = titlesNumberOfLines;
  }
  [self invalidateIntrinsicContentSize];
  [self setNeedsLayout];
}

- (void)setBarTintColor:(nullable UIColor *)barTintColor {
  _barTintColor = barTintColor;
  self.barView.backgroundColor = barTintColor;
}

- (void)setBackgroundColor:(nullable UIColor *)backgroundColor {
  self.barView.backgroundColor = backgroundColor;
}

- (nullable UIColor *)backgroundColor {
  return self.barView.backgroundColor;
}

- (void)setBackgroundBlurEffectStyle:(UIBlurEffectStyle)backgroundBlurEffectStyle {
  if (_backgroundBlurEffectStyle == backgroundBlurEffectStyle) {
    return;
  }
  _backgroundBlurEffectStyle = backgroundBlurEffectStyle;
  if (self.blurEffectView) {
    self.blurEffectView.effect = [UIBlurEffect effectWithStyle:_backgroundBlurEffectStyle];
  }
}

- (void)setBackgroundBlurEnabled:(BOOL)backgroundBlurEnabled {
  if (_backgroundBlurEnabled == backgroundBlurEnabled) {
    return;
  }
  _backgroundBlurEnabled = backgroundBlurEnabled;

  if (_backgroundBlurEnabled & !self.blurEffectView) {
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:_backgroundBlurEffectStyle];
    self.blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
    self.blurEffectView.hidden = !_backgroundBlurEnabled;
    self.blurEffectView.autoresizingMask =
        (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    [self insertSubview:self.blurEffectView atIndex:0];  // Needs to always be at the bottom
    self.blurEffectView.frame = CGRectStandardize(self.bounds);
  } else if (self.blurEffectView) {
    self.blurEffectView.hidden = !_backgroundBlurEnabled;
  }
}

- (void)setAlignment:(MDCBottomNavigationBarAlignment)alignment {
  if (_alignment == alignment) {
    return;
  }
  _alignment = alignment;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    [self configureTitleStateForItemView:itemView];
  }
  [self recalculateBarHeightAndUpdateLayout];
}

- (void)setShowsSelectionIndicator:(BOOL)showsSelectionIndicator {
  if (showsSelectionIndicator == _showsSelectionIndicator) {
    return;
  }
  _showsSelectionIndicator = showsSelectionIndicator;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.showsSelectionIndicator = _showsSelectionIndicator;
  }
}

- (void)setSelectionIndicatorColor:(UIColor *)selectionIndicatorColor {
  _selectionIndicatorColor = selectionIndicatorColor;

  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.selectionIndicatorColor = _selectionIndicatorColor;
  }
}

- (void)setSelectionIndicatorSize:(CGSize)selectionIndicatorSize {
  _selectionIndicatorSize = selectionIndicatorSize;

  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.selectionIndicatorSize = _selectionIndicatorSize;
  }
}

#pragma mark - MDCRippleTouchControllerDelegate methods

- (BOOL)rippleTouchController:(MDCRippleTouchController *)rippleTouchController
    shouldProcessRippleTouchesAtTouchLocation:(CGPoint)location {
  return self.rippleEnabled;
}

#pragma mark - MDCElevation

- (CGFloat)mdc_currentElevation {
  return self.elevation;
}

- (MDCShadowsCollection *)shadowsCollection {
  if (!_shadowsCollection) {
    _shadowsCollection = MDCShadowsCollectionDefault();
  }
  return _shadowsCollection;
}

- (void)setShadowsCollection:(nullable MDCShadowsCollection *)shadowsCollection {
  _shadowsCollection = shadowsCollection;

  [self updateShadow];
}

- (void)cancelRippleInItemView:(MDCBottomNavigationItemView *)itemView animated:(BOOL)animated {
  if (self.isRippleEnabled) {
    if (animated) {
      [itemView.rippleTouchController.rippleView beginRippleTouchUpAnimated:YES completion:nil];
    } else {
      [itemView.rippleTouchController.rippleView cancelAllRipplesAnimated:NO completion:nil];
    }
  }
}

- (void)beginRippleInItemView:(MDCBottomNavigationItemView *)itemView animated:(BOOL)animated {
  if (self.isRippleEnabled) {
    [itemView.rippleTouchController.rippleView beginRippleTouchDownAtPoint:itemView.center
                                                                  animated:animated
                                                                completion:nil];
  }
}

#pragma mark - UILargeContentViewerInteractionDelegate

#if MDC_AVAILABLE_SDK_IOS(13_0)
- (nullable id<UILargeContentViewerItem>)largeContentViewerInteraction:
                                             (UILargeContentViewerInteraction *)interaction
                                                           itemAtPoint:(CGPoint)point
    NS_AVAILABLE_IOS(13_0) {
  MDCBottomNavigationItemView *lastItemView =
      (MDCBottomNavigationItemView *)self.lastLargeContentViewerItem;

  if (!CGRectContainsPoint(self.itemsLayoutView.frame, point)) {
    // The touch has wandered outside of the view. Clear the ripple and do not display the
    // content viewer.
    if (lastItemView) {
      [self cancelRippleInItemView:lastItemView animated:NO];
    }
    self.lastLargeContentViewerItem = nil;
    return nil;
  }

  MDCBottomNavigationItemView *itemView = [self itemViewForPoint:point];
  if (!itemView) {
    // The touch is still within the navigation bar. Return the last seen item view.
    return self.lastLargeContentViewerItem;
  }

  if (lastItemView != itemView) {
    if (lastItemView) {
      [self cancelRippleInItemView:lastItemView animated:NO];
    }
    // Only start ripple if it's not the first touch down of the long press
    if (self.isLargeContentLongPressInProgress) {
      [self beginRippleInItemView:itemView animated:NO];
    }
    self.lastLargeContentViewerItem = itemView;
  }
  self.isLargeContentLongPressInProgress = YES;
  return itemView;
}

- (void)largeContentViewerInteraction:(UILargeContentViewerInteraction *)interaction
                         didEndOnItem:(nullable id<UILargeContentViewerItem>)item
                              atPoint:(CGPoint)point NS_AVAILABLE_IOS(13_0) {
  if (self.lastLargeContentViewerItem) {
    MDCBottomNavigationItemView *lastItemView =
        (MDCBottomNavigationItemView *)self.lastLargeContentViewerItem;
    [self cancelRippleInItemView:lastItemView animated:YES];
    [self didTouchUpInsideButton:lastItemView.button];
  }

  self.lastLargeContentViewerItem = nil;
  self.isLargeContentLongPressInProgress = NO;
}
#endif  // MDC_AVAILABLE_SDK_IOS(13_0)

#ifdef __IPHONE_13_4
#pragma mark - UIPointerInteractionDelegate

- (nullable UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction
                                 styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)) {
  MDCBottomNavigationItemView *bottomNavigationView = interaction.view;
  if (![bottomNavigationView isKindOfClass:[MDCBottomNavigationItemView class]]) {
    return nil;
  }
  UITargetedPreview *targetedPreview = [[UITargetedPreview alloc] initWithView:interaction.view];
  UIPointerEffect *highlightEffect = [UIPointerHighlightEffect effectWithPreview:targetedPreview];
  CGRect hoverRect =
      [bottomNavigationView convertRect:[bottomNavigationView pointerEffectHighlightRect]
                                 toView:self.itemsLayoutView];
  UIPointerShape *shape = [UIPointerShape shapeWithRoundedRect:hoverRect];
  return [UIPointerStyle styleWithEffect:highlightEffect shape:shape];
}
#endif

#pragma mark - Performant Shadow Toggle

+ (void)setEnablePerformantShadow:(BOOL)enable {
  gEnablePerformantShadow = enable;
}

+ (BOOL)enablePerformantShadow {
  return gEnablePerformantShadow;
}

#pragma mark - Configuring the ripple appearance

- (void)setRippleColor:(nullable UIColor *)rippleColor {
  _rippleColor = rippleColor;

  for (NSUInteger i = 0; i < [self itemCount]; ++i) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    itemView.rippleColor = _rippleColor;
  }
}

#pragma mark - Configuring the visual appearance for all badges

- (void)setItemBadgeAppearance:(MDCBadgeAppearance *)itemBadgeAppearance {
  _itemBadgeAppearance = [itemBadgeAppearance copy];

  // Setting default values if `nil` is received for the appearance properties.
  // The default value for the textColor is `white` and the default value for the font is
  // `systemFontOfSize:8`.
  if (!_itemBadgeAppearance.textColor) {
    _itemBadgeAppearance.textColor = [UIColor whiteColor];
  }
  if (!_itemBadgeAppearance.font) {
    _itemBadgeAppearance.font = [UIFont systemFontOfSize:kBadgeFontSize];
  }

  for (NSUInteger i = 0; i < [self itemCount]; ++i) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    if (self.barItems.count > 0 && self.barItems[i].badgeAppearance != nil) {
      itemView.badgeAppearance = self.barItems[i].badgeAppearance;
    } else {
      itemView.badgeAppearance = _itemBadgeAppearance;
    }
  }
}

- (void)setItemBadgeHorizontalOffset:(CGFloat)itemBadgeHorizontalOffset {
  _itemBadgeHorizontalOffset = itemBadgeHorizontalOffset;
  for (NSUInteger i = 0; i < [self itemCount]; ++i) {
    MDCBottomNavigationItemView *itemView = self.itemViews[i];
    itemView.badgeHorizontalOffset = itemBadgeHorizontalOffset;
  }
}

// TODO(b/244765238): Remove branching layout logic after GM3 migrations
// Assume that setting itemBadgeHorizontalOffset to any value other than its default (0) should
// activate the new anchored/GM3 layout, and assume that anyone applying GM3 branding for Bottom
// Navigation will use a non-zero offset.
- (BOOL)shouldUseAnchoredLayout {
  return _itemBadgeHorizontalOffset != 0;
}

- (BOOL)itemViewsShouldAlwaysHideTitles {
  return _titleVisibility == MDCBottomNavigationBarTitleVisibilityNever;
}

- (BOOL)barHeightShouldShrinkBasedOnTraitCollection:(UITraitCollection *)traitCollection {
  return traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact ||
         [self itemViewsShouldAlwaysHideTitles];
}

- (void)configureTitleStateForItemView:(MDCBottomNavigationItemView *)itemView {
  if ([self shouldUseAnchoredLayout]) {
    itemView.titleBelowIcon = ![self itemViewsShouldAlwaysHideTitles];
  } else {
    itemView.titleBelowIcon = self.isTitleBelowIcon;
  }
}

- (void)setEnableSquareImages:(BOOL)enableSquareImages {
  _enableSquareImages = enableSquareImages;
  for (MDCBottomNavigationItemView *itemView in self.itemViews) {
    itemView.enableSquareImages = enableSquareImages;
  }
}

@end

NS_ASSUME_NONNULL_END
