// Copyright 2016-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 "MDCFloatingButton.h"

#import "private/MDCFloatingButtonModeAnimator.h"
#import "private/MDCFloatingButtonModeAnimatorDelegate.h"
#import "MDCButton.h"
#import "MaterialShadowElevations.h"

#import <MDFInternationalization/MDFInternationalization.h>

static const CGFloat MDCFloatingButtonDefaultDimension = 56;
static const CGFloat MDCFloatingButtonMiniDimension = 40;
static const CGFloat MDCFloatingButtonDefaultImageTitleSpace = 8;
static const UIEdgeInsets internalLayoutInsets = (UIEdgeInsets){0, 16, 0, 24};

@interface MDCFloatingButton () <MDCFloatingButtonModeAnimatorDelegate>

@property(nonatomic, readonly)
    NSMutableDictionary<NSNumber *, NSMutableDictionary<NSNumber *, NSValue *> *>
        *shapeToModeToMinimumSize;

@property(nonatomic, readonly)
    NSMutableDictionary<NSNumber *, NSMutableDictionary<NSNumber *, NSValue *> *>
        *shapeToModeToMaximumSize;

@property(nonatomic, readonly)
    NSMutableDictionary<NSNumber *, NSMutableDictionary<NSNumber *, NSValue *> *>
        *shapeToModeToContentEdgeInsets;

@property(nonatomic, readonly)
    NSMutableDictionary<NSNumber *, NSMutableDictionary<NSNumber *, NSValue *> *>
        *shapeToModeToHitAreaInsets;

@property(nonatomic, readonly)
    NSMutableDictionary<NSNumber *, NSMutableDictionary<NSNumber *, NSNumber *> *>
        *shapeToModeToCenterVisibleArea;

@end

@implementation MDCFloatingButton {
  MDCFloatingButtonShape _shape;

  MDCFloatingButtonModeAnimator *_modeAnimator;
  // Allows us to perform masking effects during mode animations.
  UIView *_titleLabelContainerView;
}

+ (void)initialize {
  [[MDCFloatingButton appearance] setElevation:MDCShadowElevationFABResting
                                      forState:UIControlStateNormal];
  [[MDCFloatingButton appearance] setElevation:MDCShadowElevationFABPressed
                                      forState:UIControlStateHighlighted];
}

+ (CGFloat)defaultDimension {
  return MDCFloatingButtonDefaultDimension;
}

+ (CGFloat)miniDimension {
  return MDCFloatingButtonMiniDimension;
}

+ (instancetype)floatingButtonWithShape:(MDCFloatingButtonShape)shape {
  return [[[self class] alloc] initWithFrame:CGRectZero shape:shape];
}

- (instancetype)init {
  return [self initWithFrame:CGRectZero shape:MDCFloatingButtonShapeDefault];
}

- (instancetype)initWithFrame:(CGRect)frame {
  return [self initWithFrame:frame shape:MDCFloatingButtonShapeDefault];
}

- (instancetype)initWithFrame:(CGRect)frame shape:(MDCFloatingButtonShape)shape {
  self = [super initWithFrame:frame];
  if (self) {
    _shape = shape;
    [self commonMDCFloatingButtonInit];
    // The superclass sets contentEdgeInsets from defaultContentEdgeInsets before the _shape is set.
    // Set contentEdgeInsets again to ensure the defaults are for the correct shape.
    [self updateShapeAndAllowResize:NO];
  }
  return self;
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
// https://stackoverflow.com/questions/24458608/convenience-initializer-missing-a-self-call-to-another-initializer
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [super initWithCoder:aDecoder];
#pragma clang diagnostic pop
  if (self) {
    // Required to migrate any previously-archived FloatingButtons from .largeIcon shape value
    if (@(_shape).integerValue >= 2) {
      _shape = MDCFloatingButtonShapeDefault;
    }
    // Shape must be set first before the common initialization
    [self commonMDCFloatingButtonInit];

    [self updateShapeAndAllowResize:NO];
  }
  return self;
}

- (void)commonMDCFloatingButtonInit {
  _imageTitleSpace = MDCFloatingButtonDefaultImageTitleSpace;

  // Create a container view for titleLabel and add the titelLabel to it. This will enable us to
  // mask the titleLabel mode animations if desired, while acting effectively as a pass-through for
  // the superview layout logic.
  _titleLabelContainerView = [[UIView alloc] initWithFrame:self.bounds];
  _titleLabelContainerView.autoresizingMask =
      UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  [self insertSubview:_titleLabelContainerView belowSubview:self.titleLabel];
  _titleLabelContainerView.userInteractionEnabled = NO;
  [_titleLabelContainerView addSubview:self.titleLabel];

  const CGSize miniNormalSize =
      CGSizeMake(MDCFloatingButtonMiniDimension, MDCFloatingButtonMiniDimension);
  const CGSize defaultNormalSize =
      CGSizeMake(MDCFloatingButtonDefaultDimension, MDCFloatingButtonDefaultDimension);
  const CGSize defaultExpandedMinimumSize = CGSizeMake(0, 48);
  const CGSize defaultExpandedMaximumSize = CGSizeMake(328, 0);

  // Minimum size values for different shape + mode combinations
  NSMutableDictionary *miniShapeMinimumSizeDictionary =
      [@{@(MDCFloatingButtonModeNormal) : [NSValue valueWithCGSize:miniNormalSize]} mutableCopy];
  NSMutableDictionary *defaultShapeMinimumSizeDictionary = [@{
    @(MDCFloatingButtonModeNormal) : [NSValue valueWithCGSize:defaultNormalSize],
    @(MDCFloatingButtonModeExpanded) : [NSValue valueWithCGSize:defaultExpandedMinimumSize],
  } mutableCopy];
  _shapeToModeToMinimumSize = [@{
    @(MDCFloatingButtonShapeMini) : miniShapeMinimumSizeDictionary,
    @(MDCFloatingButtonShapeDefault) : defaultShapeMinimumSizeDictionary,
  } mutableCopy];

  // Maximum size values for different shape + mode combinations
  NSMutableDictionary *miniShapeMaximumSizeDictionary =
      [@{@(MDCFloatingButtonModeNormal) : [NSValue valueWithCGSize:miniNormalSize]} mutableCopy];
  NSMutableDictionary *defaultShapeMaximumSizeDictionary = [@{
    @(MDCFloatingButtonModeNormal) : [NSValue valueWithCGSize:defaultNormalSize],
    @(MDCFloatingButtonModeExpanded) : [NSValue valueWithCGSize:defaultExpandedMaximumSize],
  } mutableCopy];
  _shapeToModeToMaximumSize = [@{
    @(MDCFloatingButtonShapeMini) : miniShapeMaximumSizeDictionary,
    @(MDCFloatingButtonShapeDefault) : defaultShapeMaximumSizeDictionary,
  } mutableCopy];

  // Content edge insets values for different shape + mode combinations
  // .mini shape, .normal mode
  const UIEdgeInsets miniNormalContentInsets = UIEdgeInsetsMake(8, 8, 8, 8);
  NSMutableDictionary *miniShapeContentEdgeInsetsDictionary =
      [@{@(MDCFloatingButtonModeNormal) : [NSValue valueWithUIEdgeInsets:miniNormalContentInsets]}
          mutableCopy];
  _shapeToModeToContentEdgeInsets =
      [@{@(MDCFloatingButtonShapeMini) : miniShapeContentEdgeInsetsDictionary} mutableCopy];

  // Hit area insets values for different shape + mode combinations
  // .mini shape, .normal mode
  const UIEdgeInsets miniNormalHitAreaInset = UIEdgeInsetsMake(-4, -4, -4, -4);
  NSMutableDictionary *miniShapeHitAreaInsetsDictionary = [@{
    @(MDCFloatingButtonModeNormal) : [NSValue valueWithUIEdgeInsets:miniNormalHitAreaInset],
  } mutableCopy];
  _shapeToModeToHitAreaInsets = [@{
    @(MDCFloatingButtonShapeMini) : miniShapeHitAreaInsetsDictionary,
  } mutableCopy];

  _shapeToModeToCenterVisibleArea = [[NSMutableDictionary alloc] init];
}

#pragma mark - UIView

- (CGSize)sizeThatFits:(__unused CGSize)size {
  return [self intrinsicContentSize];
}

- (CGSize)intrinsicContentSizeForModeNormal {
  switch (_shape) {
    case MDCFloatingButtonShapeDefault:
      return CGSizeMake(MDCFloatingButtonDefaultDimension, MDCFloatingButtonDefaultDimension);
    case MDCFloatingButtonShapeMini:
      return CGSizeMake(MDCFloatingButtonMiniDimension, MDCFloatingButtonMiniDimension);
  }
}

- (CGSize)intrinsicContentSizeForModeExpanded {
  const CGSize intrinsicTitleSize =
      [self.titleLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
  const CGSize intrinsicImageSize =
      [self.imageView sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
  CGFloat intrinsicWidth = intrinsicTitleSize.width + intrinsicImageSize.width +
                           self.imageTitleSpace + internalLayoutInsets.left +
                           internalLayoutInsets.right + self.contentEdgeInsets.left +
                           self.contentEdgeInsets.right;
  CGFloat intrinsicHeight = MAX(intrinsicTitleSize.height, intrinsicImageSize.height) +
                            self.contentEdgeInsets.top + self.contentEdgeInsets.bottom +
                            internalLayoutInsets.top + internalLayoutInsets.bottom;
  return CGSizeMake(intrinsicWidth, intrinsicHeight);
}

- (CGSize)intrinsicContentSize {
  CGSize contentSize = CGSizeZero;
  if (self.mode == MDCFloatingButtonModeNormal) {
    contentSize = [self intrinsicContentSizeForModeNormal];
  } else if (self.mode == MDCFloatingButtonModeExpanded) {
    contentSize = [self intrinsicContentSizeForModeExpanded];
  }

  if (self.minimumSize.height > 0) {
    contentSize.height = MAX(self.minimumSize.height, contentSize.height);
  }
  if (self.maximumSize.height > 0) {
    contentSize.height = MIN(self.maximumSize.height, contentSize.height);
  }
  if (self.minimumSize.width > 0) {
    contentSize.width = MAX(self.minimumSize.width, contentSize.width);
  }
  if (self.maximumSize.width > 0) {
    contentSize.width = MIN(self.maximumSize.width, contentSize.width);
  }

  return contentSize;
}

/*
 Performs custom layout when the FAB is in .expanded mode. Specifically, the layout algorithm is
 as follows:

 1. Inset the bounds by the value of `contentEdgeInsets` and use this as the layout bounds.
 2. Determine the intrinsic sizes of the imageView and titleLabel.
 3. Compute the space remaining for the titleLabel after accounting for the imageView and built-in
    alignment guidelines (internalLayoutInsets).
 4. Position the imageView along the leading (or trailing) edge of the button, inset by
    internalLayoutInsets.left (flipped for RTL).
 5. Position the titleLabel along the leading edge of its available space.
 6. Apply the imageEdgeInsets and titleEdgeInsets to their respective views.
 */
- (void)layoutSubviews {
  // We have to set cornerRadius before laying out subviews so that the boundingPath is correct.
  CGRect visibleBounds = UIEdgeInsetsInsetRect(self.bounds, self.visibleAreaInsets);
  self.layer.cornerRadius = CGRectGetHeight(visibleBounds) / 2;
  [super layoutSubviews];

  if (self.mode == MDCFloatingButtonModeNormal) {
    return;
  }

  // Position the imageView and titleView
  //
  // +------------------------------------+
  // |    |  |  |  CEI TOP            |   |
  // |CEI +--+  |+-----+              |CEI|
  // | LT ||SP||Title|              |RGT|
  // |    +--+  |+-----+              |   |
  // |    |  |  |  CEI BOT            |   |
  // +------------------------------------+
  //
  // (A) The same spacing on either side of the label.
  // (SP) The spacing between the image and title
  // (CEI) Content Edge Insets
  //
  // The diagram above assumes an LTR user interface orientation
  // and a .leadingIcon imageLocation for this button.

  const CGRect insetBounds = [self insetBoundsForBounds:self.bounds];

  const CGFloat imageViewWidth = CGRectGetWidth(self.imageView.bounds);
  const CGFloat boundsCenterY = CGRectGetMidY(insetBounds);
  CGFloat titleWidthAvailable = CGRectGetWidth(insetBounds);
  titleWidthAvailable -= imageViewWidth;
  titleWidthAvailable -= self.imageTitleSpace;

  const CGFloat availableHeight = CGRectGetHeight(insetBounds);
  CGSize titleIntrinsicSize =
      [self.titleLabel sizeThatFits:CGSizeMake(titleWidthAvailable, availableHeight)];

  const CGSize titleSize = CGSizeMake(MAX(0, MIN(titleIntrinsicSize.width, titleWidthAvailable)),
                                      MAX(0, MIN(titleIntrinsicSize.height, availableHeight)));

  CGPoint titleCenter;
  CGPoint imageCenter;
  BOOL isLTR =
      self.effectiveUserInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionLeftToRight;
  BOOL isLeadingIcon = self.imageLocation == MDCFloatingButtonImageLocationLeading;

  // If we are LTR with a leading image, the image goes on the left.
  // If we are RTL with a trailing image, the image goes on the left.
  if ((isLTR && isLeadingIcon) || (!isLTR && !isLeadingIcon)) {
    const CGFloat imageCenterX = CGRectGetMinX(insetBounds) + (imageViewWidth / 2);
    const CGFloat titleCenterX =
        CGRectGetMaxX(insetBounds) - titleWidthAvailable + (titleSize.width / 2);
    titleCenter = CGPointMake(titleCenterX, boundsCenterY);
    imageCenter = CGPointMake(imageCenterX, boundsCenterY);
  }
  // If we are LTR with a trailing image, the image goes on the right.
  // If we are RTL with a leading image, the image goes on the right.
  else {
    const CGFloat imageCenterX = CGRectGetMaxX(insetBounds) - (imageViewWidth / 2);
    const CGFloat titleCenterX =
        CGRectGetMinX(insetBounds) + titleWidthAvailable - (titleSize.width / 2);
    imageCenter = CGPointMake(imageCenterX, boundsCenterY);
    titleCenter = CGPointMake(titleCenterX, boundsCenterY);
  }

  self.imageView.center = imageCenter;
  self.imageView.frame = UIEdgeInsetsInsetRect(self.imageView.frame, self.imageEdgeInsets);
  self.titleLabel.center = titleCenter;
  CGRect newBounds = CGRectStandardize(self.titleLabel.bounds);
  self.titleLabel.bounds = (CGRect){newBounds.origin, titleSize};
  self.titleLabel.frame = UIEdgeInsetsInsetRect(self.titleLabel.frame, self.titleEdgeInsets);
}

- (CGRect)insetBoundsForBounds:(CGRect)bounds {
  BOOL isLeadingIcon = self.imageLocation == MDCFloatingButtonImageLocationLeading;
  UIEdgeInsets adjustedLayoutInsets =
      (isLeadingIcon ? internalLayoutInsets : MDFInsetsFlippedHorizontally(internalLayoutInsets));
  return UIEdgeInsetsInsetRect(UIEdgeInsetsInsetRect(bounds, adjustedLayoutInsets),
                               self.contentEdgeInsets);
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  // Explicitly disable hit testing in VoiceOver mode when not the actively focused element to avoid
  // intercepting touch events that should go to elements beneath the button. See b/303378197 for
  // more.
  if (UIAccessibilityIsVoiceOverRunning() && !self.accessibilityElementIsFocused) {
    return nil;
  }
  return [super hitTest:point withEvent:event];
}

#pragma mark - Mode animator

- (MDCFloatingButtonModeAnimator *)modeAnimator {
  if (!_modeAnimator) {
    _modeAnimator =
        [[MDCFloatingButtonModeAnimator alloc] initWithTitleLabel:self.titleLabel
                                          titleLabelContainerView:_titleLabelContainerView];
    _modeAnimator.delegate = self;
  }
  return _modeAnimator;
}

#pragma mark MDCFloatingButtonModeAnimatorDelegate

- (void)floatingButtonModeAnimatorCommitLayoutChanges:(MDCFloatingButtonModeAnimator *)modeAnimator
                                                 mode:(MDCFloatingButtonMode)mode {
  [self sizeToFit];
}

#pragma mark - Property Setters/Getters

- (void)setShape:(MDCFloatingButtonShape)shape {
  if (_shape == shape) {
    return;
  }
  _shape = shape;
  [self updateShapeAndAllowResize:YES];
}

- (void)setMode:(MDCFloatingButtonMode)mode {
  [self setMode:mode animated:NO animateAlongside:nil completion:nil];
}

- (void)setMode:(MDCFloatingButtonMode)mode animated:(BOOL)animated {
  [self setMode:mode animated:animated animateAlongside:nil completion:nil];
}

- (void)setMode:(MDCFloatingButtonMode)mode
            animated:(BOOL)animated
    animateAlongside:(void (^)(void))animateAlongside
          completion:(void (^)(BOOL finished))completion {
  if (_mode == mode) {
    if (animateAlongside) {
      animateAlongside();
    }
    if (completion) {
      completion(YES);
    }
    return;
  }
  _mode = mode;

  [self updateShapeAndAllowResize:YES];

  [[self modeAnimator] modeDidChange:mode
                            animated:animated
                    animateAlongside:animateAlongside
                          completion:completion];
}

- (void)setMinimumSize:(CGSize)size
              forShape:(MDCFloatingButtonShape)shape
                inMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToMinimumSize = self.shapeToModeToMinimumSize[@(shape)];
  if (!modeToMinimumSize) {
    modeToMinimumSize = [@{} mutableCopy];
    self.shapeToModeToMinimumSize[@(shape)] = modeToMinimumSize;
  }
  modeToMinimumSize[@(mode)] = [NSValue valueWithCGSize:size];
  if (shape == _shape && mode == self.mode) {
    [self updateShapeAndAllowResize:YES];
  }
}

- (CGSize)minimumSizeForMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToMinimumSize = self.shapeToModeToMinimumSize[@(_shape)];
  if (!modeToMinimumSize) {
    return CGSizeZero;
  }

  NSValue *sizeValue = modeToMinimumSize[@(mode)];
  if (sizeValue) {
    return [sizeValue CGSizeValue];
  } else {
    return CGSizeZero;
  }
}

- (BOOL)updateMinimumSize {
  CGSize newSize = [self minimumSizeForMode:self.mode];
  if (CGSizeEqualToSize(newSize, self.minimumSize)) {
    return NO;
  }
  super.minimumSize = newSize;
  return YES;
}

- (void)setMaximumSize:(CGSize)size
              forShape:(MDCFloatingButtonShape)shape
                inMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToMaximumSize = self.shapeToModeToMaximumSize[@(shape)];
  if (!modeToMaximumSize) {
    modeToMaximumSize = [@{} mutableCopy];
    self.shapeToModeToMaximumSize[@(shape)] = modeToMaximumSize;
  }
  modeToMaximumSize[@(mode)] = [NSValue valueWithCGSize:size];
  if (shape == _shape && mode == self.mode) {
    [self updateShapeAndAllowResize:YES];
  }
}

- (CGSize)maximumSizeForMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToMaximumSize = self.shapeToModeToMaximumSize[@(_shape)];
  if (!modeToMaximumSize) {
    return CGSizeZero;
  }

  NSValue *sizeValue = modeToMaximumSize[@(mode)];
  if (sizeValue) {
    return [sizeValue CGSizeValue];
  } else {
    return CGSizeZero;
  }
}

- (BOOL)updateMaximumSize {
  CGSize newSize = [self maximumSizeForMode:self.mode];
  if (CGSizeEqualToSize(newSize, self.maximumSize)) {
    return NO;
  }
  super.maximumSize = newSize;
  return YES;
}

- (void)setContentEdgeInsets:(UIEdgeInsets)contentEdgeInsets
                    forShape:(MDCFloatingButtonShape)shape
                      inMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToContentEdgeInsets = self.shapeToModeToContentEdgeInsets[@(shape)];
  if (!modeToContentEdgeInsets) {
    modeToContentEdgeInsets = [@{} mutableCopy];
    self.shapeToModeToContentEdgeInsets[@(shape)] = modeToContentEdgeInsets;
  }
  modeToContentEdgeInsets[@(mode)] = [NSValue valueWithUIEdgeInsets:contentEdgeInsets];
  if (shape == _shape && mode == self.mode) {
    [self updateShapeAndAllowResize:YES];
  }
}

- (UIEdgeInsets)contentEdgeInsetsForMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToContentEdgeInsets = self.shapeToModeToContentEdgeInsets[@(_shape)];
  if (!modeToContentEdgeInsets) {
    return UIEdgeInsetsZero;
  }

  NSValue *insetsValue = modeToContentEdgeInsets[@(mode)];
  if (insetsValue) {
    return [insetsValue UIEdgeInsetsValue];
  } else {
    return UIEdgeInsetsZero;
  }
}

- (void)updateContentEdgeInsets {
  super.contentEdgeInsets = [self contentEdgeInsetsForMode:self.mode];
}

- (void)setHitAreaInsets:(UIEdgeInsets)insets
                forShape:(MDCFloatingButtonShape)shape
                  inMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToHitAreaInsets = self.shapeToModeToHitAreaInsets[@(shape)];
  if (!modeToHitAreaInsets) {
    modeToHitAreaInsets = [@{} mutableCopy];
    self.shapeToModeToHitAreaInsets[@(shape)] = modeToHitAreaInsets;
  }
  modeToHitAreaInsets[@(mode)] = [NSValue valueWithUIEdgeInsets:insets];
  if (shape == _shape && mode == self.mode) {
    [self updateShapeAndAllowResize:NO];
  }
}

- (UIEdgeInsets)hitAreaInsetsForMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToHitAreaInsets = self.shapeToModeToHitAreaInsets[@(_shape)];
  if (!modeToHitAreaInsets) {
    return UIEdgeInsetsZero;
  }

  NSValue *insetsValue = modeToHitAreaInsets[@(mode)];
  if (insetsValue) {
    return [insetsValue UIEdgeInsetsValue];
  } else {
    return UIEdgeInsetsZero;
  }
}

- (void)updateHitAreaInsets {
  super.hitAreaInsets = [self hitAreaInsetsForMode:self.mode];
}

- (void)setCenterVisibleArea:(BOOL)centerVisibleArea
                    forShape:(MDCFloatingButtonShape)shape
                      inMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToCenterVisibleArea = self.shapeToModeToCenterVisibleArea[@(shape)];
  if (!modeToCenterVisibleArea) {
    modeToCenterVisibleArea = [@{} mutableCopy];
    self.shapeToModeToCenterVisibleArea[@(shape)] = modeToCenterVisibleArea;
  }
  modeToCenterVisibleArea[@(mode)] = @(centerVisibleArea);
  if (shape == _shape && mode == self.mode) {
    [self updateShapeAndAllowResize:NO];
  }
}

- (BOOL)centerVisibleAreaForMode:(MDCFloatingButtonMode)mode {
  NSMutableDictionary *modeToCenterVisibleArea = self.shapeToModeToCenterVisibleArea[@(_shape)];
  if (!modeToCenterVisibleArea) {
    return NO;
  }

  return [modeToCenterVisibleArea[@(mode)] boolValue];
}

- (void)updateCenterVisibleArea {
  super.centerVisibleArea = [self centerVisibleAreaForMode:self.mode];
}

- (void)updateShapeAndAllowResize:(BOOL)allowsResize {
  BOOL minimumSizeChanged = [self updateMinimumSize];
  BOOL maximumSizeChanged = [self updateMaximumSize];
  [self updateContentEdgeInsets];
  [self updateHitAreaInsets];
  [self updateCenterVisibleArea];

  if (allowsResize && (minimumSizeChanged || maximumSizeChanged)) {
    [self invalidateIntrinsicContentSize];
    [self setNeedsLayout];
  }
}

@end
